mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
pkg/wakaama: Add LwM2M Client implementation
This commit is contained in:
parent
2826779fbf
commit
c52ad2df9e
@ -88,6 +88,7 @@ PSEUDOMODULES += stdio_ethos
|
||||
PSEUDOMODULES += stdio_cdc_acm
|
||||
PSEUDOMODULES += stdio_uart_rx
|
||||
PSEUDOMODULES += suit_%
|
||||
PSEUDOMODULES += wakaama_objects_%
|
||||
|
||||
# handle suit_v4 being a distinct module
|
||||
NO_PSEUDOMODULES += suit_v4
|
||||
|
@ -6,17 +6,20 @@ PKG_LICENSE=EDL-1.0,EPL-1.0
|
||||
.PHONY: all
|
||||
|
||||
all: patch
|
||||
"$(MAKE)" -C $(PKG_BUILDDIR)/riotbuild
|
||||
"$(MAKE)" -C $(PKG_BUILDDIR)
|
||||
|
||||
patch: git-download
|
||||
mkdir -p "$(PKG_BUILDDIR)/riotbuild"
|
||||
cp $(PKG_BUILDDIR)/core/*.c $(PKG_BUILDDIR)/core/*.h $(PKG_BUILDDIR)/riotbuild
|
||||
cp $(PKG_BUILDDIR)/core/er-coap-13/*.c $(PKG_BUILDDIR)/core/er-coap-13/*.h $(PKG_BUILDDIR)/riotbuild
|
||||
cp $(PKG_BUILDDIR)/examples/client/object_server.c $(PKG_BUILDDIR)/riotbuild
|
||||
cp $(PKG_BUILDDIR)/examples/client/object_security.c $(PKG_BUILDDIR)/riotbuild
|
||||
cp $(PKG_BUILDDIR)/examples/client/object_access_control.c $(PKG_BUILDDIR)/riotbuild
|
||||
mkdir -p "$(PKG_BUILDDIR)"
|
||||
# copy the Wakaama core files
|
||||
cp $(PKG_BUILDDIR)/core/*.c $(PKG_BUILDDIR)/core/*.h $(PKG_BUILDDIR)
|
||||
# copy the coap implementation from Wakaama
|
||||
cp $(PKG_BUILDDIR)/core/er-coap-13/*.c $(PKG_BUILDDIR)/core/er-coap-13/*.h $(PKG_BUILDDIR)
|
||||
# copy the mandatory objects, implemented on Wakaama examples
|
||||
cp $(PKG_BUILDDIR)/examples/client/object_server.c $(PKG_BUILDDIR)
|
||||
cp $(PKG_BUILDDIR)/examples/client/object_security.c $(PKG_BUILDDIR)
|
||||
cp $(PKG_BUILDDIR)/examples/client/object_access_control.c $(PKG_BUILDDIR)
|
||||
|
||||
echo 'MODULE:=wakaama' > $(PKG_BUILDDIR)/riotbuild/Makefile
|
||||
echo 'include $$(RIOTBASE)/Makefile.base' >> $(PKG_BUILDDIR)/riotbuild/Makefile
|
||||
echo 'MODULE:=wakaama' > $(PKG_BUILDDIR)/Makefile
|
||||
echo 'include $$(RIOTBASE)/Makefile.base' >> $(PKG_BUILDDIR)/Makefile
|
||||
|
||||
include $(RIOTBASE)/pkg/pkg.mk
|
||||
|
17
pkg/wakaama/Makefile.dep
Normal file
17
pkg/wakaama/Makefile.dep
Normal file
@ -0,0 +1,17 @@
|
||||
# include contrib code (platform adaption and client implementation)
|
||||
USEMODULE += wakaama_contrib
|
||||
|
||||
# this allows us to include our own objects, implemented in the 'objects'
|
||||
# folder, by adding 'wakaama_objects_<objectName>' modules
|
||||
USEMODULE += wakaama_objects
|
||||
|
||||
# include the 'device' object implementation (mandatory)
|
||||
USEMODULE += wakaama_objects_device
|
||||
|
||||
USEMODULE += xtimer
|
||||
USEPKG += tlsf
|
||||
|
||||
# If logs for the package are active, we need fmt
|
||||
ifneq (,$(filter -DLWM2M_WITH_LOGS,$(CFLAGS)))
|
||||
USEMODULE += fmt
|
||||
endif
|
@ -1 +1,4 @@
|
||||
INCLUDES += -I$(PKGDIRBASE)/wakaama/riotbuild
|
||||
DIRS += $(RIOTBASE)/pkg/wakaama/contrib
|
||||
|
||||
INCLUDES += -I$(RIOTBASE)/pkg/wakaama/include
|
||||
INCLUDES += -I$(PKGDIRBASE)/wakaama
|
||||
|
5
pkg/wakaama/contrib/Makefile
Normal file
5
pkg/wakaama/contrib/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
MODULE := wakaama_contrib
|
||||
|
||||
DIRS += $(RIOTBASE)/pkg/wakaama/contrib/objects
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
200
pkg/wakaama/contrib/lwm2m_client.c
Normal file
200
pkg/wakaama/contrib/lwm2m_client.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Beduino Master Projekt - University of Bremen
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup lwm2m_client
|
||||
*
|
||||
* @file
|
||||
* @brief LwM2M client implementation using Wakaama
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "liblwm2m.h"
|
||||
|
||||
#include "lwm2m_platform.h"
|
||||
#include "lwm2m_client.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
#include "lwm2m_client_connection.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief Determines if there has been a reboot request on the device object
|
||||
*
|
||||
* @note This function is implemented in object_device.c
|
||||
*
|
||||
* @return true Reboot has been requested
|
||||
* @return false Reboot has not been requested
|
||||
*/
|
||||
bool lwm2m_device_reboot_requested(void);
|
||||
|
||||
/**
|
||||
* @brief Thread with the main loop for receiving packets and stepping the LwM2M
|
||||
* FSM.
|
||||
*
|
||||
* @param arg ignored
|
||||
*/
|
||||
static void *_lwm2m_client_run(void *arg);
|
||||
|
||||
|
||||
static char _lwm2m_client_stack[THREAD_STACKSIZE_MAIN +
|
||||
THREAD_EXTRA_STACKSIZE_PRINTF];
|
||||
static lwm2m_client_data_t *_client_data;
|
||||
|
||||
void lwm2m_client_init(lwm2m_client_data_t *client_data)
|
||||
{
|
||||
(void)client_data;
|
||||
lwm2m_platform_init();
|
||||
}
|
||||
|
||||
lwm2m_context_t *lwm2m_client_run(lwm2m_client_data_t *client_data,
|
||||
lwm2m_object_t *obj_list[],
|
||||
uint16_t obj_numof)
|
||||
{
|
||||
int res;
|
||||
|
||||
_client_data = client_data;
|
||||
_client_data->local_ep.family = AF_INET6;
|
||||
_client_data->local_ep.netif = SOCK_ADDR_ANY_NETIF;
|
||||
|
||||
/* create sock for UDP server */
|
||||
_client_data->local_ep.port = atoi(LWM2M_LOCAL_PORT);
|
||||
if (sock_udp_create(&_client_data->sock, &_client_data->local_ep, NULL, 0)) {
|
||||
DEBUG("[lwm2m_client_run] Can't create server socket\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initiate LwM2M */
|
||||
_client_data->lwm2m_ctx = lwm2m_init(_client_data);
|
||||
if (!_client_data->lwm2m_ctx) {
|
||||
DEBUG("[lwm2m_client_run] Failed to initiate LwM2M\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = lwm2m_configure(_client_data->lwm2m_ctx, LWM2M_DEVICE_NAME, NULL,
|
||||
LWM2M_ALT_PATH, obj_numof, obj_list);
|
||||
if (res) {
|
||||
DEBUG("[lwm2m_client_run] Failed to configure LwM2M\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_client_data->pid = thread_create(_lwm2m_client_stack,
|
||||
sizeof(_lwm2m_client_stack),
|
||||
THREAD_PRIORITY_MAIN - 1,
|
||||
THREAD_CREATE_STACKTEST,
|
||||
_lwm2m_client_run,
|
||||
NULL,
|
||||
"LwM2M client");
|
||||
return _client_data->lwm2m_ctx;
|
||||
}
|
||||
|
||||
static void *_lwm2m_client_run(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
time_t reboot_time = 0;
|
||||
while (1) {
|
||||
time_t tv = LWM2M_CLIENT_MIN_REFRESH_TIME;
|
||||
uint8_t rcv_buf[LWM2M_CLIENT_RCV_BUFFER_SIZE];
|
||||
ssize_t rcv_len = sizeof(rcv_buf);
|
||||
sock_udp_ep_t remote;
|
||||
|
||||
if (lwm2m_device_reboot_requested()) {
|
||||
time_t tv_sec;
|
||||
|
||||
tv_sec = lwm2m_gettime();
|
||||
|
||||
if (0 == reboot_time) {
|
||||
DEBUG("reboot requested; rebooting in %u seconds\n",
|
||||
LWM2M_CLIENT_REBOOT_TIME);
|
||||
reboot_time = tv_sec + LWM2M_CLIENT_REBOOT_TIME;
|
||||
}
|
||||
if (reboot_time < tv_sec) {
|
||||
DEBUG("reboot time expired, rebooting ...\n");
|
||||
pm_reboot();
|
||||
}
|
||||
else {
|
||||
tv = reboot_time - tv_sec;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function does two things:
|
||||
* - first it does the work needed by liblwm2m (eg. (re)sending some
|
||||
* packets).
|
||||
* - Secondly it adjusts the timeout value (default 60s) depending on the
|
||||
* state of the transaction
|
||||
* (eg. retransmission) and the time between the next operation
|
||||
*/
|
||||
lwm2m_step(_client_data->lwm2m_ctx, &tv);
|
||||
DEBUG(" -> State: ");
|
||||
switch (_client_data->lwm2m_ctx->state) {
|
||||
case STATE_INITIAL:
|
||||
DEBUG("STATE_INITIAL\n");
|
||||
break;
|
||||
case STATE_BOOTSTRAP_REQUIRED:
|
||||
DEBUG("STATE_BOOTSTRAP_REQUIRED\n");
|
||||
break;
|
||||
case STATE_BOOTSTRAPPING:
|
||||
DEBUG("STATE_BOOTSTRAPPING\n");
|
||||
break;
|
||||
case STATE_REGISTER_REQUIRED:
|
||||
DEBUG("STATE_REGISTER_REQUIRED\n");
|
||||
break;
|
||||
case STATE_REGISTERING:
|
||||
DEBUG("STATE_REGISTERING\n");
|
||||
break;
|
||||
case STATE_READY:
|
||||
DEBUG("STATE_READY\n");
|
||||
if (tv > LWM2M_CLIENT_MIN_REFRESH_TIME) {
|
||||
tv = LWM2M_CLIENT_MIN_REFRESH_TIME;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEBUG("Unknown...\n");
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG("Waiting for UDP packet on port: %d\n", _client_data->sock.local.port);
|
||||
rcv_len = sock_udp_recv(&_client_data->sock, &rcv_buf, sizeof(rcv_buf),
|
||||
tv * US_PER_SEC, &remote);
|
||||
DEBUG("sock_udp_recv()\n");
|
||||
if (rcv_len > 0) {
|
||||
DEBUG("Finding connection\n");
|
||||
lwm2m_client_connection_t *conn = lwm2m_client_connection_find(
|
||||
_client_data->conn_list, &remote);
|
||||
if (conn) {
|
||||
DEBUG("lwm2m_connection_handle_packet(%d)\n", rcv_len);
|
||||
int result = lwm2m_connection_handle_packet(conn, rcv_buf,
|
||||
rcv_len,
|
||||
_client_data);
|
||||
if (0 != result) {
|
||||
DEBUG("error handling message %d\n", result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DEBUG("Could not find incoming connection\n");
|
||||
}
|
||||
}
|
||||
else if ((rcv_len < 0) &&
|
||||
((rcv_len != -EAGAIN) && (rcv_len != -ETIMEDOUT))) {
|
||||
DEBUG("Unexpected sock_udp_recv error code %i\n", rcv_len);
|
||||
}
|
||||
else {
|
||||
DEBUG("UDP error code: %d\n", rcv_len);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
452
pkg/wakaama/contrib/lwm2m_client_connection.c
Normal file
452
pkg/wakaama/contrib/lwm2m_client_connection.c
Normal file
@ -0,0 +1,452 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2015 Intel Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* The Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* David Navarro, Intel Corporation - initial API and implementation
|
||||
* Christian Renz - Please refer to git log
|
||||
* Christian Manal - Ported to RIOT OS
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Beduino Master Projekt - University of Bremen
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup lwm2m_client
|
||||
*
|
||||
* @file
|
||||
* @brief Connection handle for LwM2M client implementation using Wakaama
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "net/netif.h"
|
||||
|
||||
#include "liblwm2m.h"
|
||||
#include "lwm2m_client.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
#include "lwm2m_client_connection.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define URI_LENGTH 256
|
||||
|
||||
/**
|
||||
* @brief Creates a new connection object based on the security instance
|
||||
* represented by @p instance_id.
|
||||
*
|
||||
* @param[in] instance_id ID number of the instance of security object
|
||||
* @param[in, out] client_data LwM2M client data
|
||||
*
|
||||
* @return Pointer to the new connection
|
||||
*/
|
||||
static lwm2m_client_connection_t *_connection_create(int instance_id,
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Gets the URI from an @p instance_id of a @p obj security object
|
||||
*
|
||||
* @param[in] obj security object
|
||||
* @param[in] instance_id ID number of the instance of security object
|
||||
* @param[out] uri_buffer buffer to place the URI
|
||||
* @param[in] buffer_size size of @p uri_buffer
|
||||
*
|
||||
* @return Pointer to the URI in success
|
||||
* @return NULL otherwise
|
||||
*/
|
||||
static char *_get_uri_from_security_obj(lwm2m_object_t *obj, int instance_id,
|
||||
char *uri_buffer, int buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Sends data with a specified connection @p conn
|
||||
*
|
||||
* @param[in] conn connection to use to send data
|
||||
* @param[in] buffer data to send
|
||||
* @param[in] buffer_size size of @p buffer
|
||||
* @param[in] client_data LwM2M client data
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 otherwise
|
||||
*/
|
||||
static int _connection_send(lwm2m_client_connection_t *conn, uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Parses the schema of a given URI and sets the default port for the
|
||||
* found valid schema
|
||||
* @param[in] uri URI string to parse
|
||||
* @param[out] port will point to the default port string
|
||||
* @param[in] instance_id instance ID of the connection
|
||||
*
|
||||
* @return pointer to the character after the schema, if found
|
||||
* @return NULL if no valid schema found
|
||||
*/
|
||||
static char *_parse_schema(char *uri, char **port, int instance_id);
|
||||
|
||||
/**
|
||||
* @brief Parses the host and the port part after the schema
|
||||
*
|
||||
* @param[in, out] host pointer to the beginning of the host
|
||||
* @param[out] port pointer to store the position of the port
|
||||
* @param[in] default_port default port
|
||||
*/
|
||||
static void _parse_host_and_port(char **host, char **port, char *default_port);
|
||||
|
||||
/**
|
||||
* @brief Tries to find an interface in the host string. If not, it will check
|
||||
* if there only exists one interface, and will use it
|
||||
* @param[in] host host string
|
||||
*
|
||||
* @return pointer to the interface to use on success
|
||||
* @return NULL on error
|
||||
*/
|
||||
static netif_t *_get_interface(char *host);
|
||||
|
||||
/**
|
||||
* @brief Sets a given interface to a given UDP endpoint
|
||||
*
|
||||
* @param[out] ep UDP endpoint
|
||||
* @param[in] netif Network interface to assign
|
||||
*/
|
||||
static void _set_interface(sock_udp_ep_t *ep, const netif_t *netif);
|
||||
|
||||
void *lwm2m_connect_server(uint16_t sec_obj_inst_id, void *user_data)
|
||||
{
|
||||
lwm2m_client_data_t *client_data = (lwm2m_client_data_t *)user_data;
|
||||
lwm2m_list_t *instance;
|
||||
lwm2m_client_connection_t *new_conn = NULL;
|
||||
|
||||
/* get the security object instance */
|
||||
instance = LWM2M_LIST_FIND(client_data->obj_security->instanceList,
|
||||
sec_obj_inst_id);
|
||||
if (instance == NULL) {
|
||||
DEBUG("[lwm2m_connect_server] Could not find sec object instance\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_conn = _connection_create(instance->id, client_data);
|
||||
if (new_conn) {
|
||||
DEBUG("[lwm2m_connect_server] Connection created\n");
|
||||
/* if the connections list is empty this is the first node, if not
|
||||
* attach to the last one */
|
||||
if (!client_data->conn_list) {
|
||||
client_data->conn_list = new_conn;
|
||||
}
|
||||
else {
|
||||
lwm2m_client_connection_t *last = client_data->conn_list;
|
||||
while (last->next != NULL) {
|
||||
last = last->next;
|
||||
}
|
||||
last->next = new_conn;
|
||||
}
|
||||
}
|
||||
|
||||
return new_conn;
|
||||
}
|
||||
|
||||
void lwm2m_close_connection(void *sessionH, void *user_data)
|
||||
{
|
||||
lwm2m_client_connection_t *conn = (lwm2m_client_connection_t *) sessionH;
|
||||
lwm2m_client_data_t *client_data = (lwm2m_client_data_t *) user_data;
|
||||
|
||||
if (conn == client_data->conn_list) {
|
||||
client_data->conn_list = conn->next;
|
||||
}
|
||||
else {
|
||||
lwm2m_client_connection_t *prev = client_data->conn_list;
|
||||
|
||||
while(prev != NULL && prev->next != conn) {
|
||||
prev = prev->next;
|
||||
}
|
||||
if (prev != NULL) {
|
||||
prev->next = conn->next;
|
||||
lwm2m_free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool lwm2m_session_is_equal(void *session1, void *session2, void *user_data)
|
||||
{
|
||||
(void)user_data;
|
||||
lwm2m_client_connection_t *conn_1 = (lwm2m_client_connection_t *)session1;
|
||||
lwm2m_client_connection_t *conn_2 = (lwm2m_client_connection_t *)session2;
|
||||
|
||||
return ((conn_1->remote.port == conn_2->remote.port) &&
|
||||
ipv6_addr_equal((ipv6_addr_t *)&(conn_1->remote.addr.ipv6),
|
||||
(ipv6_addr_t *)&(conn_2->remote.addr.ipv6)));
|
||||
}
|
||||
|
||||
uint8_t lwm2m_buffer_send(void *sessionH, uint8_t *buffer, size_t length,
|
||||
void *userdata)
|
||||
{
|
||||
lwm2m_client_data_t *client_data = (lwm2m_client_data_t *)userdata;
|
||||
lwm2m_client_connection_t *conn = (lwm2m_client_connection_t *)sessionH;
|
||||
|
||||
if (!conn) {
|
||||
DEBUG("[lwm2m_buffer_send] Failed to send, missing connection\n");
|
||||
return COAP_500_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if (_connection_send(conn, buffer, length, client_data)) {
|
||||
DEBUG("[lwm2m_buffer_send] Failed to send\n");
|
||||
return COAP_500_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return COAP_NO_ERROR;
|
||||
}
|
||||
|
||||
lwm2m_client_connection_t *lwm2m_client_connection_find(
|
||||
lwm2m_client_connection_t *conn_list,
|
||||
const sock_udp_ep_t *remote)
|
||||
{
|
||||
lwm2m_client_connection_t *conn = conn_list;
|
||||
|
||||
char ip[128];
|
||||
uint8_t ip_len = 128;
|
||||
|
||||
ipv6_addr_to_str(ip, (ipv6_addr_t *)&remote->addr.ipv6, ip_len);
|
||||
DEBUG("Looking for connection from [%s]:%d\n", ip, remote->port);
|
||||
|
||||
if (conn_list == NULL) {
|
||||
DEBUG("Conn list is null!");
|
||||
}
|
||||
|
||||
while(conn != NULL) {
|
||||
ipv6_addr_to_str(ip, (ipv6_addr_t *)&conn->remote.addr.ipv6, ip_len);
|
||||
DEBUG("Comparing to [%s]:%d\n", ip, conn->remote.port);
|
||||
if ((conn->remote.port == remote->port) &&
|
||||
ipv6_addr_equal((ipv6_addr_t *)&(conn->remote.addr.ipv6),
|
||||
(ipv6_addr_t *)&(remote->addr.ipv6))) {
|
||||
break;
|
||||
}
|
||||
conn = conn->next;
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
int lwm2m_connection_handle_packet(lwm2m_client_connection_t *conn,
|
||||
uint8_t *buffer, size_t num_bytes,
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
lwm2m_handle_packet(client_data->lwm2m_ctx, buffer, num_bytes, conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _connection_send(lwm2m_client_connection_t *conn, uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
ssize_t sent_bytes = sock_udp_send(&(client_data->sock), buffer,
|
||||
buffer_size, &(conn->remote));
|
||||
if (sent_bytes <= 0) {
|
||||
DEBUG("[_connection_send] Could not send UDP packet: %d\n", sent_bytes);
|
||||
return -1;
|
||||
}
|
||||
conn->last_send = lwm2m_gettime();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_parse_schema(char *uri, char **port, int instance_id)
|
||||
{
|
||||
char *host = NULL;
|
||||
if (!uri) {
|
||||
DEBUG("[_parse_schema] Could not get URI of instance\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* parse the URI in the form "coaps://[host]:port" */
|
||||
if (!strncmp(uri, SCHEME_COAPS, sizeof(SCHEME_COAPS) - 1)) {
|
||||
host = uri + sizeof(SCHEME_COAPS) - 1;
|
||||
}
|
||||
else if (!strncmp(uri, SCHEME_COAP, sizeof(SCHEME_COAP) - 1)) {
|
||||
host = uri + sizeof(SCHEME_COAP) - 1;
|
||||
}
|
||||
|
||||
*port = (IS_ACTIVE(LWM2M_BOOTSTRAP) && !instance_id) ?
|
||||
LWM2M_BSSERVER_PORT : LWM2M_STANDARD_PORT;
|
||||
out:
|
||||
return host;
|
||||
}
|
||||
|
||||
static void _parse_host_and_port(char **host, char **port, char *default_port)
|
||||
{
|
||||
char *_port = NULL;
|
||||
char *pos = *host;
|
||||
|
||||
if (pos[0] == '[') {
|
||||
(*host)++;
|
||||
pos = strrchr(pos, ']');
|
||||
}
|
||||
|
||||
_port = strrchr(pos, ':');
|
||||
if (!_port) {
|
||||
*pos = '\0';
|
||||
DEBUG("[_parse_port] No port specified, using default\n");
|
||||
_port = default_port;
|
||||
}
|
||||
else {
|
||||
*(_port - 1) = '\0';
|
||||
_port++;
|
||||
}
|
||||
*port = _port;
|
||||
}
|
||||
|
||||
static void _set_interface(sock_udp_ep_t *ep, const netif_t *netif)
|
||||
{
|
||||
if (netif == NULL || ep == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* currently there is no way to assign a network interface to a sock
|
||||
* endpoint by means of a generic API, so we need to check */
|
||||
if (IS_USED(MODULE_GNRC_NETIF)) {
|
||||
const gnrc_netif_t *gnrc_netif = (gnrc_netif_t *)netif;
|
||||
ep->netif = (uint16_t)gnrc_netif->pid;
|
||||
}
|
||||
}
|
||||
|
||||
static netif_t *_get_interface(char *host)
|
||||
{
|
||||
netif_t *netif = NULL;
|
||||
char *iface = ipv6_addr_split_iface(host);
|
||||
|
||||
if (iface == NULL) {
|
||||
/* get the number of net interfaces */
|
||||
unsigned netif_numof = 0;
|
||||
while ((netif = netif_iter(netif)) != NULL) {
|
||||
netif_numof++;
|
||||
}
|
||||
/* if we only have one interface use that one */
|
||||
if (netif_numof == 1) {
|
||||
netif = netif_iter(NULL);
|
||||
}
|
||||
else {
|
||||
DEBUG("[_connection_create] No iface for link-local address\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
netif = netif_get_by_name(iface);
|
||||
}
|
||||
|
||||
return netif;
|
||||
}
|
||||
|
||||
static lwm2m_client_connection_t *_connection_create(int instance_id,
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
lwm2m_client_connection_t *conn = NULL;
|
||||
char *default_port;
|
||||
char *host;
|
||||
char *port;
|
||||
char *uri;
|
||||
char uri_buf[URI_LENGTH + 1];
|
||||
|
||||
memset(uri_buf, 0, sizeof(uri_buf));
|
||||
DEBUG("Creating connection\n");
|
||||
/* get the server URI from the requested instance */
|
||||
uri = _get_uri_from_security_obj(client_data->obj_security, instance_id,
|
||||
uri_buf, sizeof(uri_buf) - 1);
|
||||
|
||||
host = _parse_schema(uri, &default_port, instance_id);
|
||||
if (!host) {
|
||||
DEBUG("[_connection_create] Could not parse URI schema\n");
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
_parse_host_and_port(&host, &port, default_port);
|
||||
DEBUG("[_connection_create] Creating connection to Host: %s, Port: %s\n",
|
||||
host, port);
|
||||
|
||||
/* allocate new connection */
|
||||
conn = lwm2m_malloc(sizeof(lwm2m_client_connection_t));
|
||||
if (!conn) {
|
||||
DEBUG("[_connection_create] Could not allocate new connection\n");
|
||||
goto out;
|
||||
}
|
||||
conn->next = client_data->conn_list;
|
||||
|
||||
/* configure to any IPv6 */
|
||||
conn->remote.family = AF_INET6;
|
||||
conn->remote.netif = SOCK_ADDR_ANY_NETIF;
|
||||
conn->remote.port = atoi(port);
|
||||
|
||||
if (!ipv6_addr_from_str((ipv6_addr_t *)&conn->remote.addr.ipv6, host)) {
|
||||
DEBUG("[_connection_create] IPv6 address malformed\n");
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
if (ipv6_addr_is_unspecified((const ipv6_addr_t *)&conn->remote.addr.ipv6)) {
|
||||
DEBUG("[_connection_create] Invalid server address ([::])\n");
|
||||
goto free_out;
|
||||
}
|
||||
|
||||
/* If the address is a link-local one first check if interface is specified,
|
||||
* if not, check the number of interfaces and default to the first if there
|
||||
* is only one defined. */
|
||||
if (ipv6_addr_is_link_local((ipv6_addr_t *)&conn->remote.addr.ipv6)) {
|
||||
netif_t *netif = _get_interface(host);
|
||||
if (netif == NULL) {
|
||||
goto free_out;
|
||||
}
|
||||
else {
|
||||
_set_interface(&conn->remote, netif);
|
||||
}
|
||||
}
|
||||
|
||||
conn->last_send = lwm2m_gettime();
|
||||
goto out;
|
||||
|
||||
free_out:
|
||||
lwm2m_free(conn);
|
||||
conn = NULL;
|
||||
out:
|
||||
return conn;
|
||||
}
|
||||
|
||||
static char *_get_uri_from_security_obj(lwm2m_object_t *obj, int instance_id,
|
||||
char *uri_buffer, int buffer_size)
|
||||
{
|
||||
int size = 1;
|
||||
char *res = NULL;
|
||||
|
||||
/* allocate a data instance */
|
||||
lwm2m_data_t *data = lwm2m_data_new(size);
|
||||
|
||||
/* get the uri from the security object */
|
||||
data->id = 0;
|
||||
obj->readFunc(instance_id, &size, &data, obj);
|
||||
|
||||
if (data != NULL && data->type == LWM2M_TYPE_STRING &&
|
||||
data->value.asBuffer.length > 0) {
|
||||
if ((size_t)buffer_size > data->value.asBuffer.length) {
|
||||
strncpy(uri_buffer, (char *)data->value.asBuffer.buffer,
|
||||
data->value.asBuffer.length);
|
||||
res = uri_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
lwm2m_data_free(size, data);
|
||||
return res;
|
||||
}
|
71
pkg/wakaama/contrib/lwm2m_client_objects.c
Normal file
71
pkg/wakaama/contrib/lwm2m_client_objects.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup lwm2m_client
|
||||
*
|
||||
* @file
|
||||
* @brief Helper functions to interact with the basic objects provided by
|
||||
* Wakaama from a LwM2M client.
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#include "lwm2m_client.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
#include "lwm2m_client_objects.h"
|
||||
|
||||
/* These functions are defined by the objects (object_security.c and
|
||||
* object_server.c are implemented by the Wakaama package. device.c can be
|
||||
* found in 'contrib/objects') */
|
||||
lwm2m_object_t *get_security_object(int server_id, const char *server_uri,
|
||||
char *bs_psk_id, char *psk,
|
||||
uint16_t psk_len, bool is_bootstrap);
|
||||
lwm2m_object_t *get_server_object(int server_id, const char *binding,
|
||||
int lifetime, bool storing);
|
||||
lwm2m_object_t *lwm2m_get_object_device(void);
|
||||
|
||||
lwm2m_object_t *lwm2m_client_get_security_object(
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
lwm2m_object_t *ret;
|
||||
char *server_uri = LWM2M_SERVER_URI;
|
||||
int server_id = LWM2M_SERVER_ID;
|
||||
uint16_t psk_len = -1;
|
||||
char *psk_buffer = NULL;
|
||||
char *psk_id = NULL;
|
||||
|
||||
ret = get_security_object(server_id, server_uri, psk_id, psk_buffer,
|
||||
psk_len, IS_ACTIVE(LWM2M_BOOTSTRAP));
|
||||
|
||||
client_data->obj_security = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
lwm2m_object_t *lwm2m_client_get_server_object(
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
(void)client_data;
|
||||
lwm2m_object_t *ret;
|
||||
int server_id = LWM2M_SERVER_ID;
|
||||
int lifetime = LWM2M_DEVICE_TTL;
|
||||
|
||||
ret = get_server_object(server_id, LWM2M_DEVICE_BINDINGS, lifetime, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
lwm2m_object_t *lwm2m_client_get_device_object(
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
(void)client_data;
|
||||
return lwm2m_get_object_device();
|
||||
}
|
122
pkg/wakaama/contrib/lwm2m_platform.c
Normal file
122
pkg/wakaama/contrib/lwm2m_platform.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2013, 2014, 2015 Intel Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* The Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* David Navarro, Intel Corporation - initial API and implementation
|
||||
* Christian Manal - Ported to RIOT OS
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* Copyright (C) 2018 Beduino Master Projekt - University of Bremen
|
||||
* 2019 HAW Hamburg
|
||||
* @{
|
||||
* @ingroup pkg_wakaama
|
||||
*
|
||||
* @file
|
||||
* @brief Platform adaption for Wakaama package
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <liblwm2m.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xtimer.h"
|
||||
#include "tlsf.h"
|
||||
|
||||
#include "lwm2m_platform.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
|
||||
static uint32_t _tlsf_heap[(LWM2M_TLSF_BUFFER / sizeof(uint32_t))];
|
||||
static tlsf_t _tlsf;
|
||||
|
||||
typedef struct {
|
||||
unsigned free; /**< total free size */
|
||||
unsigned used; /**< total used size */
|
||||
} _tlsf_size_container_t;
|
||||
|
||||
static void _tlsf_size_walker(void* ptr, size_t size, int used, void* user)
|
||||
{
|
||||
printf("\t%p %s size: %u (%p)\n", ptr, used ? "used" : "free", (unsigned int)size, ptr);
|
||||
|
||||
if (used) {
|
||||
((_tlsf_size_container_t *)user)->used += (unsigned int)size;
|
||||
}
|
||||
else {
|
||||
((_tlsf_size_container_t *)user)->free += (unsigned int)size;
|
||||
}
|
||||
}
|
||||
|
||||
void lwm2m_tlsf_status(void)
|
||||
{
|
||||
puts("\nTLSF usage:");
|
||||
_tlsf_size_container_t sizes = { .free = 0, .used = 0 };
|
||||
tlsf_walk_pool(tlsf_get_pool(_tlsf), _tlsf_size_walker, &sizes);
|
||||
printf("\tTotal free size: %u\n", sizes.free);
|
||||
printf("\tTotal used size: %u\n", sizes.used);
|
||||
}
|
||||
|
||||
void lwm2m_platform_init(void)
|
||||
{
|
||||
_tlsf = tlsf_create_with_pool(_tlsf_heap, sizeof(_tlsf_heap));
|
||||
}
|
||||
|
||||
void *lwm2m_malloc(size_t s)
|
||||
{
|
||||
return tlsf_malloc(_tlsf, s);
|
||||
}
|
||||
|
||||
void lwm2m_free(void *p)
|
||||
{
|
||||
tlsf_free(_tlsf, p);
|
||||
}
|
||||
|
||||
char *lwm2m_strdup(const char *str)
|
||||
{
|
||||
size_t len = strlen(str) + 1;
|
||||
void *new = lwm2m_malloc(len);
|
||||
|
||||
if (new == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strncpy(new, str, len);
|
||||
}
|
||||
|
||||
int lwm2m_strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
return strncmp(s1, s2, n);
|
||||
}
|
||||
|
||||
time_t lwm2m_gettime(void)
|
||||
{
|
||||
return (time_t)(xtimer_now_usec64() / US_PER_SEC);
|
||||
}
|
||||
|
||||
/* For clang we need to specify that the first argument will be a format string
|
||||
* for print
|
||||
*/
|
||||
__attribute__((__format__ (__printf__, 1, 0)))
|
||||
void lwm2m_printf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
vfprintf(stderr, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
5
pkg/wakaama/contrib/objects/Makefile
Normal file
5
pkg/wakaama/contrib/objects/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
MODULE := wakaama_objects
|
||||
|
||||
SUBMODULES = 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
312
pkg/wakaama/contrib/objects/device.c
Normal file
312
pkg/wakaama/contrib/objects/device.c
Normal file
@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Beduino Master Projekt - University of Bremen
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @{
|
||||
* @ingroup lwm2m_objects_device
|
||||
*
|
||||
* @file
|
||||
* @brief Device object implementation for LwM2M client using Wakaama
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "liblwm2m.h"
|
||||
#include "objects/device.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
|
||||
/* Set to true if reboot requested. */
|
||||
static bool reboot;
|
||||
|
||||
/* Lookup table for static resources of device object */
|
||||
static const char *_static_resources[] = {
|
||||
[LWM2M_RES_MANUFACTURER] = LWM2M_DEVICE_MANUFACTURER,
|
||||
[LWM2M_RES_MODEL_NO] = LWM2M_DEVICE_MODEL,
|
||||
[LWM2M_RES_SERIAL] = LWM2M_DEVICE_SERIAL,
|
||||
[LWM2M_RES_FW_VER] = LWM2M_DEVICE_FW_VERSION,
|
||||
[LWM2M_RES_BINDINGS] = LWM2M_DEVICE_BINDINGS,
|
||||
[LWM2M_RES_TYPE] = LWM2M_DEVICE_TYPE,
|
||||
[LWM2M_RES_HW_VERSION] = LWM2M_DEVICE_HW_VERSION,
|
||||
[LWM2M_RES_SW_VERSION] = LWM2M_DEVICE_SW_VERSION,
|
||||
[LWM2M_DEVICE_RESOURCES] = NULL
|
||||
};
|
||||
|
||||
/*Descriptor of a LwM2M device object instance */
|
||||
typedef struct {
|
||||
uint8_t *power_sources; /**< types of power sources (0-7) */
|
||||
uint16_t *power_voltage; /**< voltage of power sources in mV */
|
||||
uint16_t *power_current; /**< current of power sources in mA */
|
||||
uint8_t battery_status; /**< battery status (0-6) */
|
||||
uint32_t mem_total; /**< amount of memory on the device in kB */
|
||||
uint16_t(*ext_dev_info)[2]; /**< external devices information */
|
||||
uint8_t ext_dev_info_len; /**< amount of external devices information */
|
||||
uint8_t error_code[7]; /**< error codes */
|
||||
uint8_t error_code_used; /**< amount of error codes used */
|
||||
} dev_data_t;
|
||||
|
||||
static uint8_t prv_device_discover(uint16_t instance_id, int *num_dataP,
|
||||
lwm2m_data_t **data_arrayP,
|
||||
lwm2m_object_t *objectP)
|
||||
{
|
||||
uint8_t result;
|
||||
int i;
|
||||
|
||||
(void)objectP;
|
||||
|
||||
if (instance_id != 0) {
|
||||
return COAP_404_NOT_FOUND;
|
||||
}
|
||||
|
||||
result = COAP_205_CONTENT;
|
||||
|
||||
if (*num_dataP == 0) {
|
||||
/* This list must contain all available resources */
|
||||
uint16_t res[] = {
|
||||
LWM2M_RES_MANUFACTURER, LWM2M_RES_MODEL_NO, LWM2M_RES_SERIAL,
|
||||
LWM2M_RES_FW_VER, LWM2M_RES_REBOOT, LWM2M_RES_ERROR_CODE,
|
||||
/* LWM2M_RES_ERROR_CODE_RESET, TODO */
|
||||
LWM2M_RES_BINDINGS, LWM2M_RES_TYPE, LWM2M_RES_HW_VERSION,
|
||||
LWM2M_RES_SW_VERSION,
|
||||
};
|
||||
int len = sizeof(res) / sizeof(uint16_t);
|
||||
|
||||
*data_arrayP = lwm2m_data_new(len);
|
||||
if (*data_arrayP == NULL) {
|
||||
return COAP_500_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
*num_dataP = len;
|
||||
for (i = 0; i < len; i++) {
|
||||
(*data_arrayP)[i].id = res[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Check if each given resource is present */
|
||||
for (i = 0; i < *num_dataP && result == COAP_205_CONTENT; i++) {
|
||||
switch ((*data_arrayP)[i].id) {
|
||||
case LWM2M_RES_MANUFACTURER:
|
||||
case LWM2M_RES_MODEL_NO:
|
||||
case LWM2M_RES_SERIAL:
|
||||
case LWM2M_RES_FW_VER:
|
||||
case LWM2M_RES_REBOOT:
|
||||
case LWM2M_RES_ERROR_CODE:
|
||||
/* case LWM2M_RES_ERROR_CODE_RESET: TODO */
|
||||
case LWM2M_RES_BINDINGS:
|
||||
case LWM2M_RES_TYPE:
|
||||
case LWM2M_RES_HW_VERSION:
|
||||
case LWM2M_RES_SW_VERSION:
|
||||
break;
|
||||
default:
|
||||
result = COAP_404_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint8_t prv_device_read(uint16_t instance_id, int *num_dataP,
|
||||
lwm2m_data_t **data_arrayP,
|
||||
lwm2m_object_t *objectP)
|
||||
{
|
||||
int i;
|
||||
uint8_t result = COAP_404_NOT_FOUND;
|
||||
dev_data_t *data = (dev_data_t *)objectP->userData;
|
||||
|
||||
(void)data;
|
||||
|
||||
/* Single instance object */
|
||||
if (instance_id != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Full object requested */
|
||||
if (*num_dataP == 0) {
|
||||
/* This list must contain all readable resources */
|
||||
uint16_t resList[] = {
|
||||
LWM2M_RES_MANUFACTURER, LWM2M_RES_MODEL_NO, LWM2M_RES_SERIAL,
|
||||
LWM2M_RES_FW_VER, LWM2M_RES_HW_VERSION, LWM2M_RES_SW_VERSION,
|
||||
LWM2M_RES_BINDINGS, LWM2M_RES_TYPE, LWM2M_RES_ERROR_CODE,
|
||||
};
|
||||
int cnt = sizeof(resList) / sizeof(uint16_t);
|
||||
*data_arrayP = lwm2m_data_new(cnt);
|
||||
if (*data_arrayP == NULL) {
|
||||
result = COAP_500_INTERNAL_SERVER_ERROR;
|
||||
goto out;
|
||||
}
|
||||
*num_dataP = cnt;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
(*data_arrayP)[i].id = resList[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < *num_dataP; i++) {
|
||||
switch ((*data_arrayP)[i].id) {
|
||||
/* Exec resources */
|
||||
case LWM2M_RES_REBOOT:
|
||||
case LWM2M_RES_FRESET:
|
||||
case LWM2M_RES_ERROR_CODE_RESET:
|
||||
result = COAP_405_METHOD_NOT_ALLOWED;
|
||||
goto out;
|
||||
break;
|
||||
case LWM2M_RES_ERROR_CODE:
|
||||
/* TODO: Here some error reporting should be implemented. */
|
||||
lwm2m_data_encode_int(LWM2M_DEVICE_ERR_NO_ERR, *data_arrayP + i);
|
||||
result = COAP_205_CONTENT;
|
||||
break;
|
||||
/* The rest are either static or not defined resources */
|
||||
default:
|
||||
if (_static_resources[(*data_arrayP)[i].id]) {
|
||||
lwm2m_data_encode_string(
|
||||
_static_resources[(*data_arrayP)[i].id],
|
||||
*data_arrayP + i);
|
||||
result = COAP_205_CONTENT;
|
||||
}
|
||||
else {
|
||||
result = COAP_404_NOT_FOUND;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint8_t prv_device_write(uint16_t instance_id, int num_data,
|
||||
lwm2m_data_t *data_array,
|
||||
lwm2m_object_t *objectP)
|
||||
{
|
||||
dev_data_t *data = (dev_data_t *)objectP->userData;
|
||||
|
||||
(void)data;
|
||||
(void)instance_id;
|
||||
(void)num_data;
|
||||
(void)data_array;
|
||||
|
||||
if (data_array[0].id < LWM2M_DEVICE_RESOURCES) {
|
||||
/* for now not writing resources */
|
||||
return COAP_405_METHOD_NOT_ALLOWED;
|
||||
}
|
||||
else {
|
||||
return COAP_404_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t prv_device_execute(uint16_t instance_id, uint16_t resource_id,
|
||||
uint8_t *buffer, int length,
|
||||
lwm2m_object_t *objectP)
|
||||
{
|
||||
uint8_t result;
|
||||
dev_data_t *data = (dev_data_t *)objectP->userData;
|
||||
|
||||
(void)data;
|
||||
|
||||
(void)buffer;
|
||||
(void)length;
|
||||
(void)objectP;
|
||||
|
||||
/* single instance object */
|
||||
if (instance_id != 0) {
|
||||
result = COAP_404_NOT_FOUND;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (length != 0) {
|
||||
result = COAP_400_BAD_REQUEST;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
switch (resource_id) {
|
||||
case LWM2M_RES_REBOOT:
|
||||
reboot = true;
|
||||
result = COAP_204_CHANGED;
|
||||
break;
|
||||
case LWM2M_RES_ERROR_CODE_RESET:
|
||||
/* TODO */
|
||||
case LWM2M_RES_FRESET:
|
||||
/* TODO Callback? */
|
||||
default:
|
||||
result = COAP_405_METHOD_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
err_out:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this from the main loop to check whether a reboot was requested.
|
||||
*/
|
||||
bool lwm2m_device_reboot_requested(void)
|
||||
{
|
||||
return reboot;
|
||||
}
|
||||
|
||||
lwm2m_object_t *lwm2m_get_object_device(void)
|
||||
{
|
||||
lwm2m_object_t *obj;
|
||||
|
||||
obj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
|
||||
|
||||
if (obj == NULL) {
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
memset(obj, 0, sizeof(lwm2m_object_t));
|
||||
obj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
|
||||
|
||||
if (obj->instanceList == NULL) {
|
||||
goto free_obj;
|
||||
}
|
||||
|
||||
memset(obj->instanceList, 0, sizeof(lwm2m_list_t));
|
||||
|
||||
obj->objID = LWM2M_DEVICE_OBJECT_ID;
|
||||
|
||||
obj->readFunc = prv_device_read;
|
||||
obj->writeFunc = prv_device_write;
|
||||
obj->executeFunc = prv_device_execute;
|
||||
obj->discoverFunc = prv_device_discover;
|
||||
|
||||
/* Don't allocate memory for stuff that isn't used at the moment */
|
||||
/* obj->userData = lwm2m_malloc(sizeof(dev_data_t)); */
|
||||
/* if (obj->userData == NULL) { */
|
||||
/* goto free_ilist; */
|
||||
/* } */
|
||||
/* */
|
||||
/* memset(obj->userData, 0, sizeof(dev_data_t)); */
|
||||
/* INT USER DATA HERE */
|
||||
|
||||
return obj;
|
||||
|
||||
/* free_ilist: */
|
||||
/* lwm2m_free(obj->instanceList); */
|
||||
|
||||
free_obj:
|
||||
lwm2m_free(obj);
|
||||
|
||||
err_out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lwm2m_free_object_device(lwm2m_object_t *obj)
|
||||
{
|
||||
if (obj == NULL) {
|
||||
return;
|
||||
}
|
||||
if (obj->userData) {
|
||||
lwm2m_free(obj->userData);
|
||||
}
|
||||
if (obj->instanceList) {
|
||||
lwm2m_free(obj->instanceList);
|
||||
}
|
||||
lwm2m_free(obj);
|
||||
}
|
124
pkg/wakaama/include/lwm2m_client.h
Normal file
124
pkg/wakaama/include/lwm2m_client.h
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_wakaama
|
||||
* @defgroup lwm2m_client LwM2M Client using Wakaama
|
||||
* @brief Wakaama adaption to RIOT for implementing a LwM2M client
|
||||
* @{
|
||||
* @file
|
||||
* @brief Definitions and public API for a LwM2M client using Wakaama
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef LWM2M_CLIENT_H
|
||||
#define LWM2M_CLIENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "periph/pm.h"
|
||||
#include "net/sock/udp.h"
|
||||
|
||||
#include "lwm2m_client_config.h"
|
||||
#include "liblwm2m.h"
|
||||
|
||||
/**
|
||||
* @brief Connection to server descriptor
|
||||
*/
|
||||
typedef struct lwm2m_client_connection {
|
||||
struct lwm2m_client_connection *next; /**< pointer to the next connection */
|
||||
sock_udp_ep_t remote; /**< remote endpoint */
|
||||
time_t last_send; /**< last sent packet to the server */
|
||||
} lwm2m_client_connection_t;
|
||||
|
||||
/**
|
||||
* @brief LwM2M client descriptor
|
||||
*/
|
||||
typedef struct {
|
||||
kernel_pid_t pid; /**< PID of the client thread */
|
||||
sock_udp_t sock; /**< UDP server sock */
|
||||
sock_udp_ep_t local_ep; /**< Local endpoint */
|
||||
lwm2m_context_t *lwm2m_ctx; /**< LwM2M context */
|
||||
lwm2m_object_t *obj_security; /**< LwM2M security object */
|
||||
lwm2m_client_connection_t *conn_list; /**< LwM2M connections list */
|
||||
} lwm2m_client_data_t;
|
||||
|
||||
/**
|
||||
* @brief Size of the buffer for the UDP packet reception
|
||||
*/
|
||||
#define LWM2M_CLIENT_RCV_BUFFER_SIZE (200)
|
||||
|
||||
/**
|
||||
* @brief Time in seconds to wait until reboot after a server
|
||||
* request
|
||||
*/
|
||||
#define LWM2M_CLIENT_REBOOT_TIME (5)
|
||||
|
||||
/**
|
||||
* @brief Time in seconds to wait until LwM2M is refreshed.
|
||||
*
|
||||
* @note This time is used as the timeout for receiving UDP packets and will be
|
||||
* the maximum time to wait between calls to wakaama core.
|
||||
*/
|
||||
#define LWM2M_CLIENT_MIN_REFRESH_TIME (1)
|
||||
|
||||
/**
|
||||
* @brief Starts a LwM2M client
|
||||
*
|
||||
* @param[in, out] client_data Pointer to a LwM2M client data descriptor
|
||||
* @param[in] obj_list List of LwM2M objects to be registered
|
||||
* @param[in] obj_numof Number of objects in @p obj_list
|
||||
*
|
||||
* @return Context of the LwM2M client
|
||||
*/
|
||||
lwm2m_context_t *lwm2m_client_run(lwm2m_client_data_t *client_data,
|
||||
lwm2m_object_t *obj_list[],
|
||||
uint16_t obj_numof);
|
||||
|
||||
/**
|
||||
* @brief Initializes a LwM2M client
|
||||
*
|
||||
* @note This functions initializes the memory allocation and is needed before
|
||||
* calling any object creation (i.e. any call to lwm2m_malloc).
|
||||
*
|
||||
* @param[in] client_data Pointer to a LwM2M client data descriptor
|
||||
*/
|
||||
void lwm2m_client_init(lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Returns the LwM2M context of a LwM2M client
|
||||
*
|
||||
* @param[in] client_data pointer to the LwM2M client descriptor
|
||||
*
|
||||
* @return Pointer to the LwM2M context
|
||||
*/
|
||||
static inline lwm2m_context_t *lwm2m_client_get_ctx(
|
||||
lwm2m_client_data_t *client_data)
|
||||
{
|
||||
return client_data->lwm2m_ctx;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWM2M_CLIENT_H */
|
||||
/** @} */
|
190
pkg/wakaama/include/lwm2m_client_config.h
Normal file
190
pkg/wakaama/include/lwm2m_client_config.h
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Beduino Master Projekt - University of Bremen
|
||||
* 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_wakaama
|
||||
* @ingroup config
|
||||
* @defgroup lwm2m_client_config Wakaama LwM2M Client configuration
|
||||
*
|
||||
* @brief Configuration options for the LwM2M client implementation
|
||||
* based on the Wakaama package.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief LwM2M client configurations
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LWM2M_CLIENT_CONFIG_H
|
||||
#define LWM2M_CLIENT_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief CoAP default port of the LwM2M server
|
||||
*/
|
||||
#ifndef LWM2M_STANDARD_PORT
|
||||
#define LWM2M_STANDARD_PORT "5683"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief CoAPS default port of the LwM2M server
|
||||
*/
|
||||
#ifndef LWM2M_DTLS_PORT
|
||||
#define LWM2M_DTLS_PORT "5684"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief CoAP default port of the LwM2M bootstrap server
|
||||
*/
|
||||
#ifndef LWM2M_BSSERVER_PORT
|
||||
#define LWM2M_BSSERVER_PORT "5685"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Default port for the local LwM2M instance
|
||||
*/
|
||||
#ifndef LWM2M_LOCAL_PORT
|
||||
#define LWM2M_LOCAL_PORT "5683"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device name used to register at the LwM2M server
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_NAME
|
||||
#define LWM2M_DEVICE_NAME "testRIOTDevice"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Lifetime of the device object on the LwM2M server
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_TTL
|
||||
#define LWM2M_DEVICE_TTL 300
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LwM2M server URI to register/bootstrap with
|
||||
*
|
||||
* @note The host part of the URI MUST be a valid IPv6 address. Host names can
|
||||
* not be resolved at this time.
|
||||
*/
|
||||
#ifndef LWM2M_SERVER_URI
|
||||
#define LWM2M_SERVER_URI "coap://[fd00:dead:beef::1]"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Numeric ID of LWM2M_SERVER_URI
|
||||
*/
|
||||
#ifndef LWM2M_SERVER_ID
|
||||
#define LWM2M_SERVER_ID 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Alternate path to place LwM2M resources
|
||||
*/
|
||||
#ifndef LWM2M_ALT_PATH
|
||||
#define LWM2M_ALT_PATH NULL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Define to 1 to specify that @ref LWM2M_SERVER_URI is a bootstrap server
|
||||
*
|
||||
* To define just add it to your `CFLAGS` in your application's Makefile:
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.mk}
|
||||
* CFLAGS += -DLWM2M_BOOTSTRAP=1
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
#ifdef DOXYGEN
|
||||
#define LWM2M_BOOTSTRAP
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object manufacturer string
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_MANUFACTURER
|
||||
#define LWM2M_DEVICE_MANUFACTURER "A RIOT maker"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object model.
|
||||
*
|
||||
* @note Defaults to the board name
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_MODEL
|
||||
#define LWM2M_DEVICE_MODEL RIOT_BOARD
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object serial number
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_SERIAL
|
||||
#define LWM2M_DEVICE_SERIAL "undefined"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object firmware version
|
||||
*
|
||||
* @note Defaults to the running RIOT version
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_FW_VERSION
|
||||
#define LWM2M_DEVICE_FW_VERSION RIOT_VERSION
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object binding and queue mode
|
||||
*
|
||||
* Valid values are:
|
||||
* - U: UDP
|
||||
* - UQ: UDP with Queue mode
|
||||
* - S: SMS
|
||||
* - SQ: SMS with Queue mode
|
||||
* - US: UDP and SMS
|
||||
* - UQS: UDP with Queue mode and SMS
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_BINDINGS
|
||||
#define LWM2M_DEVICE_BINDINGS "U"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object device type
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_TYPE
|
||||
#define LWM2M_DEVICE_TYPE "RIOT device"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object hardware version
|
||||
*
|
||||
* @note Defaults to the board name
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_HW_VERSION
|
||||
#define LWM2M_DEVICE_HW_VERSION RIOT_BOARD
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device object software version
|
||||
*
|
||||
* @note Defaults to the running RIOT version
|
||||
*/
|
||||
#ifndef LWM2M_DEVICE_SW_VERSION
|
||||
#define LWM2M_DEVICE_SW_VERSION RIOT_VERSION
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
#endif /* LWM2M_CLIENT_CONFIG_H */
|
89
pkg/wakaama/include/lwm2m_client_connection.h
Normal file
89
pkg/wakaama/include/lwm2m_client_connection.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2015 Intel Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
*
|
||||
* The Eclipse Public License is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
* The Eclipse Distribution License is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* Contributors:
|
||||
* Simon Bernard - initial API and implementation
|
||||
* Christian Renz - Please refer to git log
|
||||
* Christian Manal - Ported to RIOT OS
|
||||
*
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Copyright (C) 2018 Beduino Master Projekt - University of Bremen
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup lwm2m_client
|
||||
* @brief Public API and definitions of the connection handle for
|
||||
* LwM2M client implementation using Wakaama
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef LWM2M_CLIENT_CONNECTION_H
|
||||
#define LWM2M_CLIENT_CONNECTION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "net/sock/udp.h"
|
||||
|
||||
#include "lwm2m_client.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
|
||||
#define SCHEME_COAPS "coaps://"
|
||||
#define SCHEME_COAP "coap://"
|
||||
|
||||
/**
|
||||
* @brief Tries to find an existing connection based on a remote UDP endpoint
|
||||
*
|
||||
* @param[in] conn_list connections list to search
|
||||
* @param[in] remote remote UDP endpoint to compare to
|
||||
*
|
||||
* @return pointer to the connection in success
|
||||
* @return NULL otherwise
|
||||
*/
|
||||
lwm2m_client_connection_t *lwm2m_client_connection_find(
|
||||
lwm2m_client_connection_t *conn_list,
|
||||
const sock_udp_ep_t *remote);
|
||||
|
||||
/**
|
||||
* @brief Handles a received packet from a connection
|
||||
*
|
||||
* @param[in] conn connection from where the packet came from
|
||||
* @param[in] buffer received packet
|
||||
* @param[in] num_bytes size of the packet
|
||||
* @param[in] client_data LwM2M client data
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return non-zero otherwise
|
||||
*/
|
||||
int lwm2m_connection_handle_packet(lwm2m_client_connection_t *conn,
|
||||
uint8_t *buffer, size_t num_bytes,
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWM2M_CLIENT_CONNECTION_H */
|
||||
/** @} */
|
95
pkg/wakaama/include/lwm2m_client_objects.h
Normal file
95
pkg/wakaama/include/lwm2m_client_objects.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup lwm2m_client
|
||||
* @{
|
||||
* @brief Public API and definitions for the helper functions to
|
||||
* interact with basic objects from a LwM2M client.
|
||||
*
|
||||
* @file
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef LWM2M_CLIENT_OBJECTS_H
|
||||
#define LWM2M_CLIENT_OBJECTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lwm2m_client.h"
|
||||
|
||||
/**
|
||||
* @name Access Control Bits
|
||||
* @brief Bit definitions for the ACL property of the LwM2M Access Control
|
||||
* Object.
|
||||
*
|
||||
* @see http://www.openmobilealliance.org/tech/profiles/LWM2M_Access_Control-v1_0_3.xml
|
||||
* @{
|
||||
*/
|
||||
#define LWM2M_ACC_CTRL_READ (1 << 0) /**< Read access */
|
||||
#define LWM2M_ACC_CTRL_WRITE (1 << 1) /**< Write access */
|
||||
#define LWM2M_ACC_CTRL_EXECUTE (1 << 2) /**< Execution access */
|
||||
#define LWM2M_ACC_CTRL_DELETE (1 << 3) /**< Deletion access */
|
||||
#define LWM2M_ACC_CTRL_CREATE (1 << 4) /**< Creation access */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Creates a LwM2M security object with the default configuration from
|
||||
* net/lwm2m.h
|
||||
*
|
||||
* @param[in, out] client_data Pointer to a LwM2M client data descriptor
|
||||
*
|
||||
* @return Pointer to the created object in success
|
||||
* @return NULL otherwise
|
||||
*/
|
||||
lwm2m_object_t *lwm2m_client_get_security_object(
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Creates a LwM2M server object with the default configuration from
|
||||
* net/lwm2m.h
|
||||
*
|
||||
* @param[in, out] client_data Pointer to a LwM2M client data descriptor
|
||||
*
|
||||
* @return Pointer to the created object
|
||||
* @return NULL otherwise
|
||||
*/
|
||||
lwm2m_object_t *lwm2m_client_get_server_object(
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Creates a LwM2M device object with the default configuration from
|
||||
* net/lwm2m.h
|
||||
* @param[in, out] client_data Pointer to a LwM2M client data descriptor
|
||||
*
|
||||
* @return Pointer to the created object
|
||||
* @return NULL otherwise
|
||||
*/
|
||||
lwm2m_object_t *lwm2m_client_get_device_object(
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
/**
|
||||
* @brief Creates a LwM2M access control object with the default configuration
|
||||
*
|
||||
* @param[in] client_data Pointer to a LwM2M client data descriptor
|
||||
*
|
||||
* @return Pointer to the created object
|
||||
* @return NULL otherwise
|
||||
*/
|
||||
lwm2m_object_t *lwm2m_client_get_acc_ctrl_object(
|
||||
lwm2m_client_data_t *client_data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWM2M_CLIENT_OBJECTS_H */
|
||||
/** @} */
|
54
pkg/wakaama/include/lwm2m_platform.h
Normal file
54
pkg/wakaama/include/lwm2m_platform.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_wakaama
|
||||
* @defgroup lwm2m_platform Platform adaption for Wakaama package
|
||||
* @brief Adaption of Wakaama LwM2M package to RIOT
|
||||
* @{
|
||||
* @file
|
||||
* @brief Definitions and public API for Wakaama adaption layer
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
#ifndef LWM2M_PLATFORM_H
|
||||
#define LWM2M_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup lwm2m_platform_conf Wakaama LwM2M platform adaption
|
||||
* @ingroup config
|
||||
* @brief Compile-time configuration options for the Wakaama LwM2M platform
|
||||
* adaption layer.
|
||||
* @{
|
||||
*/
|
||||
/** @brief Size of allocation buffer in bytes */
|
||||
#ifndef LWM2M_TLSF_BUFFER
|
||||
#define LWM2M_TLSF_BUFFER 5120
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Initializes the platform adaption for Wakaama LwM2M
|
||||
*/
|
||||
void lwm2m_platform_init(void);
|
||||
|
||||
/**
|
||||
* @brief Prints the status of TLSF allocation buffer, for development use.
|
||||
*/
|
||||
void lwm2m_tlsf_status(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWM2M_PLATFORM_H */
|
||||
/** @} */
|
105
pkg/wakaama/include/objects/device.h
Normal file
105
pkg/wakaama/include/objects/device.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2019 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup lwm2m_objects
|
||||
* @defgroup lwm2m_objects_device Device LwM2M object
|
||||
* @brief Device object implementation for LwM2M client using Wakaama
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#ifndef OBJECTS_DEVICE_H
|
||||
#define OBJECTS_DEVICE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "liblwm2m.h"
|
||||
#include "lwm2m_client_config.h"
|
||||
|
||||
/**
|
||||
* @brief Resources of the LwM2M device object instance
|
||||
*
|
||||
* @see http://www.openmobilealliance.org/tech/profiles/LWM2M_Device-v1_0_3.xml
|
||||
*/
|
||||
enum lwm2m_device_resources {
|
||||
LWM2M_RES_MANUFACTURER = 0, /**< Human readable manufacturer name */
|
||||
LWM2M_RES_MODEL_NO, /**< Model identifier (manufacturer specified string) */
|
||||
LWM2M_RES_SERIAL, /**< Serial number */
|
||||
LWM2M_RES_FW_VER, /**< Current firmware version of the device */
|
||||
LWM2M_RES_REBOOT, /**< Reboot the device */
|
||||
LWM2M_RES_FRESET, /**< Perform a factory reset of the device */
|
||||
LWM2M_RES_POWER_SRC, /**< Available power sources */
|
||||
LWM2M_RES_POWER_VOL, /**< Present voltage for each power source */
|
||||
LWM2M_RES_POWER_AMP, /**< Present current for each power source */
|
||||
LWM2M_RES_BATTERY_LEVEL, /**< Current battery level as a percentage */
|
||||
LWM2M_RES_MEM_FREE, /**< Estimated current available storage (kB) */
|
||||
LWM2M_RES_ERROR_CODE, /**< Last error code */
|
||||
LWM2M_RES_ERROR_CODE_RESET, /**< Delete all error code instances */
|
||||
LWM2M_RES_TIME, /**< Current UNIX time of the client */
|
||||
LWM2M_RES_TIME_OFFSET, /**< Indicated the UTC offset for the device */
|
||||
LWM2M_RES_TIME_ZONE, /**< Indicates the time zone of the device */
|
||||
LWM2M_RES_BINDINGS, /**< Indicates supported bindings and modes on the client */
|
||||
LWM2M_RES_TYPE, /**< Type of device */
|
||||
LWM2M_RES_HW_VERSION, /**< Current hardware version of the device */
|
||||
LWM2M_RES_SW_VERSION, /**< Current software version on the device */
|
||||
LWM2M_RES_BATTERY_STATUS, /**< Battery status when internal battery is present */
|
||||
LWM2M_RES_MEM_TOTAL, /**< Total amount of storage space in the device (kB*/
|
||||
LWM2M_RES_EXT_DEV_INFO, /**< External device object instance */
|
||||
LWM2M_DEVICE_RESOURCES /**< Number of resources */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Error codes for the
|
||||
* @ref lwm2m_device_resources::LWM2M_RES_ERROR_CODE "Error" resource in the
|
||||
* device object of LwM2M
|
||||
*/
|
||||
enum lwm2m_device_error_codes {
|
||||
LWM2M_DEVICE_ERR_NO_ERR = 0, /**< No error */
|
||||
LWM2M_DEVICE_ERR_LOW_BATT = 1, /**< Low battery power */
|
||||
LWM2M_DEVICE_ERR_EXT_OFF = 2, /**< External power supply off */
|
||||
LWM2M_DEVICE_ERR_GPS_ERR = 3, /**< GPS module failure */
|
||||
LWM2M_DEVICE_ERR_LOW_SIGNAL = 4, /**< Low received signal strength */
|
||||
LWM2M_DEVICE_ERR_NO_MEM = 5, /**< Out of memory */
|
||||
LWM2M_DEVICE_ERR_SMS_ERR = 6, /**< SMS failure */
|
||||
LWM2M_DEVICE_ERR_IP_ERR = 7, /**< IP connectivity failure */
|
||||
LWM2M_DEVICE_ERR_PERIPH_ERR = 8 /**< Peripheral malfunction */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Frees the memory of @p obj device object
|
||||
*
|
||||
* @param[in] obj pointer to the device object
|
||||
*/
|
||||
void lwm2m_free_object_device(lwm2m_object_t *obj);
|
||||
|
||||
/**
|
||||
* @brief Determines if a reboot request has been issued to the device by a
|
||||
* server.
|
||||
*
|
||||
* @return true reboot has been requested
|
||||
* @return false reboot has not been requested
|
||||
*/
|
||||
bool lwm2m_device_reboot_requested(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OBJECTS_DEVICE_H */
|
||||
/** @} */
|
8
pkg/wakaama/include/objects/doc.txt
Normal file
8
pkg/wakaama/include/objects/doc.txt
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @defgroup lwm2m_objects LwM2M Object implementations
|
||||
* @ingroup pkg_wakaama
|
||||
* @brief Implementations of LwM2M objects using Wakaama. For a complete
|
||||
list of the objects supported by the LwM2M protocol check the
|
||||
object registry:
|
||||
* @see http://www.openmobilealliance.org/wp/OMNA/LwM2M/LwM2MRegistry.html
|
||||
*/
|
Loading…
Reference in New Issue
Block a user