Merge pull request #11036 from leandrolanzieri/pr/pkg/wakaama_rework
pkg/wakaama: Add basic LWM2M client implementation
This commit is contained in:
commit
353c0e91d0
49
examples/wakaama/Makefile
Normal file
49
examples/wakaama/Makefile
Normal file
@ -0,0 +1,49 @@
|
||||
# name of your application
|
||||
APPLICATION = wakaama
|
||||
|
||||
# If no BOARD is found in the environment, use this default:
|
||||
BOARD ?= native
|
||||
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
|
||||
|
||||
# Include packages that pull up and auto-init the link layer.
|
||||
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
|
||||
USEMODULE += gnrc_netdev_default
|
||||
USEMODULE += auto_init_gnrc_netif
|
||||
# Specify the mandatory networking modules
|
||||
USEMODULE += gnrc_ipv6_router_default
|
||||
USEMODULE += gnrc_sock_udp
|
||||
# Additional networking modules that can be dropped if not needed
|
||||
USEMODULE += gnrc_icmpv6_echo
|
||||
# Add also the shell, some shell commands
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
USEMODULE += ps
|
||||
|
||||
# Comment this out to disable code in RIOT that does safety checking
|
||||
# which is not needed in a production environment but helps in the
|
||||
# development process:
|
||||
DEVELHELP ?= 1
|
||||
|
||||
# Specific the server URI address (NOTE: Domain names not supported yet)
|
||||
SERVER_URI ?= '"coap://[fd00:dead:beef::1]"'
|
||||
|
||||
ifneq (,$(SERVER_URI))
|
||||
CFLAGS += -DLWM2M_SERVER_URI=$(SERVER_URI)
|
||||
endif
|
||||
|
||||
# NOTE: Add the package for wakaama
|
||||
USEPKG += wakaama
|
||||
# Uncomment to enable Wakaama debug log
|
||||
#CFLAGS += -DLWM2M_WITH_LOGS
|
||||
|
||||
# Uncomment to indicate that the server is a LwM2M bootstrap server
|
||||
# CFLAGS += -DLWM2M_BOOTSTRAP=1
|
||||
|
||||
# NOTE: Use wakaama in client mode
|
||||
CFLAGS += -DLWM2M_CLIENT_MODE
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
60
examples/wakaama/Makefile.ci
Normal file
60
examples/wakaama/Makefile.ci
Normal file
@ -0,0 +1,60 @@
|
||||
BOARD_BLACKLIST := \
|
||||
arduino-duemilanove \
|
||||
arduino-leonardo \
|
||||
arduino-mega2560 \
|
||||
arduino-nano \
|
||||
arduino-uno \
|
||||
atmega1284p \
|
||||
atmega256rfr2-xpro \
|
||||
atmega328p \
|
||||
avr-rss2 \
|
||||
chronos \
|
||||
derfmega128 \
|
||||
derfmega256 \
|
||||
mega-xplained \
|
||||
microduino-corerf \
|
||||
msb-430 \
|
||||
msb-430h \
|
||||
pic32-clicker \
|
||||
pic32-wifire \
|
||||
telosb \
|
||||
waspmote-pro \
|
||||
wsn430-v1_3b \
|
||||
wsn430-v1_4 \
|
||||
z1
|
||||
|
||||
BOARD_INSUFFICIENT_MEMORY := \
|
||||
airfy-beacon \
|
||||
b-l072z-lrwan1 \
|
||||
blackpill \
|
||||
bluepill \
|
||||
calliope-mini \
|
||||
cc2650-launchpad \
|
||||
cc2650stk \
|
||||
hifive1 \
|
||||
hifive1b \
|
||||
i-nucleo-lrwan1 \
|
||||
lsn50 \
|
||||
maple-mini \
|
||||
microbit \
|
||||
nrf51dongle \
|
||||
nrf6310 \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f031k6 \
|
||||
nucleo-f302r8 \
|
||||
nucleo-f303k8 \
|
||||
nucleo-f042k6 \
|
||||
nucleo-f070rb \
|
||||
nucleo-f072rb \
|
||||
nucleo-f302r8 \
|
||||
nucleo-f334r8 \
|
||||
nucleo-l031k6 \
|
||||
nucleo-l053r8 \
|
||||
opencm904 \
|
||||
saml10-xpro \
|
||||
saml11-xpro \
|
||||
spark-core \
|
||||
stm32f030f4-demo \
|
||||
stm32f0discovery \
|
||||
stm32l0538-disco \
|
||||
yunjia-nrf51822
|
||||
96
examples/wakaama/README.md
Normal file
96
examples/wakaama/README.md
Normal file
@ -0,0 +1,96 @@
|
||||
# Wakaama LwM2M example client
|
||||
|
||||
This application starts a
|
||||
[LwM2M](https://wiki.openmobilealliance.org/display/TOOL/What+is+LwM2M) client
|
||||
on the node with instances of the following objects:
|
||||
- [Security object](http://www.openmobilealliance.org/tech/profiles/LWM2M_Security-v1_0.xml)
|
||||
- [Server object](http://www.openmobilealliance.org/tech/profiles/LWM2M_Server-v1_0.xml)
|
||||
- [Device object](http://www.openmobilealliance.org/tech/profiles/LWM2M_Device-v1_0_3.xml)
|
||||
|
||||
The application is based on the Eclipse Wakaama
|
||||
[example client](https://github.com/eclipse/wakaama/tree/master/examples/client)
|
||||
.
|
||||
|
||||
## Usage
|
||||
|
||||
### Setting up a LwM2M Test Server
|
||||
To test the client a LwM2M server where to register is needed.
|
||||
[Eclipse Leshan](https://github.com/eclipse/leshan) demo is a good option for
|
||||
running one locally.
|
||||
|
||||
To run the demo server:
|
||||
```shell
|
||||
wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-server-demo.jar
|
||||
|
||||
java -jar ./leshan-server-demo.jar
|
||||
```
|
||||
It will output the addresses where it is listening:
|
||||
```
|
||||
INFO LeshanServer - LWM2M server started at coap://0.0.0.0/0.0.0.0:5683 coaps://0.0.0.0/0.0.0.0:5684
|
||||
INFO LeshanServerDemo - Web server started at http://0.0.0.0:8080/.
|
||||
```
|
||||
|
||||
#### Bootstrap server
|
||||
LwM2M provides a bootstrapping mechanism to provide the clients with information
|
||||
to register to one or more servers. To test this mechanism both the previous server and a bootstrap server should be running. Eclipse Leshan also provides a bootstrap server demo.
|
||||
|
||||
By default the bootstrap server option is disabled, it can be enabled by defining
|
||||
`LWM2M_BOOTSTRAP` as 1 (see the Makefile in this application).
|
||||
|
||||
To run the bootstrap server, make sure that the ports it uses are different
|
||||
from the ones of previous server (default are 5683 for CoAP, 5684 for CoAPs,
|
||||
and 8080 for the webserver), and that it corresponds to the one set in
|
||||
`lwm2m.h` as `LWM2M_BSSERVER_PORT`:
|
||||
```shell
|
||||
# download demo
|
||||
wget https://hudson.eclipse.org/leshan/job/leshan/lastSuccessfulBuild/artifact/leshan-bsserver-demo.jar
|
||||
|
||||
# set CoAP, CoAPs and webserver ports for bootstrap server
|
||||
BS_COAPPORT=5685
|
||||
BS_COAPSPORT=5686
|
||||
BS_WEBPORT=8888
|
||||
|
||||
# run the server
|
||||
java -jar ./leshan-bsserver-demo.jar --coapport ${BS_COAPPORT} \
|
||||
--coapsport ${BS_COAPSPORT} --webport ${BS_WEBPORT}
|
||||
```
|
||||
|
||||
To set up the configuration of the node and the server:
|
||||
1. Click the `Add new client bootstrap configuration` button.
|
||||
2. Fill in the name of the device, it **should** match the one set in
|
||||
`lwm2m.h` as `LWM2M_DEVICE_NAME`.
|
||||
3. Using the `LWM2M Server` tab enter the address where the LwM2M server is
|
||||
listening. For now only `No security` mode can be used.
|
||||
|
||||
### Running the client
|
||||
The address set in `lwm2m.h` as `LWM2M_SERVER_URI` should be reachable
|
||||
from the node, e.g. either running on native with a tap interface or as a mote
|
||||
connected to a
|
||||
[border router](https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_border_router).
|
||||
|
||||
Also, if a bootstrap server is being used the macro `LWM2M_BOOTSTRAP` should be
|
||||
defined as 1.
|
||||
|
||||
The server URI for the example is being defined using the variable `SERVER_URI`
|
||||
in the Makefile, and can be changed when compiling.
|
||||
|
||||
#### Compile and run
|
||||
For debugging purposes there are two types of messages that can be enabled:
|
||||
- The lwm2m client adaptation debug can be enabled by setting `ENABLE_DEBUG` in
|
||||
`lwm2m_client.c` and `lwm2m_client_connection.c` to 1
|
||||
- The wakaama internal logging can be enabled by adding `LWM2M_WITH_LOGS` to the
|
||||
CFLAGS (`CFLAGS += -DLWM2M_WITH_LOGS`)
|
||||
|
||||
For memory allocation the TLSF package is being used, with a private heap. If
|
||||
memory usage has to be tweaked the heap size can be modified via the macro
|
||||
`LWM2M_TLSF_BUFFER`.
|
||||
|
||||
To compile run:
|
||||
|
||||
```shell
|
||||
BOARD=<board> make clean all flash term
|
||||
```
|
||||
|
||||
#### Shell commands
|
||||
- `lwm2m start`: Starts the LwM2M by configuring the module and registering to
|
||||
the server.
|
||||
74
examples/wakaama/lwm2m_cli.c
Normal file
74
examples/wakaama/lwm2m_cli.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Wakaama LwM2M Client CLI support
|
||||
*
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "lwm2m_client.h"
|
||||
#include "lwm2m_client_objects.h"
|
||||
#include "lwm2m_platform.h"
|
||||
|
||||
#define OBJ_COUNT (3)
|
||||
|
||||
uint8_t connected = 0;
|
||||
lwm2m_object_t *obj_list[OBJ_COUNT];
|
||||
lwm2m_client_data_t client_data;
|
||||
|
||||
void lwm2m_cli_init(void)
|
||||
{
|
||||
/* this call is needed before creating any objects */
|
||||
lwm2m_client_init(&client_data);
|
||||
|
||||
/* add objects that will be registered */
|
||||
obj_list[0] = lwm2m_client_get_security_object(&client_data);
|
||||
obj_list[1] = lwm2m_client_get_server_object(&client_data);
|
||||
obj_list[2] = lwm2m_client_get_device_object(&client_data);
|
||||
|
||||
if (!obj_list[0] || !obj_list[1] || !obj_list[2]) {
|
||||
puts("Could not create mandatory objects");
|
||||
}
|
||||
}
|
||||
|
||||
int lwm2m_cli_cmd(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
goto help_error;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "start")) {
|
||||
/* run the LwM2M client */
|
||||
if (!connected && lwm2m_client_run(&client_data, obj_list, OBJ_COUNT)) {
|
||||
connected = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ACTIVE(DEVELHELP) && !strcmp(argv[1],"mem")) {
|
||||
lwm2m_tlsf_status();
|
||||
return 0;
|
||||
}
|
||||
|
||||
help_error:
|
||||
if (IS_ACTIVE(DEVELHELP)) {
|
||||
printf("usage: %s <start|mem>\n", argv[0]);
|
||||
}
|
||||
else {
|
||||
printf("usage: %s <start>\n", argv[0]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
50
examples/wakaama/main.c
Normal file
50
examples/wakaama/main.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Example application for Eclipse Wakaama LwM2M Client
|
||||
*
|
||||
* @author Christian Manal <manal@uni-bremen.de>
|
||||
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "msg.h"
|
||||
#include "shell.h"
|
||||
|
||||
#define SHELL_QUEUE_SIZE (8)
|
||||
static msg_t _shell_queue[SHELL_QUEUE_SIZE];
|
||||
|
||||
extern void lwm2m_cli_init(void);
|
||||
extern int lwm2m_cli_cmd(int argc, char **argv);
|
||||
static const shell_command_t my_commands[] = {
|
||||
{ "lwm2m", "Start LwM2M client", lwm2m_cli_cmd },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* initiates LwM2M client */
|
||||
lwm2m_cli_init();
|
||||
|
||||
msg_init_queue(_shell_queue, SHELL_QUEUE_SIZE);
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
shell_run(my_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -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
|
||||
*/
|
||||
51
pkg/wakaama/patches/0018-Fix-log-in-lwm2m_configure.patch
Normal file
51
pkg/wakaama/patches/0018-Fix-log-in-lwm2m_configure.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From 8c09cf9b771f4f4c856705f239529405dd20c303 Mon Sep 17 00:00:00 2001
|
||||
From: Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
Date: Wed, 20 Nov 2019 15:47:28 +0100
|
||||
Subject: [PATCH 1/1] Fix log in lwm2m_configure.
|
||||
|
||||
This logs the parameters of lwm2m_configure only after checking that
|
||||
they are not NULL pointers.
|
||||
---
|
||||
core/liblwm2m.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/liblwm2m.c b/core/liblwm2m.c
|
||||
index a33f340..1dbcf7a 100644
|
||||
--- a/core/liblwm2m.c
|
||||
+++ b/core/liblwm2m.c
|
||||
@@ -261,7 +261,6 @@ int lwm2m_configure(lwm2m_context_t * contextP,
|
||||
int i;
|
||||
uint8_t found;
|
||||
|
||||
- LOG_ARG("endpointName: \"%s\", msisdn: \"%s\", altPath: \"%s\", numObject: %d", endpointName, msisdn, altPath, numObject);
|
||||
// This API can be called only once for now
|
||||
if (contextP->endpointName != NULL || contextP->objectList != NULL) return COAP_400_BAD_REQUEST;
|
||||
|
||||
@@ -275,9 +274,12 @@ int lwm2m_configure(lwm2m_context_t * contextP,
|
||||
if (objectList[i]->objID == LWM2M_SERVER_OBJECT_ID) found |= 0x02;
|
||||
if (objectList[i]->objID == LWM2M_DEVICE_OBJECT_ID) found |= 0x04;
|
||||
}
|
||||
+ LOG_ARG("numObject: %d", numObject);
|
||||
+
|
||||
if (found != 0x07) return COAP_400_BAD_REQUEST;
|
||||
if (altPath != NULL)
|
||||
{
|
||||
+ LOG_ARG("altPath: \"%s\"", altPath);
|
||||
if (0 == utils_isAltPathValid(altPath))
|
||||
{
|
||||
return COAP_400_BAD_REQUEST;
|
||||
@@ -292,9 +294,11 @@ int lwm2m_configure(lwm2m_context_t * contextP,
|
||||
{
|
||||
return COAP_500_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
+ LOG_ARG("endpointName: \"%s\"", endpointName);
|
||||
|
||||
if (msisdn != NULL)
|
||||
{
|
||||
+ LOG_ARG("msisdn: \"%s\"", msisdn);
|
||||
contextP->msisdn = lwm2m_strdup(msisdn);
|
||||
if (contextP->msisdn == NULL)
|
||||
{
|
||||
--
|
||||
2.20.1
|
||||
|
||||
90
pkg/wakaama/patches/0019-Fix-multiple-log-of-strings.patch
Normal file
90
pkg/wakaama/patches/0019-Fix-multiple-log-of-strings.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From 9f22d187cbd8a692b340aa6961ccfffde67fda9d Mon Sep 17 00:00:00 2001
|
||||
From: Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
Date: Tue, 26 Nov 2019 13:18:36 +0100
|
||||
Subject: [PATCH 1/1] Fix multiple log of strings
|
||||
|
||||
---
|
||||
core/data.c | 4 +++-
|
||||
core/json.c | 4 +++-
|
||||
core/transaction.c | 6 ++++--
|
||||
core/uri.c | 8 +++++---
|
||||
4 files changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/core/data.c b/core/data.c
|
||||
index 824d9bf..e4dc154 100644
|
||||
--- a/core/data.c
|
||||
+++ b/core/data.c
|
||||
@@ -255,7 +255,9 @@ void lwm2m_data_encode_nstring(const char * string,
|
||||
size_t length,
|
||||
lwm2m_data_t * dataP)
|
||||
{
|
||||
- LOG_ARG("length: %d, string: \"%s\"", length, string);
|
||||
+ if (string) {
|
||||
+ LOG_ARG("length: %d, string: \"%s\"", length, string);
|
||||
+ }
|
||||
lwm2m_data_encode_opaque((uint8_t *)string, length, dataP);
|
||||
|
||||
if (dataP->type == LWM2M_TYPE_OPAQUE)
|
||||
diff --git a/core/json.c b/core/json.c
|
||||
index 459fe9d..91562ce 100644
|
||||
--- a/core/json.c
|
||||
+++ b/core/json.c
|
||||
@@ -768,7 +768,9 @@ int json_parse(lwm2m_uri_t * uriP,
|
||||
_record_t * recordArray;
|
||||
lwm2m_data_t * parsedP;
|
||||
|
||||
- LOG_ARG("bufferLen: %d, buffer: \"%s\"", bufferLen, (char *)buffer);
|
||||
+ if (buffer) {
|
||||
+ LOG_ARG("bufferLen: %d, buffer: \"%s\"", bufferLen, (char *)buffer);
|
||||
+ }
|
||||
LOG_URI(uriP);
|
||||
*dataP = NULL;
|
||||
recordArray = NULL;
|
||||
diff --git a/core/transaction.c b/core/transaction.c
|
||||
index de78b83..1749003 100644
|
||||
--- a/core/transaction.c
|
||||
+++ b/core/transaction.c
|
||||
@@ -152,8 +152,10 @@ lwm2m_transaction_t * transaction_new(void * sessionH,
|
||||
lwm2m_transaction_t * transacP;
|
||||
int result;
|
||||
|
||||
- LOG_ARG("method: %d, altPath: \"%s\", mID: %d, token_len: %d",
|
||||
- method, altPath, mID, token_len);
|
||||
+ LOG_ARG("method: %d, mID: %d, token_len: %d", method, mID, token_len);
|
||||
+ if (altPath) {
|
||||
+ LOG_ARG("altPath: \"%s\"", altPath);
|
||||
+ }
|
||||
LOG_URI(uriP);
|
||||
|
||||
// no transactions without peer
|
||||
diff --git a/core/uri.c b/core/uri.c
|
||||
index bfe0a48..4f2ecae 100644
|
||||
--- a/core/uri.c
|
||||
+++ b/core/uri.c
|
||||
@@ -99,7 +99,9 @@ lwm2m_uri_t * uri_decode(char * altPath,
|
||||
lwm2m_uri_t * uriP;
|
||||
int readNum;
|
||||
|
||||
- LOG_ARG("altPath: \"%s\"", altPath);
|
||||
+ if (altPath) {
|
||||
+ LOG_ARG("altPath: \"%s\"", altPath);
|
||||
+ }
|
||||
|
||||
uriP = (lwm2m_uri_t *)lwm2m_malloc(sizeof(lwm2m_uri_t));
|
||||
if (NULL == uriP) return NULL;
|
||||
@@ -212,10 +214,10 @@ int lwm2m_stringToUri(const char * buffer,
|
||||
size_t head;
|
||||
int readNum;
|
||||
|
||||
- LOG_ARG("buffer_len: %u, buffer: \"%.*s\"", buffer_len, buffer_len, buffer);
|
||||
-
|
||||
if (buffer == NULL || buffer_len == 0 || uriP == NULL) return 0;
|
||||
|
||||
+ LOG_ARG("buffer_len: %u, buffer: \"%.*s\"", buffer_len, buffer_len, buffer);
|
||||
+
|
||||
memset(uriP, 0, sizeof(lwm2m_uri_t));
|
||||
|
||||
// Skip any white space
|
||||
--
|
||||
2.20.1
|
||||
|
||||
@ -0,0 +1,95 @@
|
||||
From 9a02f0d63cb14e7e6b195550882dd8363183e22c Mon Sep 17 00:00:00 2001
|
||||
From: Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
Date: Fri, 29 Nov 2019 18:17:54 +0100
|
||||
Subject: [PATCH 1/1] Add logging function for 64-bits values
|
||||
|
||||
---
|
||||
core/data.c | 6 ++++--
|
||||
core/internals.h | 13 +++++++++++++
|
||||
core/liblwm2m.c | 6 ++++--
|
||||
3 files changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/core/data.c b/core/data.c
|
||||
index e4dc154..d304410 100644
|
||||
--- a/core/data.c
|
||||
+++ b/core/data.c
|
||||
@@ -269,7 +269,8 @@ void lwm2m_data_encode_nstring(const char * string,
|
||||
void lwm2m_data_encode_int(int64_t value,
|
||||
lwm2m_data_t * dataP)
|
||||
{
|
||||
- LOG_ARG("value: %" PRId64 "", value);
|
||||
+ LOG("value: ");
|
||||
+ LOG_VALUE("%" PRId64, value);
|
||||
dataP->type = LWM2M_TYPE_INTEGER;
|
||||
dataP->value.asInteger = value;
|
||||
}
|
||||
@@ -334,7 +335,8 @@ int lwm2m_data_decode_int(const lwm2m_data_t * dataP,
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
- LOG_ARG("result: %d, value: %" PRId64, result, *valueP);
|
||||
+ LOG_ARG("result: %d, value: ", result);
|
||||
+ LOG_VALUE("%" PRId64, *valueP);
|
||||
|
||||
return result;
|
||||
}
|
||||
diff --git a/core/internals.h b/core/internals.h
|
||||
index 08e951c..84c841f 100644
|
||||
--- a/core/internals.h
|
||||
+++ b/core/internals.h
|
||||
@@ -71,8 +71,20 @@
|
||||
|
||||
#ifdef LWM2M_WITH_LOGS
|
||||
#include <inttypes.h>
|
||||
+#include "fmt.h"
|
||||
#define LOG(STR) lwm2m_printf("[%s:%d] " STR "\r\n", __func__ , __LINE__)
|
||||
#define LOG_ARG(FMT, ...) lwm2m_printf("[%s:%d] " FMT "\r\n", __func__ , __LINE__ , __VA_ARGS__)
|
||||
+/* Log a single value. Use this for 64-bits numbers */
|
||||
+#define LOG_VALUE(FMT, VALUE) \
|
||||
+{ \
|
||||
+ if (!strcmp(FMT, "%"PRId64)) \
|
||||
+ { \
|
||||
+ char int64_str[20]; \
|
||||
+ int64_str[fmt_s64_dec(int64_str, (VALUE))] = '\0'; \
|
||||
+ lwm2m_printf("[%s:%d] %s \r\n", __func__ , __LINE__ , int64_str); \
|
||||
+ } \
|
||||
+ else lwm2m_printf("[%s:%d] " FMT "\r\n", __func__ , __LINE__ , (VALUE)); \
|
||||
+}
|
||||
#define LOG_URI(URI) \
|
||||
{ \
|
||||
if ((URI) == NULL) lwm2m_printf("[%s:%d] NULL\r\n", __func__ , __LINE__); \
|
||||
@@ -119,6 +131,7 @@
|
||||
#else
|
||||
#define LOG_ARG(FMT, ...)
|
||||
#define LOG(STR)
|
||||
+#define LOG_VALUE(FMT, VALUE)
|
||||
#define LOG_URI(URI)
|
||||
#endif
|
||||
|
||||
diff --git a/core/liblwm2m.c b/core/liblwm2m.c
|
||||
index 1dbcf7a..140a85a 100644
|
||||
--- a/core/liblwm2m.c
|
||||
+++ b/core/liblwm2m.c
|
||||
@@ -373,7 +373,8 @@ int lwm2m_step(lwm2m_context_t * contextP,
|
||||
int result;
|
||||
#endif
|
||||
|
||||
- LOG_ARG("timeoutP: %" PRId64, *timeoutP);
|
||||
+ LOG("timeoutP: ");
|
||||
+ LOG_VALUE("%" PRId64, *timeoutP);
|
||||
tv_sec = lwm2m_gettime();
|
||||
if (tv_sec < 0) return COAP_500_INTERNAL_SERVER_ERROR;
|
||||
|
||||
@@ -481,7 +482,8 @@ next_step:
|
||||
registration_step(contextP, tv_sec, timeoutP);
|
||||
transaction_step(contextP, tv_sec, timeoutP);
|
||||
|
||||
- LOG_ARG("Final timeoutP: %" PRId64, *timeoutP);
|
||||
+ LOG("Final timeoutP:");
|
||||
+ LOG_VALUE("%" PRId64, *timeoutP);
|
||||
#ifdef LWM2M_CLIENT_MODE
|
||||
LOG_ARG("Final state: %s", STR_STATE(contextP->state));
|
||||
#endif
|
||||
--
|
||||
2.20.1
|
||||
|
||||
24
pkg/wakaama/patches/0021-Fix-warnings-in-discover.c.patch
Normal file
24
pkg/wakaama/patches/0021-Fix-warnings-in-discover.c.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From 2cd3bcccd3d60b90847e498d402c81ceb7e41328 Mon Sep 17 00:00:00 2001
|
||||
From: Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||
Date: Fri, 29 Nov 2019 20:18:12 +0100
|
||||
Subject: [PATCH 1/1] Fix warnings in discover.c
|
||||
|
||||
---
|
||||
core/discover.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/core/discover.c b/core/discover.c
|
||||
index a4947c7..c877769 100644
|
||||
--- a/core/discover.c
|
||||
+++ b/core/discover.c
|
||||
@@ -439,4 +439,5 @@ int discover_serialize(lwm2m_context_t * contextP,
|
||||
|
||||
return (int)head;
|
||||
}
|
||||
-#endif
|
||||
\ No newline at end of file
|
||||
+#endif
|
||||
+
|
||||
--
|
||||
2.20.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user