Implementation of OMA LWM2M Engine / IPSO Objects

This commit is contained in:
Niclas Finne 2015-12-01 04:14:46 +01:00
parent 35fb0614de
commit 3dd11603a7
33 changed files with 5304 additions and 0 deletions

View file

@ -0,0 +1,3 @@
ipso-objects_src = ipso-temperature.c ipso-button.c ipso-leds-control.c \
ipso-light-control.c ipso-objects.c
CFLAGS += -DWITH_IPSO=1

View file

@ -0,0 +1,163 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO button as a digital input
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "contiki.h"
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "er-coap-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#if PLATFORM_HAS_BUTTON
#include "dev/button-sensor.h"
PROCESS(ipso_button_process, "ipso-button");
#endif /* PLATFORM_HAS_BUTTON */
static int input_state = 0;
static int polarity = 0;
static int32_t counter = 0;
static int32_t edge_selection = 3;
static int32_t debounce_time = 10;
/*---------------------------------------------------------------------------*/
static int
read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
int value;
if(polarity == 0) {
value = input_state ? 1 : 0;
} else {
value = input_state ? 0 : 1;
}
PRINTF("Read button state (polarity=%d, state=%d): %d\n",
polarity, input_state, value);
return ctx->writer->write_boolean(ctx, outbuf, outsize, value);
}
/*---------------------------------------------------------------------------*/
static int
reset_counter(lwm2m_context_t *ctx, const uint8_t *arg, size_t len,
uint8_t *outbuf, size_t outlen)
{
counter = 0;
return 0;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(button_resources,
LWM2M_RESOURCE_CALLBACK(5500, { read_state, NULL, NULL }),
LWM2M_RESOURCE_INTEGER_VAR(5501, &counter),
LWM2M_RESOURCE_BOOLEAN_VAR(5502, &polarity),
LWM2M_RESOURCE_INTEGER_VAR(5503, &debounce_time),
LWM2M_RESOURCE_INTEGER_VAR(5504, &edge_selection),
LWM2M_RESOURCE_CALLBACK(5505, { NULL, NULL, reset_counter }),
LWM2M_RESOURCE_STRING(5751, "Button")
);
LWM2M_INSTANCES(button_instances,
LWM2M_INSTANCE(0, button_resources));
LWM2M_OBJECT(button, 3200, button_instances);
/*---------------------------------------------------------------------------*/
void
ipso_button_init(void)
{
/* register this device and its handlers - the handlers automatically
sends in the object to handle */
lwm2m_engine_register_object(&button);
#if PLATFORM_HAS_BUTTON
process_start(&ipso_button_process, NULL);
#endif /* PLATFORM_HAS_BUTTON */
}
/*---------------------------------------------------------------------------*/
#if PLATFORM_HAS_BUTTON
PROCESS_THREAD(ipso_button_process, ev, data)
{
static struct etimer timer;
int32_t time;
PROCESS_BEGIN();
SENSORS_ACTIVATE(button_sensor);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == sensors_event && data == &button_sensor) {
if(!input_state) {
input_state = 1;
counter++;
if((edge_selection & 2) != 0) {
lwm2m_object_notify_observers(&button, "/0/5500");
}
lwm2m_object_notify_observers(&button, "/0/5501");
time = (debounce_time * CLOCK_SECOND / 1000);
if(time < 1) {
time = 1;
}
etimer_set(&timer, (clock_time_t)time);
}
} else if(ev == PROCESS_EVENT_TIMER && data == &timer) {
if(!input_state) {
/* Button is not in pressed state */
} else if(button_sensor.value(0) != 0) {
/* Button is still pressed */
etimer_reset(&timer);
} else {
input_state = 0;
if((edge_selection & 1) != 0) {
lwm2m_object_notify_observers(&button, "/0/5500");
}
}
}
}
PROCESS_END();
}
#endif /* PLATFORM_HAS_BUTTON */
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Light Control for LEDs
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "er-coap-engine.h"
#include "dev/leds.h"
#include <stdint.h>
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#if LEDS_ALL > 3
#define LEDS_CONTROL_NUMBER 3
#elif LEDS_ALL > 1
#define LEDS_CONTROL_NUMBER 2
#else
#define LEDS_CONTROL_NUMBER 1
#endif
struct led_state {
unsigned long last_on_time;
uint32_t total_on_time;
uint8_t is_on;
};
static struct led_state states[LEDS_CONTROL_NUMBER];
static lwm2m_instance_t leds_control_instances[LEDS_CONTROL_NUMBER];
/*---------------------------------------------------------------------------*/
static int
read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
return ctx->writer->write_boolean(ctx, outbuf, outsize,
states[idx].is_on ? 1 : 0);
}
/*---------------------------------------------------------------------------*/
static int
write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int value;
size_t len;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
len = ctx->reader->read_boolean(ctx, inbuf, insize, &value);
if(len > 0) {
if(value) {
if(!states[idx].is_on) {
states[idx].is_on = 1;
states[idx].last_on_time = clock_seconds();
#if PLATFORM_HAS_LEDS
leds_on(1 << idx);
#endif /* PLATFORM_HAS_LEDS */
}
} else if(states[idx].is_on) {
states[idx].total_on_time += clock_seconds() - states[idx].last_on_time;
states[idx].is_on = 0;
#if PLATFORM_HAS_LEDS
leds_off(1 << idx);
#endif /* PLATFORM_HAS_LEDS */
}
} else {
PRINTF("IPSO leds control - ignored illegal write to on/off\n");
}
return len;
}
/*---------------------------------------------------------------------------*/
static int
read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
unsigned long now;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
if(states[idx].is_on) {
/* Update the on time */
now = clock_seconds();
states[idx].total_on_time += now - states[idx].last_on_time;
states[idx].last_on_time = now;
}
return ctx->writer->write_int(ctx, outbuf, outsize,
(int32_t)states[idx].total_on_time);
}
/*---------------------------------------------------------------------------*/
static int
write_on_time(lwm2m_context_t *ctx,
const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int32_t value;
size_t len;
uint8_t idx = ctx->object_instance_index;
if(idx >= LEDS_CONTROL_NUMBER) {
return 0;
}
len = ctx->reader->read_int(ctx, inbuf, insize, &value);
if(len > 0 && value == 0) {
PRINTF("IPSO leds control - reset On Time\n");
states[idx].total_on_time = 0;
if(states[idx].is_on) {
states[idx].last_on_time = clock_seconds();
}
} else {
PRINTF("IPSO leds control - ignored illegal write to On Time\n");
}
return len;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(leds_control_resources,
LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }),
LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL })
);
LWM2M_OBJECT(leds_control, 3311, leds_control_instances);
/*---------------------------------------------------------------------------*/
void
ipso_leds_control_init(void)
{
lwm2m_instance_t template = LWM2M_INSTANCE(0, leds_control_resources);
int i;
/* Initialize the instances */
for(i = 0; i < LEDS_CONTROL_NUMBER; i++) {
leds_control_instances[i] = template;
leds_control_instances[i].id = i;
}
/* register this device and its handlers - the handlers automatically
sends in the object to handle */
lwm2m_engine_register_object(&leds_control);
PRINTF("IPSO leds control initialized with %u instances\n",
LEDS_CONTROL_NUMBER);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Light Control
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "ipso-objects.h"
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#ifdef IPSO_LIGHT_CONTROL
extern const struct ipso_objects_actuator IPSO_LIGHT_CONTROL;
#endif /* IPSO_LIGHT_CONTROL */
/*---------------------------------------------------------------------------*/
static unsigned long last_on_time;
static uint32_t total_on_time;
static int dim_level = 0;
static uint8_t is_on = 0;
/*---------------------------------------------------------------------------*/
static int
read_state(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
return ctx->writer->write_boolean(ctx, outbuf, outsize, is_on ? 1 : 0);
}
/*---------------------------------------------------------------------------*/
static int
write_state(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int value;
size_t len;
len = ctx->reader->read_boolean(ctx, inbuf, insize, &value);
if(len > 0) {
if(value) {
if(!is_on) {
is_on = 1;
last_on_time = clock_seconds();
}
} else {
if(is_on) {
total_on_time += clock_seconds() - last_on_time;
is_on = 0;
}
}
#ifdef IPSO_LIGHT_CONTROL
if(IPSO_LIGHT_CONTROL.set_on) {
IPSO_LIGHT_CONTROL.set_on(value);
} else if(IPSO_LIGHT_CONTROL.set_dim_level) {
dim_level = value ? 100 : 0;
IPSO_LIGHT_CONTROL.set_dim_level(dim_level);
}
#endif /* IPSO_LIGHT_CONTROL */
}
return len;
}
/*---------------------------------------------------------------------------*/
static int
read_dim(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
return ctx->writer->write_int(ctx, outbuf, outsize, dim_level);
}
/*---------------------------------------------------------------------------*/
static int
write_dim(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int32_t value;
size_t len;
len = ctx->reader->read_int(ctx, inbuf, insize, &value);
if(len > 0) {
if(value < 0) {
value = 0;
} else if(value > 100) {
value = 100;
}
dim_level = value;
if(value > 0) {
if(!is_on) {
is_on = 1;
last_on_time = clock_seconds();
}
} else {
if(is_on) {
total_on_time += clock_seconds() - last_on_time;
is_on = 0;
}
}
#ifdef IPSO_LIGHT_CONTROL
if(IPSO_LIGHT_CONTROL.set_dim_level) {
IPSO_LIGHT_CONTROL.set_dim_level(dim_level);
} else if(IPSO_LIGHT_CONTROL.set_on) {
IPSO_LIGHT_CONTROL.set_on(is_on);
}
#endif /* IPSO_LIGHT_CONTROL */
}
return len;
}
/*---------------------------------------------------------------------------*/
static int
read_on_time(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
unsigned long now;
if(is_on) {
/* Update the on time */
now = clock_seconds();
total_on_time += now - last_on_time;
last_on_time = now;
}
return ctx->writer->write_int(ctx, outbuf, outsize, (int32_t)total_on_time);
}
/*---------------------------------------------------------------------------*/
static int
write_on_time(lwm2m_context_t *ctx,
const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
int32_t value;
size_t len;
len = ctx->reader->read_int(ctx, inbuf, insize, &value);
if(len > 0 && value == 0) {
total_on_time = 0;
if(is_on) {
last_on_time = clock_seconds();
}
}
return len;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(light_control_resources,
LWM2M_RESOURCE_CALLBACK(5850, { read_state, write_state, NULL }),
LWM2M_RESOURCE_CALLBACK(5851, { read_dim, write_dim, NULL }),
LWM2M_RESOURCE_CALLBACK(5852, { read_on_time, write_on_time, NULL }),
);
LWM2M_INSTANCES(light_control_instances,
LWM2M_INSTANCE(0, light_control_resources));
LWM2M_OBJECT(light_control, 3311, light_control_instances);
/*---------------------------------------------------------------------------*/
void
ipso_light_control_init(void)
{
#ifdef IPSO_LIGHT_CONTROL
if(IPSO_LIGHT_CONTROL.init) {
IPSO_LIGHT_CONTROL.init();
}
if(IPSO_LIGHT_CONTROL.is_on) {
is_on = IPSO_LIGHT_CONTROL.is_on();
}
if(IPSO_LIGHT_CONTROL.get_dim_level) {
dim_level = IPSO_LIGHT_CONTROL.get_dim_level();
if(dim_level > 0 && IPSO_LIGHT_CONTROL.is_on == NULL) {
is_on = 1;
}
}
#endif /* IPSO_LIGHT_CONTROL */
last_on_time = clock_seconds();
lwm2m_engine_register_object(&light_control);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Implementation of the IPSO Objects
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "contiki.h"
#include "ipso-objects.h"
/*---------------------------------------------------------------------------*/
void
ipso_objects_init(void)
{
/* initialize any relevant object for the IPSO Objects */
#ifdef IPSO_TEMPERATURE
ipso_temperature_init();
#endif
#if PLATFORM_HAS_BUTTON
ipso_button_init();
#endif
#ifdef IPSO_LIGHT_CONTROL
ipso_light_control_init();
#elif PLATFORM_HAS_LEDS
ipso_leds_control_init();
#endif
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup ipso-objects An implementation of IPSO Objects
* @{
*
* This application is an implementation of IPSO Objects for
* OMA Lightweight M2M.
*/
/**
* \file
* Header file for the Contiki IPSO Objects for OMA LWM2M
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef IPSO_OBJECTS_H_
#define IPSO_OBJECTS_H_
#include "contiki-conf.h"
void ipso_temperature_init(void);
void ipso_button_init(void);
void ipso_light_control_init(void);
void ipso_leds_control_init(void);
/* the init function to register the IPSO objects */
void ipso_objects_init(void);
struct ipso_objects_actuator {
/**
* \brief Initialize the driver.
*/
void (* init)(void);
/**
* \brief Check if the actuator is on or off.
*
* \return Zero if the actuator is off and non-zero otherwise.
*/
int (* is_on)(void);
/**
* \brief Set the actuator to on or off.
*
* \param onoroff Zero to set the actuator to off and non-zero otherwise.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* set_on)(int onoroff);
/**
* \brief Set the actuator to on or off.
*
* \param onoroff Zero to set the actuator to off and non-zero otherwise.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* get_dim_level)(void);
/**
* \brief Set the dim level of the actuator.
*
* \param level The dim level between 0% and 100%.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* set_dim_level)(int level);
};
struct ipso_objects_sensor {
/**
* \brief Initialize the driver.
*/
void (* init)(void);
/**
* \brief Read the sensor value in 1/1000 units.
*
* \param value A pointer to the variable to hold the sensor value.
* \return Zero if ok and a non-zero error code otherwise.
*/
int (* read_value)(int32_t *value);
};
#endif /* IPSO_OBJECTS_H_ */
/**
* @}
* @}
*/

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Temperature
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "ipso-objects.h"
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "er-coap-engine.h"
#ifdef IPSO_TEMPERATURE
extern const struct ipso_objects_sensor IPSO_TEMPERATURE;
#endif /* IPSO_TEMPERATURE */
#ifndef IPSO_TEMPERATURE_MIN
#define IPSO_TEMPERATURE_MIN (-50 * LWM2M_FLOAT32_FRAC)
#endif
#ifndef IPSO_TEMPERATURE_MAX
#define IPSO_TEMPERATURE_MAX (80 * LWM2M_FLOAT32_FRAC)
#endif
static struct ctimer periodic_timer;
static int32_t min_temp;
static int32_t max_temp;
static int read_temp(int32_t *value);
/*---------------------------------------------------------------------------*/
static int
temp(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
int32_t value;
if(read_temp(&value)) {
return ctx->writer->write_float32fix(ctx, outbuf, outsize,
value, LWM2M_FLOAT32_BITS);
}
return 0;
}
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(temperature_resources,
/* Temperature (Current) */
LWM2M_RESOURCE_CALLBACK(5700, { temp, NULL, NULL }),
/* Units */
LWM2M_RESOURCE_STRING(5701, "Celcius"),
/* Min Range Value */
LWM2M_RESOURCE_FLOATFIX(5603, IPSO_TEMPERATURE_MIN),
/* Max Range Value */
LWM2M_RESOURCE_FLOATFIX(5604, IPSO_TEMPERATURE_MAX),
/* Min Measured Value */
LWM2M_RESOURCE_FLOATFIX_VAR(5601, &min_temp),
/* Max Measured Value */
LWM2M_RESOURCE_FLOATFIX_VAR(5602, &max_temp),
);
LWM2M_INSTANCES(temperature_instances,
LWM2M_INSTANCE(0, temperature_resources));
LWM2M_OBJECT(temperature, 3303, temperature_instances);
/*---------------------------------------------------------------------------*/
static int
read_temp(int32_t *value)
{
#ifdef IPSO_TEMPERATURE
int32_t temp;
if(IPSO_TEMPERATURE.read_value == NULL ||
IPSO_TEMPERATURE.read_value(&temp) != 0) {
return 0;
}
/* Convert milliCelsius to fix float */
*value = (temp * LWM2M_FLOAT32_FRAC) / 1000;
if(*value < min_temp) {
min_temp = *value;
lwm2m_object_notify_observers(&temperature, "/0/5601");
}
if(*value > max_temp) {
max_temp = *value;
lwm2m_object_notify_observers(&temperature, "/0/5602");
}
return 1;
#else /* IPSO_TEMPERATURE */
return 0;
#endif /* IPSO_TEMPERATURE */
}
/*---------------------------------------------------------------------------*/
static void
handle_periodic_timer(void *ptr)
{
static int32_t last_value = IPSO_TEMPERATURE_MIN;
int32_t v;
/* Only notify when the value has changed since last */
if(read_temp(&v) && v != last_value) {
last_value = v;
lwm2m_object_notify_observers(&temperature, "/0/5700");
}
ctimer_reset(&periodic_timer);
}
/*---------------------------------------------------------------------------*/
void
ipso_temperature_init(void)
{
int32_t v;
min_temp = IPSO_TEMPERATURE_MAX;
max_temp = IPSO_TEMPERATURE_MIN;
#ifdef IPSO_TEMPERATURE
if(IPSO_TEMPERATURE.init) {
IPSO_TEMPERATURE.init();
}
#endif /* IPSO_TEMPERATURE */
/* register this device and its handlers - the handlers automatically
sends in the object to handle */
lwm2m_engine_register_object(&temperature);
/* update temp and min/max + notify any listeners */
read_temp(&v);
ctimer_set(&periodic_timer, CLOCK_SECOND * 10, handle_periodic_timer, NULL);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,5 @@
oma-lwm2m_src = lwm2m-object.c lwm2m-engine.c \
lwm2m-device.c lwm2m-server.c lwm2m-security.c \
oma-tlv.c oma-tlv-reader.c oma-tlv-writer.c \
lwm2m-plain-text.c
CFLAGS += -DHAVE_OMA_LWM2M=1

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M device
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-device.h"
#include "lwm2m-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
static int32_t time_offset = 0;
/*---------------------------------------------------------------------------*/
static int
read_lwtime(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outsize)
{
return ctx->writer->write_int(ctx, outbuf, outsize,
time_offset + clock_seconds());
}
/*---------------------------------------------------------------------------*/
static int
set_lwtime(lwm2m_context_t *ctx, const uint8_t *inbuf, size_t insize,
uint8_t *outbuf, size_t outsize)
{
/* assume that this only read one TLV value */
int32_t lw_time;
size_t len = ctx->reader->read_int(ctx, inbuf, insize, &lw_time);
if(len == 0) {
PRINTF("FAIL: could not read time '%*.s'\n", (int)insize, inbuf);
} else {
PRINTF("Got: time: %*.s => %" PRId32 "\n", (int)insize, inbuf, lw_time);
time_offset = lw_time - clock_seconds();
PRINTF("Write time...%" PRId32 " => offset = %" PRId32 "\n",
lw_time, time_offset);
}
/* return the number of bytes read */
return len;
}
/*---------------------------------------------------------------------------*/
#ifdef PLATFORM_REBOOT
static struct ctimer reboot_timer;
static void
do_the_reboot(void *ptr)
{
PLATFORM_REBOOT();
}
static int
reboot(lwm2m_context_t *ctx, const uint8_t *arg, size_t argsize,
uint8_t *outbuf, size_t outsize)
{
PRINTF("Device will reboot!\n");
ctimer_set(&reboot_timer, CLOCK_SECOND / 2, do_the_reboot, NULL);
return 0;
}
#endif /* PLATFORM_REBOOT */
/*---------------------------------------------------------------------------*/
#ifdef PLATFORM_FACTORY_DEFAULT
static int
factory_reset(lwm2m_context_t *ctx, const uint8_t *arg, size_t arg_size,
uint8_t *outbuf, size_t outsize)
{
PRINTF("Device will do factory default!\n");
PLATFORM_FACTORY_DEFAULT();
return 0;
}
#endif /* PLATFORM_FACTORY_DEFAULT */
/*---------------------------------------------------------------------------*/
LWM2M_RESOURCES(device_resources,
#ifdef LWM2M_DEVICE_MANUFACTURER
LWM2M_RESOURCE_STRING(0, LWM2M_DEVICE_MANUFACTURER),
#endif /* LWM2M_DEVICE_MANUFACTURER */
#ifdef LWM2M_DEVICE_TYPE
LWM2M_RESOURCE_STRING(17, LWM2M_DEVICE_TYPE),
#endif /* LWM2M_DEVICE_TYPE */
#ifdef LWM2M_DEVICE_MODEL_NUMBER
LWM2M_RESOURCE_STRING(1, LWM2M_DEVICE_MODEL_NUMBER),
#endif /* LWM2M_DEVICE_MODEL_NUMBER */
#ifdef LWM2M_DEVICE_SERIAL_NO
LWM2M_RESOURCE_STRING(2, LWM2M_DEVICE_SERIAL_NO),
#endif /* LWM2M_DEVICE_SERIAL_NO */
#ifdef LWM2M_DEVICE_FIRMWARE_VERSION
LWM2M_RESOURCE_STRING(3, LWM2M_DEVICE_FIRMWARE_VERSION),
#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */
#ifdef PLATFORM_REBOOT
LWM2M_RESOURCE_CALLBACK(4, { NULL, NULL, reboot }),
#endif /* PLATFORM_REBOOT */
#ifdef PLATFORM_FACTORY_DEFAULT
LWM2M_RESOURCE_CALLBACK(5, { NULL, NULL, factory_reset }),
#endif /* PLATFORM_FACTORY_DEFAULT */
/* Current Time */
LWM2M_RESOURCE_CALLBACK(13, { read_lwtime, set_lwtime, NULL }),
);
LWM2M_INSTANCES(device_instances, LWM2M_INSTANCE(0, device_resources));
LWM2M_OBJECT(device, 3, device_instances);
/*---------------------------------------------------------------------------*/
void
lwm2m_device_init(void)
{
/**
* Register this device and its handlers - the handlers
* automatically sends in the object to handle.
*/
PRINTF("*** Init lwm2m-device\n");
lwm2m_engine_register_object(&device);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Header file for the Contiki OMA LWM2M device
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_DEVICE_H_
#define LWM2M_DEVICE_H_
#include "contiki-conf.h"
#ifndef LWM2M_DEVICE_MODEL_NUMBER
#ifdef BOARD_STRING
#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING
#endif /* BOARD_STRING */
#endif /* LWM2M_DEVICE_MODEL_NUMBER */
#ifndef LWM2M_DEVICE_FIRMWARE_VERSION
#define LWM2M_DEVICE_FIRMWARE_VERSION CONTIKI_VERSION_STRING
#endif /* LWM2M_DEVICE_FIRMWARE_VERSION */
void lwm2m_device_init(void);
#endif /* LWM2M_DEVICE_H_ */
/** @} */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Header file for the Contiki OMA LWM2M engine
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_ENGINE_H
#define LWM2M_ENGINE_H
#include "lwm2m-object.h"
#define LWM2M_FLOAT32_BITS 10
#define LWM2M_FLOAT32_FRAC (1L << LWM2M_FLOAT32_BITS)
/* LWM2M / CoAP Content-Formats */
typedef enum {
LWM2M_TEXT_PLAIN = 1541,
LWM2M_TLV = 1542,
LWM2M_JSON = 1543,
LWM2M_OPAQUE = 1544
} lwm2m_content_format_t;
void lwm2m_engine_init(void);
void lwm2m_engine_register_default_objects(void);
void lwm2m_engine_use_bootstrap_server(int use);
void lwm2m_engine_use_registration_server(int use);
void lwm2m_engine_register_with_server(const uip_ipaddr_t *server, uint16_t port);
void lwm2m_engine_register_with_bootstrap_server(const uip_ipaddr_t *server, uint16_t port);
const lwm2m_object_t *lwm2m_engine_get_object(uint16_t id);
int lwm2m_engine_register_object(const lwm2m_object_t *object);
void lwm2m_engine_handler(const lwm2m_object_t *object,
void *request, void *response,
uint8_t *buffer, uint16_t preferred_size,
int32_t *offset);
void lwm2m_engine_delete_handler(const lwm2m_object_t *object,
void *request, void *response,
uint8_t *buffer, uint16_t preferred_size,
int32_t *offset);
#endif /* LWM2M_ENGINE_H */
/** @} */

View file

@ -0,0 +1,336 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M object API
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_string(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
const uint8_t *
lwm2m_object_get_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context)
{
if(resource == NULL || context == NULL) {
return NULL;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) {
return resource->value.string.value;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) {
return *(resource->value.stringvar.var);
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.stringvararr.count) {
return resource->value.stringvararr.var +
resource->value.stringvararr.size * context->object_instance_index;
}
return NULL;
}
/* Not a string */
return NULL;
}
/*---------------------------------------------------------------------------*/
uint16_t
lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource,
const lwm2m_context_t *context)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VALUE) {
return resource->value.string.len;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) {
return *(resource->value.stringvar.len);
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.stringvararr.count) {
return resource->value.stringvararr.len[context->object_instance_index];
}
return 0;
}
/* Not a string */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
uint16_t len, const uint8_t *string)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE) {
if(len > resource->value.stringvar.size) {
/* Too large */
return 0;
}
memcpy(resource->value.stringvar.var, string, len);
*(resource->value.stringvar.len) = len;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.stringvararr.count &&
len <= resource->value.stringvararr.size) {
memcpy(resource->value.stringvararr.var +
resource->value.stringvararr.size * context->object_instance_index,
string, len);
resource->value.stringvararr.len[context->object_instance_index] = len;
return 1;
}
return 0;
}
/* Not a string variable */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_int(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_get_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value)
{
if(resource == NULL || context == NULL || value == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VALUE) {
*value = resource->value.integer.value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) {
*value = *(resource->value.integervar.var);
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.integervararr.count) {
*value = resource->value.integervararr.var[context->object_instance_index];
return 1;
}
return 0;
}
/* Not an integer */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE) {
*(resource->value.integervar.var) = value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.integervararr.count) {
resource->value.integervararr.var[context->object_instance_index] =
value;
return 1;
}
return 0;
}
/* Not an integer variable */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value)
{
if(resource == NULL || context == NULL || value == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE) {
*value = resource->value.floatfix.value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) {
*value = *(resource->value.floatfixvar.var);
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.floatfixvararr.count) {
*value = resource->value.floatfixvararr.var[context->object_instance_index];
return 1;
}
return 0;
}
/* Not an float */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE) {
*(resource->value.floatfixvar.var) = value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.floatfixvararr.count) {
resource->value.floatfixvararr.var[context->object_instance_index] =
value;
return 1;
}
return 0;
}
/* Not an float variable */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource)
{
if(resource == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE ||
resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE ||
resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int *value)
{
if(resource == NULL || context == NULL || value == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE) {
*value = resource->value.boolean.value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) {
*value = *(resource->value.booleanvar.var);
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.booleanvararr.count) {
*value = resource->value.booleanvararr.var[context->object_instance_index];
return 1;
}
return 0;
}
/* Not a boolean */
return 0;
}
/*---------------------------------------------------------------------------*/
int
lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int value)
{
if(resource == NULL || context == NULL) {
return 0;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE) {
*(resource->value.booleanvar.var) = value;
return 1;
}
if(resource->type == LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY) {
if(context->object_instance_index < resource->value.booleanvararr.count) {
resource->value.booleanvararr.var[context->object_instance_index] =
value;
return 1;
}
return 0;
}
/* Not a boolean variable */
return 0;
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,359 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup apps
* @{
*/
/**
* \defgroup oma-lwm2m An implementation of OMA LWM2M
* @{
*
* This application is an implementation of OMA Lightweight M2M.
*/
/**
* \file
* Header file for the Contiki OMA LWM2M object API
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_OBJECT_H_
#define LWM2M_OBJECT_H_
#include "rest-engine.h"
#include "er-coap-observe.h"
#define LWM2M_OBJECT_SECURITY_ID 0
#define LWM2M_OBJECT_SERVER_ID 1
#define LWM2M_OBJECT_ACCESS_CONTROL_ID 2
#define LWM2M_OBJECT_DEVICE_ID 3
#define LWM2M_OBJECT_CONNECTIVITY_MONITORING_ID 4
#define LWM2M_OBJECT_FIRMWARE_ID 5
#define LWM2M_OBJECT_LOCATION_ID 6
#define LWM2M_OBJECT_CONNECTIVITY_STATISTICS_ID 7
#define LWM2M_SECURITY_SERVER_URI 0
#define LWM2M_SECURITY_BOOTSTRAP_SERVER 1
#define LWM2M_SECURITY_MODE 2
#define LWM2M_SECURITY_CLIENT_PKI 3
#define LWM2M_SECURITY_SERVER_PKI 4
#define LWM2M_SECURITY_KEY 5
#define LWM2M_SECURITY_SHORT_SERVER_ID 10
/* Pre-shared key mode */
#define LWM2M_SECURITY_MODE_PSK 0
/* Raw Public Key mode */
#define LWM2M_SECURITY_MODE_RPK 1
/* Certificate mode */
#define LWM2M_SECURITY_MODE_CERTIFICATE 2
/* NoSec mode */
#define LWM2M_SECURITY_MODE_NOSEC 3
#define LWM2M_OBJECT_STR_HELPER(x) (uint8_t *) #x
#define LWM2M_OBJECT_STR(x) LWM2M_OBJECT_STR_HELPER(x)
#define LWM2M_OBJECT_PATH_STR_HELPER(x) #x
#define LWM2M_OBJECT_PATH_STR(x) LWM2M_OBJECT_PATH_STR_HELPER(x)
struct lwm2m_reader;
struct lwm2m_writer;
/* Data model for OMA LWM2M objects */
typedef struct lwm2m_context {
uint16_t object_id;
uint16_t object_instance_id;
uint16_t resource_id;
uint8_t object_instance_index;
uint8_t resource_index;
/* TODO - add uint16_t resource_instance_id */
const struct lwm2m_reader *reader;
const struct lwm2m_writer *writer;
} lwm2m_context_t;
/* LWM2M format writer for the various formats supported */
typedef struct lwm2m_writer {
size_t (* write_int)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value);
size_t (* write_string)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, const char *value, size_t strlen);
size_t (* write_float32fix)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int32_t value, int bits);
size_t (* write_boolean)(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen, int value);
} lwm2m_writer_t;
typedef struct lwm2m_reader {
size_t (* read_int)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value);
size_t (* read_string)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, uint8_t *value, size_t strlen);
size_t (* read_float32fix)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int32_t *value, int bits);
size_t (* read_boolean)(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len, int *value);
} lwm2m_reader_t;
typedef struct lwm2m_value_callback {
int (* read)(lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen);
int (* write)(lwm2m_context_t *ctx,
const uint8_t *buffer, size_t len,
uint8_t *outbuf, size_t outlen);
int (* exec)(lwm2m_context_t *ctx, const uint8_t *arg, size_t len,
uint8_t *outbuf, size_t outlen);
} lwm2m_value_callback_t;
#define LWM2M_RESOURCE_TYPE_STR_VALUE 1
#define LWM2M_RESOURCE_TYPE_STR_VARIABLE 2
#define LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY 3
#define LWM2M_RESOURCE_TYPE_INT_VALUE 4
#define LWM2M_RESOURCE_TYPE_INT_VARIABLE 5
#define LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY 6
#define LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE 7
#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE 8
#define LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY 9
#define LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE 10
#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE 11
#define LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY 12
#define LWM2M_RESOURCE_TYPE_CALLBACK 16
#define LWM2M_RESOURCE_TYPE_INSTANCES 17
typedef struct lwm2m_resource {
uint16_t id;
uint8_t type; /* indicate value type and multi-instance resource */
union {
struct {
uint16_t len;
const uint8_t *value;
} string;
struct {
uint16_t size;
uint16_t *len;
uint8_t **var;
} stringvar;
struct {
uint16_t count;
uint16_t size;
/* string var array with counting entries */
uint16_t *len;
uint8_t *var;
} stringvararr;
struct {
int32_t value;
} integer;
struct {
int32_t *var;
} integervar;
struct {
/* used for multiple instances (dynamic) NOTE: this is an index into
the instance so having two instances means that there is need for
allocation of two ints here */
uint16_t count;
int32_t *var; /* used as an array? */
} integervararr;
struct {
int32_t value;
} floatfix;
struct {
int32_t *var;
} floatfixvar;
struct {
uint16_t count;
int32_t *var;
} floatfixvararr;
struct {
int value;
} boolean;
struct {
int *var;
} booleanvar;
struct {
uint16_t count;
int *var;
} booleanvararr;
lwm2m_value_callback_t callback;
/* lwm2m_resource *resources[]; TO BE ADDED LATER*/
} value;
} lwm2m_resource_t;
#define LWM2M_INSTANCE_FLAG_USED 1
typedef struct lwm2m_instance {
uint16_t id;
uint16_t count;
uint16_t flag;
const lwm2m_resource_t *resources;
} lwm2m_instance_t;
typedef struct lwm2m_object {
uint16_t id;
uint16_t count;
const char *path;
resource_t *coap_resource;
lwm2m_instance_t *instances;
} lwm2m_object_t;
#define LWM2M_RESOURCES(name, ...) \
static const lwm2m_resource_t name[] = { __VA_ARGS__ }
#define LWM2M_RESOURCE_STRING(id, s) \
{ id, LWM2M_RESOURCE_TYPE_STR_VALUE, .value.string.len = sizeof(s) - 1, .value.string.value = (uint8_t *) s }
#define LWM2M_RESOURCE_STRING_VAR(id, s, l, v) \
{ id, LWM2M_RESOURCE_TYPE_STR_VARIABLE, .value.stringvar.size = (s), .value.stringvar.len = (l), .value.stringvar.var = (v) }
#define LWM2M_RESOURCE_STRING_VAR_ARR(id, c, s, l, v) \
{ id, LWM2M_RESOURCE_TYPE_STR_VARIABLE_ARRAY, .value.stringvararr.count = c, .value.stringvararr.size = s, .value.stringvararr.len = l, .value.stringvararr.var = (uint8_t *) v }
#define LWM2M_RESOURCE_INTEGER(id, v) \
{ id, LWM2M_RESOURCE_TYPE_INT_VALUE, .value.integer.value = (v) }
#define LWM2M_RESOURCE_INTEGER_VAR(id, v) \
{ id, LWM2M_RESOURCE_TYPE_INT_VARIABLE, .value.integervar.var = (v) }
#define LWM2M_RESOURCE_INTEGER_VAR_ARR(id, c, v) \
{ id, LWM2M_RESOURCE_TYPE_INT_VARIABLE_ARRAY, .value.integervararr.count = (c), .value.integervararr.var = (v) }
#define LWM2M_RESOURCE_FLOATFIX(id, v) \
{ id, LWM2M_RESOURCE_TYPE_FLOATFIX_VALUE, .value.floatfix.value = (v) }
#define LWM2M_RESOURCE_FLOATFIX_VAR(id, v) \
{ id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE, .value.floatfixvar.var = (v) }
#define LWM2M_RESOURCE_FLOATFIX_VAR_ARR(id, c, v) \
{ id, LWM2M_RESOURCE_TYPE_FLOATFIX_VARIABLE_ARRAY, .value.floatfixvararr.count = (c), .value.floatfixvararr.var = (v) }
#define LWM2M_RESOURCE_BOOLEAN(id, v) \
{ id, LWM2M_RESOURCE_TYPE_BOOLEAN_VALUE, .value.boolean.value = (v) }
#define LWM2M_RESOURCE_BOOLEAN_VAR(id, v) \
{ id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE, .value.booleanvar.var = (v) }
#define LWM2M_RESOURCE_BOOLEAN_VAR_ARR(id, c, v) \
{ id, LWM2M_RESOURCE_TYPE_BOOLEAN_VARIABLE_ARRAY, .value.booleanvararr.count = (c), .value.booleanvararr.var = (v) }
#define LWM2M_RESOURCE_CALLBACK(id, ...) \
{ id, LWM2M_RESOURCE_TYPE_CALLBACK, .value.callback = __VA_ARGS__ }
#define LWM2M_INSTANCE(id, resources) \
{ id, sizeof(resources)/sizeof(lwm2m_resource_t), LWM2M_INSTANCE_FLAG_USED, resources }
#define LWM2M_INSTANCE_UNUSED(id, resources) \
{ id, sizeof(resources)/sizeof(lwm2m_resource_t), 0, resources }
#define LWM2M_INSTANCES(name, ...) \
static lwm2m_instance_t name[] = { __VA_ARGS__ }
#define LWM2M_OBJECT(name, id, instances) \
static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); \
static resource_t rest_rsc_##name = { NULL, NULL, HAS_SUB_RESOURCES | IS_OBSERVABLE, NULL, lwm2m_get_h_##name, lwm2m_post_h_##name, lwm2m_put_h_##name, lwm2m_delete_h_##name, { NULL } }; \
static const lwm2m_object_t name = { id, sizeof(instances)/sizeof(lwm2m_instance_t), LWM2M_OBJECT_PATH_STR(id), &rest_rsc_##name, instances}; \
static void lwm2m_get_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \
static void lwm2m_put_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \
static void lwm2m_post_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_handler(&name, request, response, buffer, preferred_size, offset); } \
static void lwm2m_delete_h_##name(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { \
lwm2m_engine_delete_handler(&name, request, response, buffer, preferred_size, offset); }
/* how do we register attributes in the above resource here ??? */
int lwm2m_object_is_resource_string(const lwm2m_resource_t *resource);
int lwm2m_object_is_resource_int(const lwm2m_resource_t *resource);
int lwm2m_object_is_resource_floatfix(const lwm2m_resource_t *resource);
int lwm2m_object_is_resource_boolean(const lwm2m_resource_t *resource);
static inline int
lwm2m_object_is_resource_callback(const lwm2m_resource_t *resource)
{
return resource != NULL && resource->type == LWM2M_RESOURCE_TYPE_CALLBACK;
}
const uint8_t *
lwm2m_object_get_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context);
uint16_t
lwm2m_object_get_resource_strlen(const lwm2m_resource_t *resource,
const lwm2m_context_t *context);
int
lwm2m_object_set_resource_string(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
uint16_t len, const uint8_t *string);
int
lwm2m_object_get_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value);
int
lwm2m_object_set_resource_int(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value);
int
lwm2m_object_get_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t *value);
int
lwm2m_object_set_resource_floatfix(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int32_t value);
int
lwm2m_object_get_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int *value);
int
lwm2m_object_set_resource_boolean(const lwm2m_resource_t *resource,
const lwm2m_context_t *context,
int value);
static inline resource_t *
lwm2m_object_get_coap_resource(const lwm2m_object_t *object)
{
return (resource_t *)object->coap_resource;
}
static inline void
lwm2m_object_notify_observers(const lwm2m_object_t *object, char *path)
{
coap_notify_observers_sub(lwm2m_object_get_coap_resource(object), path);
}
#include "lwm2m-engine.h"
#endif /* LWM2M_OBJECT_H_ */
/**
* @}
* @}
*/

View file

@ -0,0 +1,248 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M plain text reader / writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-plain-text.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
size_t
lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len, int32_t *value)
{
int i, neg = 0;
*value = 0;
for(i = 0; i < len; i++) {
if(inbuf[i] >= '0' && inbuf[i] <= '9') {
*value = *value * 10 + (inbuf[i] - '0');
} else if(inbuf[i] == '-' && i == 0) {
neg = 1;
} else {
break;
}
}
if(neg) {
*value = -*value;
}
return i;
}
/*---------------------------------------------------------------------------*/
size_t
lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len,
int32_t *value, int bits)
{
int i, dot = 0, neg = 0;
int32_t counter, integerpart, frac;
integerpart = 0;
counter = 0;
frac = 0;
for(i = 0; i < len; i++) {
if(inbuf[i] >= '0' && inbuf[i] <= '9') {
counter = counter * 10 + (inbuf[i] - '0');
frac = frac * 10;
} else if(inbuf[i] == '.' && dot == 0) {
integerpart = counter;
counter = 0;
frac = 1;
dot = 1;
} else if(inbuf[i] == '-' && i == 0) {
neg = 1;
} else {
break;
}
}
*value = integerpart << bits;
if(frac > 1) {
*value += ((counter << bits) / frac);
}
PRINTF("READ FLOATFIX: \"%.*s\" => int(%ld) frac(%ld) f=%ld Value=%ld\n",
(int)len, (char *)inbuf,
(long)integerpart,
(long)counter,
(long)frac,
(long)*value);
if(neg) {
*value = -*value;
}
return i;
}
/*---------------------------------------------------------------------------*/
size_t
lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen,
int32_t value, int bits)
{
int64_t v;
unsigned long integer_part;
unsigned long frac_part;
int n, o = 0;
if(outlen == 0) {
return 0;
}
if(value < 0) {
*outbuf++ = '-';
outlen--;
o = 1;
value = -value;
}
integer_part = (unsigned long)(value >> bits);
v = value - (integer_part << bits);
v = (v * 100) >> bits;
frac_part = (unsigned long)v;
n = snprintf((char *)outbuf, outlen, "%lu.%02lu", integer_part, frac_part);
if(n < 0 || n >= outlen) {
return 0;
}
return n + o;
}
/*---------------------------------------------------------------------------*/
static size_t
write_boolean(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int value)
{
if(outlen > 0) {
if(value) {
*outbuf = '1';
} else {
*outbuf = '0';
}
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static size_t
write_int(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int32_t value)
{
int n = snprintf((char *)outbuf, outlen, "%ld", (long)value);
if(n < 0 || n >= outlen) {
return 0;
}
return n;
}
/*---------------------------------------------------------------------------*/
static size_t
write_float32fix(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int32_t value, int bits)
{
return lwm2m_plain_text_write_float32fix(outbuf, outlen, value, bits);
}
/*---------------------------------------------------------------------------*/
static size_t
write_string(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
const char *value, size_t stringlen)
{
int n = snprintf((char *)outbuf, outlen, "%.*s", (int) stringlen, value);
if(n < 0 || n >= outlen) {
return 0;
}
return n;
}
/*---------------------------------------------------------------------------*/
const lwm2m_writer_t lwm2m_plain_text_writer = {
write_int,
write_string,
write_float32fix,
write_boolean
};
/*---------------------------------------------------------------------------*/
static size_t
read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value)
{
return lwm2m_plain_text_read_int(inbuf, len, value);
}
/*---------------------------------------------------------------------------*/
static size_t
read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
uint8_t *value, size_t stringlen)
{
if(stringlen <= len) {
/* The outbuffer can not contain the full string including ending zero */
return 0;
}
memcpy(value, inbuf, len);
value[len] = '\0';
return len;
}
/*---------------------------------------------------------------------------*/
static size_t
read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value, int bits)
{
return lwm2m_plain_text_read_float32fix(inbuf, len, value, bits);
}
/*---------------------------------------------------------------------------*/
static size_t
read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int *value)
{
if(len > 0) {
if(*inbuf == '1' || *inbuf == '0') {
*value = *inbuf == '1' ? 1 : 0;
return 1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
const lwm2m_reader_t lwm2m_plain_text_reader = {
read_int,
read_string,
read_float32fix,
read_boolean
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*/
/**
* \file
* Header file for the Contiki OMA LWM2M plain text reader / writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef LWM2M_PLAIN_TEXT_H_
#define LWM2M_PLAIN_TEXT_H_
#include "lwm2m-object.h"
extern const lwm2m_reader_t lwm2m_plain_text_reader;
extern const lwm2m_writer_t lwm2m_plain_text_writer;
size_t lwm2m_plain_text_read_int(const uint8_t *inbuf, size_t len,
int32_t *value);
size_t lwm2m_plain_text_read_float32fix(const uint8_t *inbuf, size_t len,
int32_t *value, int bits);
size_t lwm2m_plain_text_write_float32fix(uint8_t *outbuf, size_t outlen,
int32_t value, int bits);
#endif /* LWM2M_PLAIN_TEXT_H_ */
/** @} */

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M security
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#ifdef LWM2M_CONF_SERVER_MAX_COUNT
#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT
#else
#define MAX_COUNT 2
#endif
/* hoping that we do not get more than 64 bytes... */
#define MAX_SIZE 64
static int32_t bs_arr[MAX_COUNT];
static int32_t secmode_arr[MAX_COUNT];
static int32_t sid_arr[MAX_COUNT];
static char server_uri[MAX_COUNT][MAX_SIZE];
static uint16_t su_len[MAX_COUNT];
static char client_id[MAX_COUNT][MAX_SIZE];
static uint16_t client_id_len[MAX_COUNT];
static char server_id[MAX_COUNT][MAX_SIZE];
static uint16_t server_id_len[MAX_COUNT];
static char psk_key[MAX_COUNT][MAX_SIZE];
static uint16_t psk_key_len[MAX_COUNT];
static lwm2m_instance_t security_instances[MAX_COUNT];
LWM2M_RESOURCES(security_resources,
LWM2M_RESOURCE_STRING_VAR_ARR(0, MAX_COUNT, MAX_SIZE, su_len, server_uri),
LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, bs_arr),
LWM2M_RESOURCE_INTEGER_VAR_ARR(2, MAX_COUNT, secmode_arr),
LWM2M_RESOURCE_STRING_VAR_ARR(3, MAX_COUNT, MAX_SIZE, client_id_len, client_id),
LWM2M_RESOURCE_STRING_VAR_ARR(4, MAX_COUNT, MAX_SIZE, server_id_len, server_id),
/* TODO This should not be readable! */
LWM2M_RESOURCE_STRING_VAR_ARR(5, MAX_COUNT, MAX_SIZE, psk_key_len, psk_key),
LWM2M_RESOURCE_INTEGER_VAR_ARR(10, MAX_COUNT, sid_arr)
);
LWM2M_OBJECT(security, 0, security_instances);
/*---------------------------------------------------------------------------*/
void
lwm2m_security_init(void)
{
lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, security_resources);
int i;
/* Initialize the instances */
for(i = 0; i < MAX_COUNT; i++) {
security_instances[i] = template;
security_instances[i].id = i;
}
/**
* Register this device and its handlers - the handlers
* automatically sends in the object to handle.
*/
PRINTF("*** Init lwm2m-security\n");
lwm2m_engine_register_object(&security);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M server
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#ifdef LWM2M_CONF_SERVER_MAX_COUNT
#define MAX_COUNT LWM2M_CONF_SERVER_MAX_COUNT
#else
#define MAX_COUNT 2
#endif
static int32_t sid_arr[MAX_COUNT];
static int32_t lifetime_arr[MAX_COUNT];
static lwm2m_instance_t server_instances[MAX_COUNT];
LWM2M_RESOURCES(server_resources,
LWM2M_RESOURCE_INTEGER_VAR_ARR(0, MAX_COUNT, sid_arr),
LWM2M_RESOURCE_INTEGER_VAR_ARR(1, MAX_COUNT, lifetime_arr),
);
LWM2M_OBJECT(server, 1, server_instances);
/*---------------------------------------------------------------------------*/
void
lwm2m_server_init(void)
{
lwm2m_instance_t template = LWM2M_INSTANCE_UNUSED(0, server_resources);
int i;
/* Initialize the instances */
for(i = 0; i < MAX_COUNT; i++) {
server_instances[i] = template;
server_instances[i].id = i;
}
/**
* Register this device and its handlers - the handlers
* automatically sends in the object to handle
*/
PRINTF("*** Init lwm2m-server\n");
lwm2m_engine_register_object(&server);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M TLV reader
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "oma-tlv-reader.h"
#include "oma-tlv.h"
/*---------------------------------------------------------------------------*/
static size_t
read_int(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
*value = oma_tlv_get_int32(&tlv);
}
return size;
}
/*---------------------------------------------------------------------------*/
static size_t
read_string(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
uint8_t *value, size_t stringlen)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
if(stringlen <= tlv.length) {
/* The outbuffer can not contain the full string including ending zero */
return 0;
}
memcpy(value, tlv.value, tlv.length);
value[tlv.length] = '\0';
}
return size;
}
/*---------------------------------------------------------------------------*/
static size_t
read_float32fix(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int32_t *value, int bits)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
oma_tlv_float32_to_fix(&tlv, value, bits);
}
return size;
}
/*---------------------------------------------------------------------------*/
static size_t
read_boolean(const lwm2m_context_t *ctx, const uint8_t *inbuf, size_t len,
int *value)
{
oma_tlv_t tlv;
size_t size;
size = oma_tlv_read(&tlv, inbuf, len);
if(size > 0) {
*value = oma_tlv_get_int32(&tlv) != 0;
}
return size;
}
/*---------------------------------------------------------------------------*/
const lwm2m_reader_t oma_tlv_reader = {
read_int,
read_string,
read_float32fix,
read_boolean
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \addtogroup oma-lwm2m
* @{ */
/**
* \file
* Header file for the Contiki OMA LWM2M TLV reader
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef OMA_TLV_READER_H_
#define OMA_TLV_READER_H_
#include "lwm2m-object.h"
extern const lwm2m_reader_t oma_tlv_reader;
#endif /* OMA_TLV_READER_H_ */
/** @} */

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M TLV writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "oma-tlv.h"
/*---------------------------------------------------------------------------*/
static size_t
write_boolean_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int value)
{
return oma_tlv_write_int32(ctx->resource_id, value != 0 ? 1 : 0,
outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
static size_t
write_int_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
int32_t value)
{
return oma_tlv_write_int32(ctx->resource_id, value, outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
static size_t
write_float32fix_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf,
size_t outlen, int32_t value, int bits)
{
return oma_tlv_write_float32(ctx->resource_id, value, bits, outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
static size_t
write_string_tlv(const lwm2m_context_t *ctx, uint8_t *outbuf, size_t outlen,
const char *value, size_t stringlen)
{
oma_tlv_t tlv;
tlv.type = OMA_TLV_TYPE_RESOURCE;
tlv.value = (uint8_t *) value;
tlv.length = (uint32_t) stringlen;
tlv.id = ctx->resource_id;
return oma_tlv_write(&tlv, outbuf, outlen);
}
/*---------------------------------------------------------------------------*/
const lwm2m_writer_t oma_tlv_writer = {
write_int_tlv,
write_string_tlv,
write_float32fix_tlv,
write_boolean_tlv
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \addtogroup oma-lwm2m
* @{ */
/**
* \file
* Header file for the Contiki OMA LWM2M TLV writer
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef OMA_TLV_WRITER_H_
#define OMA_TLV_WRITER_H_
#include "lwm2m-object.h"
extern const lwm2m_writer_t oma_tlv_writer;
#endif /* OMA_TLV_WRITER_H_ */
/** @} */

296
apps/oma-lwm2m/oma-tlv.c Normal file
View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup oma-lwm2m
* @{
*
*/
/**
* \file
* Implementation of the Contiki OMA LWM2M TLV
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <string.h>
#include <stdint.h>
#include "oma-tlv.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
static inline uint8_t
get_len_type(const oma_tlv_t *tlv)
{
if(tlv->length < 8) {
return 0;
} else if(tlv->length < 256) {
return 1;
} else if(tlv->length < 0x10000) {
return 2;
} else {
return 3;
}
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len)
{
uint8_t len_type;
uint8_t len_pos = 1;
size_t tlv_len;
tlv->type = (buffer[0] >> 6) & 3;
len_type = (buffer[0] >> 3) & 3;
len_pos = 1 + (((buffer[0] & (1 << 5)) != 0) ? 2 : 1);
tlv->id = buffer[1];
/* if len_pos is larger than two it means that there is more ID to read */
if(len_pos > 2) {
tlv->id = (tlv->id << 8) + buffer[2];
}
if(len_type == 0) {
tlv_len = buffer[0] & 7;
} else {
/* read the length */
tlv_len = 0;
while(len_type > 0) {
tlv_len = tlv_len << 8 | buffer[len_pos++];
len_type--;
}
}
/* and read out the data??? */
tlv->length = tlv_len;
tlv->value = &buffer[len_pos];
return len_pos + tlv_len;
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_get_size(const oma_tlv_t *tlv)
{
size_t size;
/* first hdr + len size */
size = 1 + get_len_type(tlv);
/* id size */
size += (tlv->id > 255) ? 2 : 1;
/* and the length */
size += tlv->length;
return size;
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len)
{
int pos;
uint8_t len_type;
/* len type is the same as number of bytes required for length */
len_type = get_len_type(tlv);
pos = 1 + len_type;
/* ensure that we do not write too much */
if(len < tlv->length + pos) {
PRINTF("OMA-TLV: Could not write the TLV - buffer overflow.\n");
return 0;
}
/* first type byte in TLV header */
buffer[0] = (tlv->type << 6) |
(tlv->id > 255 ? (1 << 5) : 0) |
(len_type << 3) |
(len_type == 0 ? tlv->length : 0);
pos = 1;
/* The ID */
if(tlv->id > 255) {
buffer[pos++] = (tlv->id >> 8) & 0xff;
}
buffer[pos++] = tlv->id & 0xff;
/* Add length if needed - unrolled loop ? */
if(len_type > 2) {
buffer[pos++] = (tlv->length >> 16) & 0xff;
}
if(len_type > 1) {
buffer[pos++] = (tlv->length >> 8) & 0xff;
}
if(len_type > 0) {
buffer[pos++] = tlv->length & 0xff;
}
/* finally add the value */
memcpy(&buffer[pos], tlv->value, tlv->length);
if(DEBUG) {
int i;
PRINTF("TLV:");
for(i = 0; i < pos + tlv->length; i++) {
PRINTF("%02x", buffer[i]);
}
PRINTF("\n");
}
return pos + tlv->length;
}
/*---------------------------------------------------------------------------*/
int32_t
oma_tlv_get_int32(const oma_tlv_t *tlv)
{
int i;
int32_t value = 0;
/* will probably need to handle MSB as a sign bit? */
for(i = 0; i < tlv->length; i++) {
value = (value << 8) | tlv->value[i];
}
return value;
}
/*---------------------------------------------------------------------------*/
size_t
oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len)
{
oma_tlv_t tlv;
size_t tlvlen = 0;
uint8_t buf[4];
int i;
PRINTF("Exporting int32 %d %ld ", id, (long)value);
buf[3] = value & 0xff;
value = value >> 8;
for(i = 1; value > 0 && i < 4; i++) {
buf[3 - i] = value & 0xff;
value = value >> 8;
}
tlvlen = i;
/* export INT as TLV */
PRINTF("len: %zu\n", tlvlen);
tlv.type = OMA_TLV_TYPE_RESOURCE;
tlv.length = tlvlen;
tlv.value = &buf[3 - (tlvlen - 1)];
tlv.id = id;
return oma_tlv_write(&tlv, buffer, len);
}
/*---------------------------------------------------------------------------*/
/* convert fixpoint 32-bit to a IEEE Float in the byte array*/
size_t
oma_tlv_write_float32(int16_t id, int32_t value, int bits,
uint8_t *buffer, size_t len)
{
int i;
int e = 0;
int32_t val = 0;
int32_t v;
uint8_t b[4];
oma_tlv_t tlv;
v = value;
if(v < 0) {
v = -v;
}
while(v > 1) {
val = (val >> 1);
if (v & 1) {
val = val | (1L << 22);
}
v = (v >> 1);
e++;
}
PRINTF("Sign: %d, Fraction: %06lx 0b", value < 0, (long)val);
for(i = 0; i < 23; i++) {
PRINTF("%d", (int)((val >> (22 - i)) & 1));
}
PRINTF("\nExp:%d\n", e);
/* convert to the thing we should have */
e = e - bits + 127;
/* is this the right byte order? */
b[0] = (value < 0 ? 0x80 : 0) | (e >> 1);
b[1] = ((e & 1) << 7) | ((val >> 16) & 0x7f);
b[2] = (val >> 8) & 0xff;
b[3] = val & 0xff;
/* construct the TLV */
tlv.type = OMA_TLV_TYPE_RESOURCE;
tlv.length = 4;
tlv.value = b;
tlv.id = id;
return oma_tlv_write(&tlv, buffer, len);
}
/*---------------------------------------------------------------------------*/
/* convert float to fixpoint */
size_t
oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits)
{
/* TLV needs to be 4 bytes */
int e, i;
int32_t val;
int sign = (tlv->value[0] & 0x80) != 0;
e = ((tlv->value[0] << 1) & 0xff) | (tlv->value[1] >> 7);
val = (((long)tlv->value[1] & 0x7f) << 16) | (tlv->value[2] << 8) | tlv->value[3];
PRINTF("Sign: %d, Fraction: %06lx 0b", val < 0, (long)val);
for(i = 0; i < 23; i++) {
PRINTF("%d", (int)((val >> (22 - i)) & 1));
}
PRINTF("\nExp:%d => %d\n", e, e - 127);
e = e - 127 + bits;
/* e corresponds to the number of times we need to roll the number */
PRINTF("Actual e=%d\n", e);
e = e - 23;
PRINTF("E after sub %d\n", e);
val = val | 1L << 23;
if(e > 0) {
val = val << e;
} else {
val = val >> -e;
}
*value = sign ? -val : val;
return 4;
}
/*---------------------------------------------------------------------------*/
/** @} */

89
apps/oma-lwm2m/oma-tlv.h Normal file
View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \addtogroup oma-lwm2m
* @{ */
/**
* \file
* Header file for the Contiki OMA LWM2M TLV
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef OAM_TLV_H_
#define OAM_TLV_H_
#include "contiki.h"
enum {
OMA_TLV_TYPE_OBJECT_INSTANCE = 0,
OMA_TLV_TYPE_RESOURCE_INSTANCE = 1,
OMA_TLV_TYPE_MULTI_RESOURCE = 2,
OMA_TLV_TYPE_RESOURCE = 3
};
typedef uint8_t oma_tlv_type_t;
typedef enum {
OMA_TLV_LEN_TYPE_NO_LEN = 0,
OMA_TLV_LEN_TYPE_8BIT_LEN = 1,
OMA_TLV_LEN_TYPE_16BIT_LEN = 2,
OMA_TLV_LEN_TYPE_24BIT_LEN = 3
} oma_tlv_len_type_t;
typedef struct {
oma_tlv_type_t type;
uint16_t id; /* can be 8-bit or 16-bit when serialized */
uint32_t length;
const uint8_t *value;
} oma_tlv_t;
size_t oma_tlv_get_size(const oma_tlv_t *tlv);
/* read a TLV from the buffer */
size_t oma_tlv_read(oma_tlv_t *tlv, const uint8_t *buffer, size_t len);
/* write a TLV to the buffer */
size_t oma_tlv_write(const oma_tlv_t *tlv, uint8_t *buffer, size_t len);
int32_t oma_tlv_get_int32(const oma_tlv_t *tlv);
/* write a int as a TLV to the buffer */
size_t oma_tlv_write_int32(int16_t id, int32_t value, uint8_t *buffer, size_t len);
/* write a float converted from fixpoint as a TLV to the buffer */
size_t oma_tlv_write_float32(int16_t id, int32_t value, int bits, uint8_t *buffer, size_t len);
/* convert TLV with float32 to fixpoint */
size_t oma_tlv_float32_to_fix(const oma_tlv_t *tlv, int32_t *value, int bits);
#endif /* OAM_TLV_H_ */
/** @} */

View file

@ -0,0 +1,29 @@
CONTIKI_PROJECT = example-ipso-objects
CONTIKI_SOURCEFILES += serial-protocol.c example-ipso-temperature.c
all: $(CONTIKI_PROJECT)
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
APPS += rest-engine
APPS += er-coap
APPS += oma-lwm2m
APPS += ipso-objects
CONTIKI=../..
CONTIKI_WITH_IPV6 = 1
include $(CONTIKI)/Makefile.include
# border router rules
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
(cd $(CONTIKI)/tools && $(MAKE) tunslip6)
connect-router: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64
connect-router-cooja: $(CONTIKI)/tools/tunslip6
sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64
connect-router-native: $(CONTIKI)/examples/ipv6/native-border-router/border-router.native
sudo $(CONTIKI)/exmples/ipv6/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64

View file

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>LWM2M &amp; IPSO Objects Example</title>
<speedlimit>1.0</speedlimit>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.mspmote.WismoteMoteType
<identifier>wismote1</identifier>
<description>Wismote Border Router #border-router</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.c</source>
<commands EXPORT="discard">make border-router.wismote TARGET=wismote DEFINES=NETSTACK_RDC=nullrdc_driver,NETSTACK_MAC=nullmac_driver</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipv6/rpl-border-router/border-router.wismote</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
</motetype>
<motetype>
org.contikios.cooja.mspmote.WismoteMoteType
<identifier>wismote2</identifier>
<description>Wismote IPSO Objects #ipso-example</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.c</source>
<commands EXPORT="discard">make example-ipso-objects.wismote TARGET=wismote</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.wismote</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>56.362361976162035</x>
<y>11.826023799100883</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>wismote1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>60.1539674439426</x>
<y>11.827942168467365</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>wismote2</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>280</width>
<z>2</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.LEDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin</skin>
<viewport>53.336918739504526 0.0 0.0 53.336918739504526 -2924.9161170527295 -473.3614543395965</viewport>
</plugin_config>
<width>400</width>
<z>4</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter>ID:2</filter>
<formatted_time />
<coloring />
</plugin_config>
<width>1286</width>
<z>1</z>
<height>240</height>
<location_x>400</location_x>
<location_y>160</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Notes
<plugin_config>
<notes>OMA LWM2M &amp; IPSO Object example
1. Start a LWM2M server, for example Leshan
2. Run the example and bridge Cooja using tunslip with the prefix aaaa::1/64:
(cd contiki/examples/ipso-objects &amp;&amp; make connect-router-cooja)
After a short time, the example node should register with the LWM2M server at [aaaa::1]:5683.</notes>
<decorations>true</decorations>
</plugin_config>
<width>1006</width>
<z>0</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.serialsocket.SerialSocketServer
<mote_arg>0</mote_arg>
<plugin_config>
<port>60001</port>
<bound>true</bound>
</plugin_config>
<width>362</width>
<z>3</z>
<height>116</height>
<location_x>1</location_x>
<location_y>399</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>OMA LWM2M and IPSO Object example</title>
<speedlimit>2.0</speedlimit>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>500.0</transmitting_range>
<interference_range>500.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.mspmote.WismoteMoteType
<identifier>wismote1</identifier>
<description>Wismote Router #wismote1</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipso-objects/example-server.c</source>
<commands EXPORT="discard">make example-server.wismote TARGET=wismote</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipso-objects/example-server.wismote</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
</motetype>
<motetype>
org.contikios.cooja.mspmote.WismoteMoteType
<identifier>wismote2</identifier>
<description>Wismote Mote Type #wismote2</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.c</source>
<commands EXPORT="discard">make example-ipso-objects.wismote TARGET=wismote</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/ipso-objects/example-ipso-objects.wismote</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDefaultSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>30.243188653185154</x>
<y>29.963547412144486</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspDefaultSerial
<history>s aaaa::200:0:0:3 /3311/0/5850 0~;s aaaa::200:0:0:3 /3311/0/5850 1~;g aaaa::200:0:0:3 /3311/1/5850~;g aaaa::200:0:0:3 /3311/0/5850~;g aaaa::200:0:0:3 /3311/1/5850~;g aaaa::200:0:0:3 /3311/0/5850~;s aaaa::200:0:0:3 /3311/0/5850 1~;s aaaa::200:0:0:2 /3311/0/5850 1~;h~;s aaaa::200:0:0:2 /3311/0/5850 1~;s aaaa::200:0:0:2 /3311/0/5850 0~;g aaaa::200:0:0:2 /3311/0/5850~;g aaaa::200:0:0:2 /3311/1/5850~;g aaaa::200:0:0:2 /3311/2/5850~;l~;</history>
</interface_config>
<motetype_identifier>wismote1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>59.75123136831088</x>
<y>29.84506209179908</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>wismote2</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>60.30742753391745</x>
<y>59.35092511889063</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>3</id>
</interface_config>
<motetype_identifier>wismote2</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>280</width>
<z>0</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.LEDVisualizerSkin</skin>
<viewport>4.593848158957425 0.0 0.0 4.593848158957425 13.734375417550426 -121.37641081710846</viewport>
</plugin_config>
<width>400</width>
<z>3</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>959</width>
<z>2</z>
<height>447</height>
<location_x>400</location_x>
<location_y>160</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>679</width>
<z>1</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.MoteInterfaceViewer
<mote_arg>0</mote_arg>
<plugin_config>
<interface>Serial port</interface>
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>579</width>
<z>4</z>
<height>300</height>
<location_x>49</location_x>
<location_y>414</location_y>
</plugin>
</simconf>

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/**
* \file
* OMA LWM2M and IPSO Objects example.
* \author
* Joakim Eriksson, joakime@sics.se
* Niclas Finne, nfi@sics.se
*/
#include "contiki.h"
#include "lwm2m-engine.h"
#include "ipso-objects.h"
#define DEBUG DEBUG_NONE
#include "net/ip/uip-debug.h"
#ifndef REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER
#define REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER 0
#endif
#ifndef REGISTER_WITH_LWM2M_SERVER
#define REGISTER_WITH_LWM2M_SERVER 1
#endif
#ifndef LWM2M_SERVER_ADDRESS
#define LWM2M_SERVER_ADDRESS "aaaa::1"
#endif
PROCESS(example_ipso_objects, "IPSO object example");
AUTOSTART_PROCESSES(&example_ipso_objects);
/*---------------------------------------------------------------------------*/
static void
setup_lwm2m_servers(void)
{
#ifdef LWM2M_SERVER_ADDRESS
uip_ipaddr_t addr;
if(uiplib_ipaddrconv(LWM2M_SERVER_ADDRESS, &addr)) {
lwm2m_engine_register_with_bootstrap_server(&addr, 0);
lwm2m_engine_register_with_server(&addr, 0);
}
#endif /* LWM2M_SERVER_ADDRESS */
lwm2m_engine_use_bootstrap_server(REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER);
lwm2m_engine_use_registration_server(REGISTER_WITH_LWM2M_SERVER);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(example_ipso_objects, ev, data)
{
PROCESS_BEGIN();
PROCESS_PAUSE();
PRINTF("Starting IPSO objects example\n");
/* Initialize the OMA LWM2M engine */
lwm2m_engine_init();
/* Register default LWM2M objects */
lwm2m_engine_register_default_objects();
/* Register default IPSO objects */
ipso_objects_init();
setup_lwm2m_servers();
while(1) {
PROCESS_WAIT_EVENT();
}
PROCESS_END();
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* An dummy temperature driver as example
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "ipso-objects.h"
#include "lib/random.h"
static int32_t last_value = 27000;
/*---------------------------------------------------------------------------*/
static int
read_value(int32_t *value)
{
last_value = last_value + (random_rand() % 1000) - 500;
if(last_value < 18000) {
last_value = 18000;
} else if(last_value > 35000) {
last_value = 35000;
}
*value = last_value;
return 0;
}
/*---------------------------------------------------------------------------*/
const struct ipso_objects_sensor example_ipso_temperature = {
.read_value = read_value
};
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,392 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/**
* \file
* IPSO Objects and OMA LWM2M example.
* \author
* Joakim Eriksson, joakime@sics.se
* Niclas Finne, nfi@sics.se
*/
#include "contiki.h"
#include "net/ip/uip.h"
#include "net/rpl/rpl.h"
#include "net/netstack.h"
#include "er-coap-constants.h"
#include "er-coap-engine.h"
#include "lwm2m-engine.h"
#include "oma-tlv.h"
#include "dev/serial-line.h"
#include "serial-protocol.h"
#if CONTIKI_TARGET_WISMOTE
#include "dev/uart1.h"
#endif
#define DEBUG DEBUG_PRINT
#include "net/ip/uip-debug.h"
#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT)
#define URL_WELL_KNOWN ".well-known/core"
#define URL_DEVICE_MODEL "/3/0/1"
#define URL_DEVICE_FIRMWARE_VERSION "/3/0/3"
#define URL_LIGHT_CONTROL "/3311/0/5850"
#define URL_POWER_CONTROL "/3312/0/5850"
#define MAX_NODES 10
#define NODE_HAS_TYPE (1 << 0)
struct node {
uip_ipaddr_t ipaddr;
char type[32];
uint8_t flags;
uint8_t retries;
};
static struct node nodes[MAX_NODES];
static uint8_t node_count;
static struct node *current_target;
static char current_uri[32] = URL_LIGHT_CONTROL;
static char current_value[32] = "1";
static int current_request = COAP_PUT;
static uint8_t fetching_type = 0;
PROCESS(router_process, "router process");
AUTOSTART_PROCESSES(&router_process);
/*---------------------------------------------------------------------------*/
static struct node *
add_node(const uip_ipaddr_t *addr)
{
int i;
for(i = 0; i < node_count; i++) {
if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) {
/* Node already added */
return &nodes[i];
}
}
if(node_count < MAX_NODES) {
uip_ipaddr_copy(&nodes[node_count].ipaddr, addr);
return &nodes[node_count++];
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
set_value(const uip_ipaddr_t *addr, char *uri, char *value)
{
int i;
printf("#set value ");
uip_debug_ipaddr_print(addr);
printf(" URI: %s Value: %s\n", uri, value);
for(i = 0; i < node_count; i++) {
if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) {
/* setup command */
current_target = &nodes[i];
current_request = COAP_PUT;
strncpy(current_uri, uri, sizeof(current_uri) - 1);
strncpy(current_value, value, sizeof(current_value) - 1);
process_poll(&router_process);
break;
}
}
}
/*---------------------------------------------------------------------------*/
void
get_value(const uip_ipaddr_t *addr, char *uri)
{
int i;
printf("#get value ");
uip_debug_ipaddr_print(addr);
printf(" URI: %s\n", uri);
for(i = 0; i < node_count; i++) {
if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) {
/* setup command */
current_target = &nodes[i];
current_request = COAP_GET;
strncpy(current_uri, uri, sizeof(current_uri) - 1);
current_value[0] = 0;
process_poll(&router_process);
break;
}
}
}
/*---------------------------------------------------------------------------*/
void
print_node_list(void)
{
int i;
int out = 0;
for(i = 0; i < node_count; i++) {
if(nodes[i].flags & NODE_HAS_TYPE) {
if(out++) {
printf(";");
}
printf("%s,", nodes[i].type);
uip_debug_ipaddr_print(&nodes[i].ipaddr);
}
}
printf("\n");
}
/*---------------------------------------------------------------------------*/
/**
* This function is will be passed to COAP_BLOCKING_REQUEST() to
* handle responses.
*/
static void
client_chunk_handler(void *response)
{
const uint8_t *chunk;
unsigned int format;
int len = coap_get_payload(response, &chunk);
coap_get_header_content_format(response, &format);
/* if(len > 0) { */
/* printf("|%.*s (%d,%d)", len, (char *)chunk, len, format); */
/* } */
if(current_target != NULL && fetching_type) {
if(len > sizeof(current_target->type) - 1) {
len = sizeof(current_target->type) - 1;
}
memcpy(current_target->type, chunk, len);
current_target->type[len] = 0;
current_target->flags |= NODE_HAS_TYPE;
PRINTF("\nNODE ");
PRINT6ADDR(&current_target->ipaddr);
PRINTF(" HAS TYPE %s\n", current_target->type);
} else {
/* otherwise update the current value */
if(format == LWM2M_TLV) {
oma_tlv_t tlv;
/* we can only read int32 for now ? */
if(oma_tlv_read(&tlv, chunk, len) > 0) {
/* printf("TLV.type=%d len=%d id=%d value[0]=%d\n", */
/* tlv.type, tlv.length, tlv.id, tlv.value[0]); */
int value = oma_tlv_get_int32(&tlv);
snprintf(current_value, sizeof(current_value), "%d", value);
}
} else {
if(len > sizeof(current_value) - 1) {
len = sizeof(current_value) - 1;
}
memcpy(current_value, chunk, len);
current_value[len] = 0;
}
}
}
/*---------------------------------------------------------------------------*/
static void
setup_network(void)
{
uip_ipaddr_t ipaddr;
struct uip_ds6_addr *root_if;
rpl_dag_t *dag;
int i;
uint8_t state;
#if CONTIKI_TARGET_WISMOTE
uart1_set_input(serial_line_input_byte);
serial_line_init();
#endif
#if UIP_CONF_ROUTER
/**
* The choice of server address determines its 6LoWPAN header compression.
* Obviously the choice made here must also be selected in udp-client.c.
*
* For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences,
* e.g. set Context 0 to aaaa::. At present Wireshark copies Context/128 and then overwrites it.
* (Setting Context 0 to aaaa::1111:2222:3333:4444 will report a 16 bit compressed address of aaaa::1111:22ff:fe33:xxxx)
* Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses.
*/
#if 0
/* Mode 1 - 64 bits inline */
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
#elif 1
/* Mode 2 - 16 bits inline */
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0x00ff, 0xfe00, 1);
#else
/* Mode 3 - derived from link local (MAC) address */
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
#endif
uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
root_if = uip_ds6_addr_lookup(&ipaddr);
if(root_if != NULL) {
dag = rpl_set_root(RPL_DEFAULT_INSTANCE, &ipaddr);
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
rpl_set_prefix(dag, &ipaddr, 64);
PRINTF("created a new RPL dag\n");
} else {
PRINTF("failed to create a new RPL DAG\n");
}
#endif /* UIP_CONF_ROUTER */
PRINTF("IPv6 addresses: ");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) {
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
/* hack to make address "final" */
if (state == ADDR_TENTATIVE) {
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
}
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(router_process, ev, data)
{
/* This way the packet can be treated as pointer as usual. */
static coap_packet_t request[1];
static struct etimer timer;
uip_ds6_route_t *r;
uip_ipaddr_t *nexthop;
int n;
PROCESS_BEGIN();
PROCESS_PAUSE();
/* receives all CoAP messages */
coap_init_engine();
setup_network();
/* The data sink runs with a 100% duty cycle in order to ensure high
packet reception rates. */
NETSTACK_MAC.off(1);
while(1) {
etimer_set(&timer, CLOCK_SECOND * 5);
PROCESS_YIELD();
/* Handle serial line input */
if(ev == serial_line_event_message) {
serial_protocol_input((char *) data);
}
if(etimer_expired(&timer)) {
current_target = NULL;
n = 0;
for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
current_target = add_node(&r->ipaddr);
if(current_target == NULL ||
(current_target->flags & NODE_HAS_TYPE) != 0 ||
current_target->retries > 5) {
continue;
}
PRINTF(" ");
PRINT6ADDR(&r->ipaddr);
PRINTF(" -> ");
nexthop = uip_ds6_route_nexthop(r);
if(nexthop != NULL) {
PRINT6ADDR(nexthop);
PRINTF("\n");
} else {
PRINTF("-");
}
PRINTF("\n");
n++;
break;
}
}
/* This is a node type discovery */
if(current_target != NULL &&
(current_target->flags & NODE_HAS_TYPE) == 0 &&
current_target->retries < 6) {
/* prepare request, TID is set by COAP_BLOCKING_REQUEST() */
coap_init_message(request, COAP_TYPE_CON, COAP_GET, 0);
coap_set_header_uri_path(request, URL_DEVICE_MODEL);
current_target->retries++;
PRINTF("CoAP request to [");
PRINT6ADDR(&current_target->ipaddr);
PRINTF("]:%u (%u tx)\n", UIP_HTONS(REMOTE_PORT),
current_target->retries);
fetching_type = 1;
COAP_BLOCKING_REQUEST(&current_target->ipaddr, REMOTE_PORT, request,
client_chunk_handler);
fetching_type = 0;
strncpy(current_uri, URL_LIGHT_CONTROL, sizeof(current_uri));
printf("\n--Done--\n");
}
/* If having a type this is another type of request */
if(current_target != NULL &&
(current_target->flags & NODE_HAS_TYPE) && strlen(current_uri) > 0) {
/* prepare request, TID is set by COAP_BLOCKING_REQUEST() */
coap_init_message(request, COAP_TYPE_CON, current_request, 0);
coap_set_header_uri_path(request, current_uri);
if(strlen(current_value) > 0) {
coap_set_payload(request, (uint8_t *)current_value,
strlen(current_value));
}
PRINTF("CoAP request to [");
PRINT6ADDR(&current_target->ipaddr);
PRINTF("]:%u %s\n", UIP_HTONS(REMOTE_PORT), current_uri);
COAP_BLOCKING_REQUEST(&current_target->ipaddr, REMOTE_PORT, request,
client_chunk_handler);
/* print out result of command */
if(current_request == COAP_PUT) {
printf("s ");
} else {
printf("g ");
}
uip_debug_ipaddr_print(&current_target->ipaddr);
printf(" %s %s\n", current_uri, current_value);
current_target = NULL;
current_uri[0] = 0;
current_value[0] = 0;
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
#ifdef BOARD_STRING
#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING
#elif defined(CONTIKI_TARGET_WISMOTE)
#include "dev/watchdog.h"
#define LWM2M_DEVICE_MODEL_NUMBER "wismote"
#define LWM2M_DEVICE_MANUFACTURER "Arago Systems"
#define LWM2M_DEVICE_SERIAL_NO "001"
#define PLATFORM_REBOOT watchdog_reboot
#endif
#define IPSO_TEMPERATURE example_ipso_temperature
/**
* Disabling RDC and CSMA to save memory on constrained devices.
*/
#undef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC nullrdc_driver
#undef NETSTACK_CONF_MAC
#define NETSTACK_CONF_MAC nullmac_driver
/* Disabling TCP on CoAP nodes. */
#undef UIP_CONF_TCP
#define UIP_CONF_TCP 0
/* Increase rpl-border-router IP-buffer when using more than 64. */
#undef REST_MAX_CHUNK_SIZE
#define REST_MAX_CHUNK_SIZE 64
/* Multiplies with chunk size, be aware of memory constraints. */
#undef COAP_MAX_OPEN_TRANSACTIONS
#define COAP_MAX_OPEN_TRANSACTIONS 4
/* Filtering .well-known/core per query can be disabled to save space. */
#undef COAP_LINK_FORMAT_FILTERING
#define COAP_LINK_FORMAT_FILTERING 0
#undef COAP_PROXY_OPTION_PROCESSING
#define COAP_PROXY_OPTION_PROCESSING 0
/* Enable client-side support for COAP observe */
#define COAP_OBSERVE_CLIENT 1
#endif /* PROJECT_CONF_H_ */

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Simple serial protocol to list and interact with devices
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "contiki.h"
#include "net/ip/uip.h"
#include "net/ip/uiplib.h"
#include <stdio.h>
void print_node_list(void);
void set_value(const uip_ipaddr_t *addr, char *uri, char *value);
void get_value(const uip_ipaddr_t *addr, char *uri);
/*---------------------------------------------------------------------------*/
int
find_next_sep(const char *str, char sep, int pos)
{
char c;
while((c = str[pos]) != 0) {
if(c == sep) {
return pos + 1;
}
pos++;
}
return -1;
}
/*---------------------------------------------------------------------------*/
/*
* l - list all discovered devices
* s - set <IP> <URI> <value>
* d - get <IP> <URI>
*/
void
serial_protocol_input(char *data)
{
/* We assume that we have a string here */
char cmd = data[0];
int pos = 0;
switch(cmd) {
case 'l':
/* list devices */
print_node_list();
break;
case 's': {
uip_ip6addr_t ipaddr;
char *uri;
char *value;
pos = find_next_sep(data, ' ', pos);
if(pos > 0) {
/* start of IP */
int start = pos;
pos = find_next_sep(data, ' ', pos);
if(pos == -1) {
return;
}
data[pos - 1] = 0;
if(uiplib_ip6addrconv(&data[start], &ipaddr) == 0) {
printf("* Error not valid IP\n");
}
uri = &data[pos];
pos = find_next_sep(data, ' ', pos);
if(pos == -1) return;
data[pos - 1] = 0;
value = &data[pos];
/* set the value at the specified node */
set_value(&ipaddr, uri, value);
}
break;
}
case 'g': {
uip_ip6addr_t ipaddr;
char *uri;
pos = find_next_sep(data, ' ', pos);
if(pos > 0) {
/* start of IP */
int start = pos;
pos = find_next_sep(data, ' ', pos);
if(pos == -1) return;
data[pos - 1] = 0;
if(uiplib_ip6addrconv((const char *) &data[start], &ipaddr) == 0) {
printf("* Error not valid IP\n");
}
uri = &data[pos];
/* get the value at the specified node */
get_value(&ipaddr, uri);
}
break;
}
default:
printf("Unknown command\n");
}
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2015, Yanzi Networks AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Simple serial protocol to list and interact with devices
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef SERIAL_PROTOCOL_H_
#define SERIAL_PROTOCOL_H_
void serial_protocol_input(char *data);
#endif /* SERIAL_PROTOCOL_H_ */