osd-contiki/apps/oma-lwm2m/lwm2m-object.h
2015-12-02 15:40:05 +01:00

359 lines
14 KiB
C

/*
* 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_ */
/**
* @}
* @}
*/