Moved the LWM2M standalone example to external repository

This commit is contained in:
Niclas Finne 2017-12-08 17:44:18 +01:00
parent 11b005c7a4
commit 5dfaa5267b
21 changed files with 0 additions and 3165 deletions

View File

@ -1,3 +0,0 @@
*.o
/lwm2m-src
/lwm2m-example

View File

@ -1,141 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A Java IPv4 transport for CoAP + LWM2M
* Converts hex input to DTLS/UDP packets and incoming packets to
* hex out.
*
* Note: This needs the eclipse scandium DTLS implementation to work.
* The example use PSK and the keys according to the code. This needs
* to be configured in Leshan for it to accept the device.
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
import javax.xml.bind.DatatypeConverter;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.io.IOException;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintStream;
import org.eclipse.californium.scandium.dtls.pskstore.StaticPskStore;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.californium.scandium.DTLSConnector;
import org.eclipse.californium.elements.RawData;
import org.eclipse.californium.elements.RawDataChannel;
public class Hex2DTLS {
DTLSConnector dtlsConnector;
InetAddress address;
int port;
Hex2DTLS(String host, int port) {
try {
DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(new InetSocketAddress(0));
builder.setPskStore(new StaticPskStore("Client_Identity", "secretPSK".getBytes()));
builder.setClientOnly();
dtlsConnector = new DTLSConnector(builder.build(), null);
dtlsConnector.setRawDataReceiver(new RawDataChannel() {
public void receiveData(final RawData raw) {
receive(raw.getBytes());
}
});
dtlsConnector.start();
this.address = InetAddress.getByName(host);
this.port = port;
} catch(Exception e) {
e.printStackTrace();
}
}
public void send(byte[] data) throws IOException {
RawData rawData = new RawData(data, address, port);
dtlsConnector.send(rawData);
}
/* Override this to make something more sensible with the data */
public void receive(byte[] data) {
String s = DatatypeConverter.printHexBinary(data);
System.out.println("COAPHEX:" + s);
}
/* Loop on std in to get lines of hex to send */
public static void main(String[] args) throws IOException {
InputStream in = System.in;
final PrintStream out;
System.err.println("Connecting to " + args[0]);
if(args.length > 1) {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(args[1]);
System.err.println("Started " + args[1]);
in = pr.getInputStream();
out = new PrintStream(pr.getOutputStream());
} else {
out = System.out;
}
/* Create a Hex2DTLS that print on this out stream . CoAPs Port*/
Hex2DTLS udpc = new Hex2DTLS(args[0], 5684) {
public void receive(byte[] data) {
String s = DatatypeConverter.printHexBinary(data);
out.println("COAPHEX:" + s);
out.flush();
System.err.println("IN: " + s);
}
};
BufferedReader buffer =
new BufferedReader(new InputStreamReader(in));
/* The read loop */
while(true) {
String line = buffer.readLine();
if(line == null) {
/* Connection closed */
System.err.println("*** stdin closed");
System.exit(0);
} else if (line.startsWith("COAPHEX:")) {
byte[] data = DatatypeConverter.parseHexBinary(line.substring(8));
udpc.send(data);
}
System.err.println("OUT:" + line);
}
}
}

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A Java IPv4 transport for CoAP + LWM2M
* Converts hex input to UDP packets and incoming packets to hex out.
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
import javax.xml.bind.DatatypeConverter;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.io.IOException;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.PrintStream;
public class Hex2UDP implements Runnable {
DatagramSocket serverSocket;
InetAddress address;
int port;
Hex2UDP(String host, int port) {
try {
serverSocket = new DatagramSocket();
this.address = InetAddress.getByName(host);
this.port = port;
new Thread(this).start();
} catch(Exception e) {
/* Do good stuff here... */
e.printStackTrace();
}
}
public void run() {
byte[] receiveData = new byte[1024];
/* The receive loop */
while(true) {
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
try {
/* Receive a packet */
serverSocket.receive(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
byte[] data2 = Arrays.copyOf(receivePacket.getData(),
receivePacket.getLength());
receive(data2);
}
}
public void send(byte[] data) throws IOException {
DatagramPacket sendPacket =
new DatagramPacket(data, data.length, address, port);
serverSocket.send(sendPacket);
}
/* Override this to make something more sensible with the data */
public void receive(byte[] data) {
String s = DatatypeConverter.printHexBinary(data);
System.out.println("COAPHEX:" + s);
}
/* Loop on std in to get lines of hex to send */
public static void main(String[] args) throws IOException {
InputStream in = System.in;
final PrintStream out;
System.err.println("Connecting to " + args[0]);
if(args.length > 2) {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(args[2]);
System.err.println("Started " + args[2]);
in = pr.getInputStream();
out = new PrintStream(pr.getOutputStream());
} else {
out = System.out;
}
/* Create a Hex2UDP that print on this out stream */
Hex2UDP udpc = new Hex2UDP(args[0], Integer.parseInt(args[1])) {
public void receive(byte[] data) {
String s = DatatypeConverter.printHexBinary(data);
out.println("COAPHEX:" + s);
out.flush();
System.err.println("IN: " + s);
}
};
BufferedReader buffer =
new BufferedReader(new InputStreamReader(in));
/* The read loop */
while(true) {
String line = buffer.readLine();
if(line == null) {
/* Connection closed */
System.err.println("*** stdin closed");
System.exit(0);
} else if (line.startsWith("COAPHEX:")) {
byte[] data = DatatypeConverter.parseHexBinary(line.substring(8));
udpc.send(data);
}
System.err.println("OUT:" + line);
}
}
}

View File

@ -1,61 +0,0 @@
PROJECT = lwm2m-example
all: $(PROJECT)
TARGETCDIR = lwm2m-src
COREDIRS = sys lib
SOURCEDIRS = .
SOURCE_FILES = posix-main.c posix-coap-timer.c ipso-sensor-temp.c \
ipso-control-test.c generic-object-test.c
APPSDIRS = coap lwm2m ipso-objects
ifneq ($(MAKE_WITH_DTLS),)
CFLAGS += -DWITH_DTLS=1
TINYDTLS_DIRS = aes ecc sha2
APPSDIRS += tinydtls ${addprefix tinydtls/,$(TINYDTLS_DIRS)}
SOURCE_FILES += dtls-support.c
SOURCEDIRS += tinydtls-support
endif
TARGETCDIRS += ${addprefix $(TARGETCDIR)/,$(COREDIRS) $(APPSDIRS)}
SOURCEDIRS += ${addprefix $(TARGETCDIR)/,. $(APPSDIRS)}
CFLAGS += -Wall -Werror
CFLAGS += ${addprefix -I,$(SOURCEDIRS)}
TRANSPORT ?= ipv4
ifeq ($(TRANSPORT),ipv4)
TRANSPORTDIR = coap-ipv4
CFLAGS += -DWITH_COAP_IPV4=1 -DCOAP_TRANSPORT_CONF_H=\"coap-ipv4.h\"
else ifeq ($(TRANSPORT),hex)
TRANSPORTDIR = coap-hex
CFLAGS += -DWITH_COAP_HEX=1 -DCOAP_TRANSPORT_CONF_H=\"coap-hex.h\"
else
${error Unknown CoAP transport: $(TRANSPORT)}
endif
SOURCEDIRS += $(TRANSPORTDIR)
SOURCE_FILES += ${notdir ${wildcard $(TRANSPORTDIR)/*.c}}
vpath %.c $(SOURCEDIRS)
-include Makefile.contiki
ifndef OBJECT_FILES
SOURCE_FILES += ${wildcard ${addsuffix /*.c,$(TARGETCDIRS)} }
OBJECT_FILES = $(SOURCE_FILES:.c=.o)
endif
$(PROJECT): $(PROJECT).c $(OBJECT_FILES)
$(CC) $(CFLAGS) -o $@ $(PROJECT).c $(OBJECT_FILES)
lib: liblwm2m.a
clean::
@-rm -f $(OBJECT_FILES) *.o liblwm2m.a $(PROJECT)
liblwm2m.a: $(OBJECT_FILES)
$(AR) rvs $@ $(OBJECT_FILES)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@

View File

@ -1,57 +0,0 @@
CONTIKI = ../../..
CP=cp
MKDIR=mkdir
DTLS_PATH := $(CONTIKI)/os/net/security
CORE_FILES = sys/cc.h sys/cc-gcc.h lib/list.c lib/memb.c
COAP_FILES = ${addprefix coap/,${filter-out coap-blocking-api.% coap-uip.% coap-timer-default.%,${notdir ${wildcard $(CONTIKI)/os/net/app-layer/coap/coap*}}}}
LWM2M_FILES = ${addprefix lwm2m/,${filter-out ,${notdir ${wildcard $(CONTIKI)/os/services/lwm2m/lwm2m-*}}}}
IPSO_FILES = ${addprefix ipso-objects/,${filter-out ipso-leds-control.c ipso-objects.% ipso-temperature.% ipso-light-control.% ipso-button.c,${notdir ${wildcard $(CONTIKI)/os/services/ipso-objects/ipso-*}}}}
TARGET_FILES += ${addprefix $(TARGETCDIR)/,$(CORE_FILES) $(CORE_FILES:.c=.h) \
$(COAP_FILES) $(LWM2M_FILES) $(IPSO_FILES)}
ifeq ($(MAKE_WITH_DTLS),1)
ifeq (${wildcard $(DTLS_PATH)/tinydtls/Makefile},)
${error Could not find the tinyDTLS submodule. Please run "git submodule update --init" and try again}
endif
DTLS_FILES = ${subst $(DTLS_PATH)/,,${wildcard ${addprefix $(DTLS_PATH)/tinydtls/,*.[ch] ${addsuffix /*.[ch],$(TINYDTLS_DIRS)}}}}
TARGET_FILES += ${addprefix $(TARGETCDIR)/,$(DTLS_FILES)}
endif
SOURCE_FILES += ${filter %.c,$(TARGET_FILES)}
OBJECT_FILES = $(SOURCE_FILES:.c=.o)
$(TARGETCDIR):
@$(MKDIR) $@
$(TARGETCDIRS): $(TARGETCDIR)
@$(MKDIR) $@
$(TARGETCDIR)/sys/%: $(CONTIKI)/os/sys/% | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(TARGETCDIR)/lib/%: $(CONTIKI)/os/lib/% | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(TARGETCDIR)/coap/%: $(CONTIKI)/os/net/app-layer/coap/% | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(TARGETCDIR)/lwm2m/%: $(CONTIKI)/os/services/lwm2m/% | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(TARGETCDIR)/ipso-objects/%: $(CONTIKI)/os/services/ipso-objects/% | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(TARGETCDIR)/tinydtls/%.c: $(DTLS_PATH)/tinydtls/%.c | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(TARGETCDIR)/tinydtls/%.h: $(DTLS_PATH)/tinydtls/%.h | $(TARGETCDIRS)
@$(CP) -av $^ $@
$(OBJECT_FILES): $(TARGET_FILES)
copy: $(TARGET_FILES)
clean::
@-rm -rf $(TARGETCDIR)

View File

@ -1,77 +0,0 @@
LWM2M Standalone Example
====================================
This is an example of how to make use of the OMA LWM2M and CoAP
implementation from Contiki-NG in a native application.
The Makefile will copy necessary files from Contiki-NG to the subfolder
```lwm2m-src``` and then compile the example ```lwm2m-example```
as a native application. By copying only the needed source files,
the example can be used outside the Contiki-NG source tree.
### Running the LWM2M example
```bash
cd contiki/examples/lwm2m/standalone
make
./lwm2m-example
```
The example application will start a CoAP server listening on localhost port
5683 with some example LWM2M objects. By default, the example application will
also register itself with the Leshan server at leshan.eclipse.org. To specify
a different LWM2M server:
`./lwm2m-example coap://<server host address> <endpoint name>`.
For example to connect to a locally running LWM2M server:
```bash
./lwm2m-example coap://127.0.0.1/ example-endpoint-name
```
### Running the LWM2M example with DTLS
The example currently only supports PSK and the default credentials can be
changed in the file `lwm2m-example.c`.
```c
#define PSK_DEFAULT_IDENTITY "Client_identity"
#define PSK_DEFAULT_KEY "secretPSK"
```
To compile with DTLS support and connect to a local LWM2M server with matching
credentials configured:
```bash
cd contiki/examples/lwm2m/standalone
make clean
make MAKE_WITH_DTLS=1
./lwm2m-example coaps://127.0.0.1
```
### Moving the example outside Contiki-NG
```bash
cd contiki/examples/lwm2m/standalone
make copy
```
Copy the example directory contents to a directory outside Contiki-NG.
Remove the Makefile ```Makefile.contiki``` and the remaining Makefile
will compile the example independent of the Contiki-NG source tree.
### Running the LWM2M examle with HEX transport
The Hex Transport can be tested together with DTLS using:
```bash
make clean
make TRANSPORT=hex MAKE_WITH_DTLS=1
javac Hex2UDP.java
java Hex2UDP leshan.eclipse.org 5684 ./lwm2m-example
```
Note that you need to configure the Leshan server with the correct key and ID.
(without DTLS it should be 5683 for CoAP).

View File

@ -1,446 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A HEX text transport for CoAP
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "coap.h"
#include "coap-endpoint.h"
#include "coap-engine.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Log configuration */
#include "coap-log.h"
#define LOG_MODULE "coap-hex"
#define LOG_LEVEL LOG_LEVEL_COAP
#ifdef WITH_DTLS
#include "tinydtls.h"
#include "dtls.h"
#include "dtls_debug.h"
#endif /* WITH_DTLS */
#define BUFSIZE 1280
typedef union {
uint32_t u32[(BUFSIZE + 3) / 4];
uint8_t u8[BUFSIZE];
} coap_buf_t;
static coap_endpoint_t last_source;
static coap_buf_t coap_aligned_buf;
static uint16_t coap_buf_len;
#ifdef WITH_DTLS
#define PSK_DEFAULT_IDENTITY "Client_identity"
#define PSK_DEFAULT_KEY "secretPSK"
static dtls_handler_t cb;
static dtls_context_t *dtls_context = NULL;
/* The PSK information for DTLS */
#define PSK_ID_MAXLEN 256
#define PSK_MAXLEN 256
static unsigned char psk_id[PSK_ID_MAXLEN];
static size_t psk_id_length = 0;
static unsigned char psk_key[PSK_MAXLEN];
static size_t psk_key_length = 0;
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/
static const coap_endpoint_t *
coap_src_endpoint(void)
{
return &last_source;
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_copy(coap_endpoint_t *destination, const coap_endpoint_t *from)
{
memcpy(destination, from, sizeof(coap_endpoint_t));
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
{
return e1->addr == e2->addr;
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_log(const coap_endpoint_t *ep)
{
LOG_OUTPUT("%u", ep->addr);
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_print(const coap_endpoint_t *ep)
{
printf("%u", ep->addr);
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_snprint(char *buf, size_t size, const coap_endpoint_t *ep)
{
int n;
if(size == 0) {
return 0;
}
n = snprintf(buf, size - 1, "%u", ep->addr);
if(n >= size - 1) {
buf[size - 1] = '\0';
}
return n;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
{
/* Hex based CoAP has no addresses, just writes data to standard out */
ep->addr = last_source.addr;
#ifdef WITH_DTLS
ep->secure = 1;
#endif /* WITH_DTLS */
return 1;
}
/*---------------------------------------------------------------------------*/
uint8_t *
coap_databuf(void)
{
return coap_aligned_buf.u8;
}
/*---------------------------------------------------------------------------*/
uint16_t
coap_datalen()
{
return coap_buf_len;
}
/*---------------------------------------------------------------------------*/
static int
hextod(char c)
{
if(c >= '0' && c <= '9') {
return c - '0';
}
if(c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
if(c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
return -1;
}
/*---------------------------------------------------------------------------*/
static void
stdin_callback(const char *line)
{
uint8_t *buf;
int i, len, llen, v1, v2;
if(strncmp("COAPHEX:", line, 8) != 0) {
/* Not a CoAP message */
return;
}
line += 8;
llen = strlen(line);
if((llen & 1) != 0) {
/* Odd number of characters - not hex */
fprintf(stderr, "ERROR: %s\n", line);
return;
}
buf = coap_databuf();
for(i = 0, len = 0; i < llen; i += 2, len++) {
v1 = hextod(line[i]);
v2 = hextod(line[i + 1]);
if(v1 < 0 || v2 < 0) {
/* Not hex */
fprintf(stderr, "ERROR: %s\n", line);
return;
}
buf[len] = (uint8_t)(((v1 << 4) | v2) & 0xff);
}
LOG_INFO("RECV from ");
LOG_INFO_COAP_EP(&last_source);
LOG_INFO_(" %u bytes\n", len);
coap_buf_len = len;
if(LOG_DBG_ENABLED) {
int i;
uint8_t *data;
data = coap_databuf();
LOG_DBG("Received: ");
for(i = 0; i < len; i++) {
LOG_DBG_("%02x", data[i]);
}
LOG_DBG_("\n");
}
#ifdef WITH_DTLS
/* DTLS receive??? */
last_source.secure = 1;
dtls_handle_message(dtls_context, (coap_endpoint_t *) coap_src_endpoint(), coap_databuf(), coap_datalen());
#else
coap_receive(coap_src_endpoint(), coap_databuf(), coap_datalen());
#endif /* WITH_DTLS */
}
/*---------------------------------------------------------------------------*/
void
coap_transport_init(void)
{
select_set_stdin_callback(stdin_callback);
LOG_INFO("CoAP listening on standard in\n");
#ifdef WITH_DTLS
/* create new contet with app-data - no real app-data... */
dtls_context = dtls_new_context(&last_source);
if(!dtls_context) {
LOG_ERR("DTLS: cannot create context\n");
exit(-1);
}
#ifdef DTLS_PSK
psk_id_length = strlen(PSK_DEFAULT_IDENTITY);
psk_key_length = strlen(PSK_DEFAULT_KEY);
memcpy(psk_id, PSK_DEFAULT_IDENTITY, psk_id_length);
memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length);
#endif /* DTLS_PSK */
LOG_DBG("Setting DTLS handler\n");
dtls_set_handler(dtls_context, &cb);
#endif /* WITH_DTLS */
}
/*---------------------------------------------------------------------------*/
int
coap_sendto(const coap_endpoint_t *ep, const uint8_t *data, uint16_t len)
{
if(!coap_endpoint_is_connected(ep)) {
LOG_WARN("CoAP endpoint not connected\n");
return -1;
}
#ifdef WITH_DTLS
if(coap_endpoint_is_secure(ep)) {
return dtls_write(dtls_context, (session_t *)ep, (uint8_t *)data, len);
}
#endif /* WITH_DTLS */
int i;
printf("COAPHEX:");
for(i = 0; i < len; i++) {
printf("%02x", data[i]);
}
printf("\n");
return len;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_connect(coap_endpoint_t *ep)
{
if(ep->secure == 0) {
return 1;
}
#ifdef WITH_DTLS
LOG_DBG("DTLS EP:");
LOG_DBG_COAP_EP(ep);
LOG_DBG_(" len:%d\n", ep->size);
/* setup all address info here... should be done to connect */
dtls_connect(dtls_context, ep);
#endif /* WITH_DTLS */
return 1;
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_disconnect(coap_endpoint_t *ep)
{
#ifdef WITH_DTLS
dtls_close(dtls_context, ep);
#endif /* WITH_DTLS */
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_is_secure(const coap_endpoint_t *ep)
{
return ep->secure;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_is_connected(const coap_endpoint_t *ep)
{
if(ep->secure) {
#ifdef WITH_DTLS
dtls_peer_t *peer;
peer = dtls_get_peer(dtls_context, ep);
if(peer != NULL) {
/* only if handshake is done! */
LOG_DBG("peer state for ");
LOG_DBG_COAP_EP(ep);
LOG_DBG_(" is %d %d\n", peer->state, dtls_peer_is_connected(peer));
return dtls_peer_is_connected(peer);
} else {
LOG_DBG("Did not find peer ");
LOG_DBG_COAP_EP(ep);
LOG_DBG_("\n");
}
#endif /* WITH_DTLS */
return 0;
}
/* Assume that the UDP socket is already up... */
return 1;
}
/* DTLS */
#ifdef WITH_DTLS
/* This is input coming from the DTLS code - e.g. de-crypted input from
the other side - peer */
static int
input_from_peer(struct dtls_context_t *ctx,
session_t *session, uint8_t *data, size_t len)
{
size_t i;
dtls_peer_t *peer;
printf("received data:");
for(i = 0; i < len; i++) {
printf("%c", data[i]);
}
printf("\nHex:");
for(i = 0; i < len; i++) {
printf("%02x", data[i]);
}
printf("\n");
/* Send this into coap-input */
memmove(coap_databuf(), data, len);
coap_buf_len = len;
peer = dtls_get_peer(ctx, session);
/* If we have a peer then ensure that the endpoint is tagged as secure */
if(peer) {
session->secure = 1;
}
coap_receive(session, coap_databuf(), coap_datalen());
return 0;
}
/* This is output from the DTLS code to be sent to peer (encrypted) */
static int
output_to_peer(struct dtls_context_t *ctx,
session_t *session, uint8_t *data, size_t len)
{
int fd = *(int *)dtls_get_app_data(ctx);
printf("output_to_peer len:%d %d (s-size: %d)\n", (int)len, fd,
session->size);
int i;
printf("COAPHEX:");
for(i = 0; i < len; i++) {
printf("%02x", data[i]);
}
printf("\n");
return len;
}
/* This function is the "key store" for tinyDTLS. It is called to
* retrieve a key for the given identity within this particular
* session. */
static int
get_psk_info(struct dtls_context_t *ctx,
const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
unsigned char *result, size_t result_length)
{
LOG_DBG("---===>>> Getting the Key or ID <<<===---\n");
switch(type) {
case DTLS_PSK_IDENTITY:
if(id_len) {
dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id);
}
if(result_length < psk_id_length) {
dtls_warn("cannot set psk_identity -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, psk_id, psk_id_length);
return psk_id_length;
case DTLS_PSK_KEY:
if(id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) {
dtls_warn("PSK for unknown id requested, exiting\n");
return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
} else if(result_length < psk_key_length) {
dtls_warn("cannot set psk -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, psk_key, psk_key_length);
return psk_key_length;
default:
dtls_warn("unsupported request type: %d\n", type);
}
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
static dtls_handler_t cb = {
.write = output_to_peer,
.read = input_from_peer,
.event = NULL,
#ifdef DTLS_PSK
.get_psk_info = get_psk_info,
#endif /* DTLS_PSK */
#ifdef DTLS_ECC
/* .get_ecdsa_key = get_ecdsa_key, */
/* .verify_ecdsa_key = verify_ecdsa_key */
#endif /* DTLS_ECC */
};
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A HEX text transport for CoAP
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef COAP_HEX_H_
#define COAP_HEX_H_
#define COAP_ENDPOINT_CUSTOM 1
typedef struct {
int addr; /* if we want to switch on something... */
unsigned int size;
int secure;
} coap_endpoint_t;
#endif /* COAP_HEX_H_ */

View File

@ -1,648 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A native IPv4 transport for CoAP
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "coap.h"
#include "coap-endpoint.h"
#include "coap-engine.h"
#include "coap-keystore.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <err.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Log configuration */
#include "coap-log.h"
#define LOG_MODULE "coap-ipv4"
#define LOG_LEVEL LOG_LEVEL_COAP
#ifdef WITH_DTLS
#include "tinydtls.h"
#include "dtls.h"
#include "dtls_debug.h"
#endif /* WITH_DTLS */
#define BUFSIZE 1280
typedef union {
uint32_t u32[(BUFSIZE + 3) / 4];
uint8_t u8[BUFSIZE];
} coap_buf_t;
static int coap_ipv4_fd = -1;
static coap_endpoint_t last_source;
static coap_buf_t coap_aligned_buf;
static uint16_t coap_buf_len;
#ifdef WITH_DTLS
static int dtls_ipv4_fd = -1;
static dtls_handler_t cb;
static dtls_context_t *dtls_context = NULL;
static const coap_keystore_t *dtls_keystore = NULL;
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/
static const coap_endpoint_t *
coap_src_endpoint(void)
{
return &last_source;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_is_secure(const coap_endpoint_t *ep)
{
return ep->secure;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_is_connected(const coap_endpoint_t *ep)
{
if(ep->secure) {
#ifdef WITH_DTLS
dtls_peer_t *peer;
peer = dtls_get_peer(dtls_context, ep);
if(peer != NULL) {
/* only if handshake is done! */
LOG_DBG("DTLS peer state for ");
LOG_DBG_COAP_EP(ep);
LOG_DBG_(" is %d %d\n", peer->state, dtls_peer_is_connected(peer));
return dtls_peer_is_connected(peer);
} else {
LOG_DBG("DTLS did not find peer ");
LOG_DBG_COAP_EP(ep);
LOG_DBG_("\n");
}
#endif /* WITH_DTLS */
return 0;
}
/* Assume that the UDP socket is already up... */
return 1;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_connect(coap_endpoint_t *ep)
{
if(ep->secure == 0) {
return 1;
}
#ifdef WITH_DTLS
LOG_DBG("DTLS connect to ");
LOG_DBG_COAP_EP(ep);
LOG_DBG_(" len:%d\n", ep->size);
/* setup all address info here... should be done to connect */
if(dtls_context) {
dtls_connect(dtls_context, ep);
return 1;
}
#endif /* WITH_DTLS */
return 0;
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_disconnect(coap_endpoint_t *ep)
{
#ifdef WITH_DTLS
if(ep && ep->secure && dtls_context) {
dtls_close(dtls_context, ep);
}
#endif /* WITH_DTLS */
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_copy(coap_endpoint_t *destination, const coap_endpoint_t *from)
{
memcpy(destination, from, sizeof(coap_endpoint_t));
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
{
/* need to compare only relevant parts of sockaddr */
switch(e1->addr.sin_family) {
case AF_INET:
return e1->addr.sin_port == e2->addr.sin_port &&
e1->secure == e2->secure &&
memcmp(&e1->addr.sin_addr, &e2->addr.sin_addr,
sizeof(struct in_addr)) == 0;
default:
return 0;
}
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_log(const coap_endpoint_t *ep)
{
const char *address;
address = inet_ntoa(ep->addr.sin_addr);
if(address != NULL) {
LOG_OUTPUT("coap%s://%s:%u", ep->secure ? "s" : "",
address, ntohs(ep->addr.sin_port));
} else {
LOG_OUTPUT("<#N/A>");
}
}
/*---------------------------------------------------------------------------*/
void
coap_endpoint_print(const coap_endpoint_t *ep)
{
const char *address;
address = inet_ntoa(ep->addr.sin_addr);
if(address != NULL) {
printf("coap%s://%s:%u", ep->secure ? "s" : "",
address, ntohs(ep->addr.sin_port));
} else {
printf("<#N/A>");
}
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_snprint(char *buf, size_t size, const coap_endpoint_t *ep)
{
const char *address;
int n;
if(size == 0) {
return 0;
}
address = inet_ntoa(ep->addr.sin_addr);
if(address != NULL) {
n = snprintf(buf, size - 1,
"coap%s://%s:%u", ep->secure ? "s" : "",
address, ntohs(ep->addr.sin_port));
} else {
n = snprintf(buf, size - 1, "<#N/A>");
}
if(n >= size - 1) {
buf[size - 1] = '\0';
}
return n;
}
/*---------------------------------------------------------------------------*/
int
coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
{
/* text = format coap://host:port/... we assume */
/* will not work for know - on the TODO */
/* set server and port */
char host[32];
uint16_t port;
int hlen = 0;
int secure;
int offset = 0;
int i;
LOG_DBG("parsing endpoint %.*s => ", (int)size, text);
if(strncmp("coap://", text, 7) == 0) {
secure = 0;
offset = 7;
} else if(strncmp("coaps://", text, 8) == 0) {
secure = 1;
offset = 8;
LOG_DBG_("secure ");
} else {
secure = 0;
}
for(i = offset; i < size && text[i] != ':' && text[i] != '/' &&
hlen < sizeof(host) - 1; i++) {
host[hlen++] = text[i];
}
host[hlen] = 0;
port = secure == 0 ? COAP_DEFAULT_PORT : COAP_DEFAULT_SECURE_PORT;
if(text[i] == ':') {
/* Parse IPv4 endpoint port */
port = atoi(&text[i + 1]);
}
LOG_DBG_("endpoint at %s:%u\n", host, port);
ep->addr.sin_family = AF_INET;
ep->addr.sin_port = htons(port);
ep->size = sizeof(ep->addr);
ep->secure = secure;
if(inet_aton(host, &ep->addr.sin_addr) == 0) {
/* Failed to parse the address */
LOG_WARN("Failed to parse endpoint host '%s'\n", host);
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
uint8_t *
coap_databuf(void)
{
return coap_aligned_buf.u8;
}
/*---------------------------------------------------------------------------*/
uint16_t
coap_datalen()
{
return coap_buf_len;
}
/*---------------------------------------------------------------------------*/
static int
read_packet_to_coapbuf(int fd, int is_secure)
{
int len;
memset(&last_source, 0, sizeof(last_source));
last_source.size = sizeof(last_source.addr);
len = recvfrom(fd, coap_databuf(), BUFSIZE, 0,
(struct sockaddr *)&last_source.addr, &last_source.size);
if(len == -1) {
if(errno == EAGAIN) {
return 0;
}
err(1, "CoAP-IPv4: recv");
return 0;
}
last_source.secure = is_secure;
LOG_INFO("RECV from ");
LOG_INFO_COAP_EP(&last_source);
LOG_INFO_(" %u bytes\n", len);
coap_buf_len = len;
#if 0
if((rand() & 0xffff) < 0x1000) {
printf("*********---- PACKET LOSS ----********\n");
return 0;
}
#endif
return 1;
}
/*---------------------------------------------------------------------------*/
static int
coap_ipv4_set_fd(fd_set *rset, fd_set *wset)
{
if(coap_ipv4_fd >= 0) {
FD_SET(coap_ipv4_fd, rset);
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
static void
coap_ipv4_handle_fd(fd_set *rset, fd_set *wset)
{
if(coap_ipv4_fd >= 0 && FD_ISSET(coap_ipv4_fd, rset)) {
if(read_packet_to_coapbuf(coap_ipv4_fd, 0)) {
#if LOG_DBG_ENABLED
int i;
uint8_t *data;
data = coap_databuf();
LOG_DBG("Received: ");
for(i = 0; i < coap_buf_len; i++) {
LOG_DBG_("%02x", data[i]);
}
LOG_DBG_("\n");
#endif /* LOG_DBG_ENABLED */
coap_receive(coap_src_endpoint(), coap_databuf(), coap_datalen());
}
}
}
/*---------------------------------------------------------------------------*/
static const struct select_callback udp_callback = {
coap_ipv4_set_fd, coap_ipv4_handle_fd
};
/*---------------------------------------------------------------------------*/
#ifdef WITH_DTLS
static int
dtls_ipv4_set_fd(fd_set *rset, fd_set *wset)
{
if(dtls_ipv4_fd >= 0 && dtls_context) {
FD_SET(dtls_ipv4_fd, rset);
return 1;
}
return 0;
}
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/
#ifdef WITH_DTLS
static void
dtls_ipv4_handle_fd(fd_set *rset, fd_set *wset)
{
if(dtls_ipv4_fd >= 0 && FD_ISSET(dtls_ipv4_fd, rset)) {
if(read_packet_to_coapbuf(dtls_ipv4_fd, 1) && dtls_context) {
/* DTLS receive */
dtls_handle_message(dtls_context, &last_source,
coap_databuf(), coap_datalen());
}
}
}
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/
#ifdef WITH_DTLS
static const struct select_callback dtls_callback = {
dtls_ipv4_set_fd, dtls_ipv4_handle_fd
};
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/
void
coap_transport_init(void)
{
static struct sockaddr_in server;
coap_ipv4_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(coap_ipv4_fd == -1) {
fprintf(stderr, "Could not create CoAP UDP socket\n");
exit(1);
return;
}
memset((void *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(COAP_SERVER_PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(coap_ipv4_fd, (struct sockaddr *)&server, sizeof(server)) == -1) {
fprintf(stderr, "Could not bind CoAP UDP port to %u\n", COAP_SERVER_PORT);
exit(1);
}
LOG_INFO("CoAP server listening on port %u\n", COAP_SERVER_PORT);
select_set_callback(coap_ipv4_fd, &udp_callback);
#ifdef WITH_DTLS
dtls_init();
dtls_set_log_level(8);
dtls_ipv4_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(dtls_ipv4_fd == -1) {
fprintf(stderr, "Could not create CoAP DTLS UDP socket\n");
exit(1);
return;
}
memset((void *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(COAP_DEFAULT_SECURE_PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(dtls_ipv4_fd, (struct sockaddr *)&server, sizeof(server)) == -1) {
fprintf(stderr, "Could not bind CoAP DTLS UDP port to %u\n",
COAP_DEFAULT_SECURE_PORT);
exit(1);
}
LOG_INFO("CoAP DTLS server listening on port %u\n", COAP_DEFAULT_SECURE_PORT);
select_set_callback(dtls_ipv4_fd, &dtls_callback);
/* create new contet with app-data */
dtls_context = dtls_new_context(&dtls_ipv4_fd);
if(!dtls_context) {
fprintf(stderr, "DTLS: cannot create context\n");
exit(-1);
}
dtls_set_handler(dtls_context, &cb);
#endif /* WITH_DTLS */
}
/*---------------------------------------------------------------------------*/
int
coap_sendto(const coap_endpoint_t *ep, const uint8_t *data, uint16_t len)
{
int ret;
if(!coap_endpoint_is_connected(ep)) {
LOG_WARN("endpoint ");
LOG_WARN_COAP_EP(ep);
LOG_WARN_(" not connected - dropping packet\n");
return -1;
}
#ifdef WITH_DTLS
if(coap_endpoint_is_secure(ep)) {
if(dtls_context) {
ret = dtls_write(dtls_context, (session_t *)ep, (uint8_t *)data, len);
LOG_DBG("SENT DTLS to ");
LOG_DBG_COAP_EP(ep);
if(ret < 0) {
LOG_DBG_(" - error %d\n", ret);
} else {
LOG_DBG_(" %d/%u bytes\n", ret, len);
}
return ret;
}
LOG_WARN("no DTLS context\n");
return -1;
}
#endif /* WITH_DTLS */
if(coap_ipv4_fd >= 0) {
ret = sendto(coap_ipv4_fd, data, len, 0, (struct sockaddr *)&ep->addr,
ep->size);
LOG_INFO("SENT to ");
LOG_INFO_COAP_EP(ep);
if(ret < 0) {
LOG_INFO_(" - error %d: %s\n", ret, strerror(errno));
} else {
LOG_INFO_(" %d/%u bytes\n", ret, len);
if(LOG_DBG_ENABLED) {
int i;
LOG_DBG("Sent: ");
for(i = 0; i < len; i++) {
LOG_DBG_("%02x", data[i]);
}
LOG_DBG_("\n");
}
}
return ret;
}
LOG_DBG("failed to send - no socket\n");
return -1;
}
/*---------------------------------------------------------------------------*/
/* DTLS */
#ifdef WITH_DTLS
/* This is input coming from the DTLS code - e.g. de-crypted input from
the other side - peer */
static int
input_from_peer(struct dtls_context_t *ctx,
session_t *session, uint8_t *data, size_t len)
{
#if LOG_DBG_ENABLED
size_t i;
LOG_DBG("DTLS received data: ");
for(i = 0; i < len; i++) {
LOG_DBG_("%c", data[i]);
}
LOG_DBG_("\n");
LOG_DBG("Hex: ");
for(i = 0; i < len; i++) {
LOG_DBG_("%02x", data[i]);
}
LOG_DBG_("\n");
#endif /* LOG_DBG_ENABLED */
/* Send this into coap-input */
memmove(coap_databuf(), data, len);
coap_buf_len = len;
/* Ensure that the endpoint is tagged as secure */
session->secure = 1;
coap_receive(session, coap_databuf(), coap_datalen());
return 0;
}
/* This is output from the DTLS code to be sent to peer (encrypted) */
static int
output_to_peer(struct dtls_context_t *ctx,
session_t *session, uint8_t *data, size_t len)
{
int fd = *(int *)dtls_get_app_data(ctx);
LOG_DBG("DTLS output_to_peer len:%d %d (s-size: %d)\n", (int)len, fd,
session->size);
return sendto(fd, data, len, MSG_DONTWAIT,
(struct sockaddr *)&session->addr, session->size);
}
/* This defines the key-store set API since we hookup DTLS here */
void
coap_set_keystore(const coap_keystore_t *keystore)
{
dtls_keystore = keystore;
}
/* This function is the "key store" for tinyDTLS. It is called to
* retrieve a key for the given identity within this particular
* session. */
static int
get_psk_info(struct dtls_context_t *ctx,
const session_t *session,
dtls_credentials_type_t type,
const unsigned char *id, size_t id_len,
unsigned char *result, size_t result_length)
{
const coap_keystore_t *keystore;
coap_keystore_psk_entry_t ks;
keystore = dtls_keystore;
if(keystore == NULL) {
LOG_DBG("--- No key store available ---\n");
return 0;
}
memset(&ks, 0, sizeof(ks));
LOG_DBG("---===>>> Getting the Key or ID <<<===---\n");
switch(type) {
case DTLS_PSK_IDENTITY:
if(id && id_len) {
ks.identity_hint = id;
ks.identity_hint_len = id_len;
dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id);
}
if(keystore->coap_get_psk_info) {
/* we know that session is a coap endpoint */
keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
}
if(ks.identity == NULL || ks.identity_len == 0) {
LOG_DBG("no psk_identity found\n");
return 0;
}
if(result_length < ks.identity_len) {
LOG_DBG("cannot return psk_identity -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, ks.identity, ks.identity_len);
LOG_DBG("psk_identity with %u bytes found\n", ks.identity_len);
return ks.identity_len;
case DTLS_PSK_KEY:
if(keystore->coap_get_psk_info) {
ks.identity = id;
ks.identity_len = id_len;
/* we know that session is a coap endpoint */
keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
}
if(ks.key == NULL || ks.key_len == 0) {
LOG_DBG("PSK for unknown id requested, exiting\n");
return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
}
if(result_length < ks.key_len) {
LOG_DBG("cannot return psk -- buffer too small\n");
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
memcpy(result, ks.key, ks.key_len);
LOG_DBG("psk with %u bytes found\n", ks.key_len);
return ks.key_len;
default:
dtls_warn("unsupported request type: %d\n", type);
}
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
}
static dtls_handler_t cb = {
.write = output_to_peer,
.read = input_from_peer,
.event = NULL,
#ifdef DTLS_PSK
.get_psk_info = get_psk_info,
#endif /* DTLS_PSK */
#ifdef DTLS_ECC
/* .get_ecdsa_key = get_ecdsa_key, */
/* .verify_ecdsa_key = verify_ecdsa_key */
#endif /* DTLS_ECC */
};
#endif /* WITH_DTLS */
/*---------------------------------------------------------------------------*/

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* A native IPv4 transport for CoAP
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef COAP_IPV4_H_
#define COAP_IPV4_H_
#include <netinet/in.h>
#define COAP_ENDPOINT_CUSTOM 1
typedef struct {
struct sockaddr_in addr;
unsigned int size;
int secure;
} coap_endpoint_t;
#endif /* COAP_IPV4_H_ */

View File

@ -1,115 +0,0 @@
/*
* Copyright (c) 2017, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Standalone CoAP log configuration
* \author
* Niclas Finne <niclas.finne@ri.se>
* Joakim Eriksson <joakim.eriksson@ri.se>
*/
#ifndef COAP_LOG_CONF_H_
#define COAP_LOG_CONF_H_
#include "contiki.h"
#include <stdio.h>
/* The different log levels available */
#define LOG_LEVEL_NONE 0 /* No log */
#define LOG_LEVEL_ERR 1 /* Errors */
#define LOG_LEVEL_WARN 2 /* Warnings */
#define LOG_LEVEL_INFO 3 /* Basic info */
#define LOG_LEVEL_DBG 4 /* Detailed debug */
#ifndef LOG_LEVEL_COAP
#define LOG_LEVEL_COAP LOG_LEVEL_DBG
#endif /* LOG_LEVEL_COAP */
#ifndef LOG_LEVEL_LWM2M
#define LOG_LEVEL_LWM2M LOG_LEVEL_DBG
#endif /* LOG_LEVEL_LWM2M */
#ifndef LOG_WITH_LOC
#define LOG_WITH_LOC 0
#endif /* LOG_WITH_LOC */
#ifndef LOG_WITH_MODULE_PREFIX
#define LOG_WITH_MODULE_PREFIX 1
#endif /* LOG_WITH_MODULE_PREFIX */
/* Custom output function -- default is printf */
#ifdef LOG_CONF_OUTPUT
#define LOG_OUTPUT(...) LOG_CONF_OUTPUT(__VA_ARGS__)
#else /* LOG_CONF_OUTPUT */
#define LOG_OUTPUT(...) printf(__VA_ARGS__)
#endif /* LOG_CONF_OUTPUT */
/* Custom line prefix output function -- default is LOG_OUTPUT */
#ifdef LOG_CONF_OUTPUT_PREFIX
#define LOG_OUTPUT_PREFIX(level, levelstr, module) LOG_CONF_OUTPUT_PREFIX(level, levelstr, module)
#else /* LOG_CONF_OUTPUT_PREFIX */
#define LOG_OUTPUT_PREFIX(level, levelstr, module) LOG_OUTPUT("[%-4s: %-10s] ", levelstr, module)
#endif /* LOG_CONF_OUTPUT_PREFIX */
/* Main log function */
#define LOG(newline, level, levelstr, ...) do { \
if(level <= (LOG_LEVEL)) { \
if(newline) { \
if(LOG_WITH_MODULE_PREFIX) { \
LOG_OUTPUT_PREFIX(level, levelstr, LOG_MODULE); \
} \
if(LOG_WITH_LOC) { \
LOG_OUTPUT("[%s: %d] ", __FILE__, __LINE__); \
} \
} \
LOG_OUTPUT(__VA_ARGS__); \
} \
} while (0)
/* More compact versions of LOG macros */
#define LOG_ERR(...) LOG(1, LOG_LEVEL_ERR, "ERR", __VA_ARGS__)
#define LOG_WARN(...) LOG(1, LOG_LEVEL_WARN, "WARN", __VA_ARGS__)
#define LOG_INFO(...) LOG(1, LOG_LEVEL_INFO, "INFO", __VA_ARGS__)
#define LOG_DBG(...) LOG(1, LOG_LEVEL_DBG, "DBG", __VA_ARGS__)
#define LOG_ERR_(...) LOG(0, LOG_LEVEL_ERR, "ERR", __VA_ARGS__)
#define LOG_WARN_(...) LOG(0, LOG_LEVEL_WARN, "WARN", __VA_ARGS__)
#define LOG_INFO_(...) LOG(0, LOG_LEVEL_INFO, "INFO", __VA_ARGS__)
#define LOG_DBG_(...) LOG(0, LOG_LEVEL_DBG, "DBG", __VA_ARGS__)
/* For testing log level */
#define LOG_ERR_ENABLED ((LOG_LEVEL) >= (LOG_LEVEL_ERR))
#define LOG_WARN_ENABLED ((LOG_LEVEL) >= (LOG_LEVEL_WARN))
#define LOG_INFO_ENABLED ((LOG_LEVEL) >= (LOG_LEVEL_INFO))
#define LOG_DBG_ENABLED ((LOG_LEVEL) >= (LOG_LEVEL_DBG))
#endif /* COAP_LOG_CONF_H_ */

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Configuration for Contiki library
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef CONTIKI_H_
#define CONTIKI_H_
#include <stdint.h>
#include "posix-main.h"
#define COAP_LOG_CONF_PATH "coap-log-conf.h"
#define COAP_TIMER_CONF_DRIVER coap_timer_native_driver
#define LWM2M_ENGINE_CLIENT_ENDPOINT_NAME "lwm2m-ex"
#define LWM2M_DEVICE_MANUFACTURER "RISE SICS"
#define LWM2M_DEVICE_TYPE "lwm2m-example"
#define LWM2M_DEVICE_MODEL_NUMBER "000"
#define LWM2M_DEVICE_SERIAL_NO "1"
#define LWM2M_DEVICE_FIRMWARE_VERSION "0.1"
/* Use LWM2M as DTLS keystore */
#define COAP_DTLS_KEYSTORE_CONF_WITH_LWM2M 1
#ifdef COAP_TRANSPORT_CONF_H
#include COAP_TRANSPORT_CONF_H
#endif
#ifndef COAP_MAX_CHUNK_SIZE
#define COAP_MAX_CHUNK_SIZE 256
#endif /* COAP_MAX_CHUNK_SIZE */
#endif /* CONTIKI_H_ */

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2017, RISE SICS AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup lwm2m-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / Generic Object Example
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <stdint.h>
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "coap-engine.h"
#include <string.h>
#include <stdio.h>
/* Log configuration */
#include "coap-log.h"
#define LOG_MODULE "gen-obj-test"
#define LOG_LEVEL LOG_LEVEL_COAP
static lwm2m_object_t generic_object;
#define MAX_SIZE 512
#define NUMBER_OF_INSTANCES 50
static const lwm2m_resource_id_t resources[] = {
RO(10000),
RO(11000),
};
/*---------------------------------------------------------------------------*/
static int read_data(uint8_t *buffer, int instance_id, int start, int len)
{
int i;
int start_index;
start_index = instance_id;
/* Write len bytes into the buffer from the start-offset */
for(i = 0; i < len; i++) {
buffer[i] = '0' + ((start_index + i) & 0x3f);
if(i + start >= MAX_SIZE) return i;
}
return i;
}
static lwm2m_status_t
opaque_callback(lwm2m_object_instance_t *object,
lwm2m_context_t *ctx, int num_to_write)
{
int len;
LOG_DBG("opaque-stream callback num_to_write: %d off: %d outlen: %d\n",
num_to_write, ctx->offset, ctx->outbuf->len);
len = read_data(&ctx->outbuf->buffer[ctx->outbuf->len],
ctx->object_instance_id,
ctx->offset, num_to_write);
ctx->outbuf->len += len;
/* Do we need to write more */
if(ctx->offset + len < MAX_SIZE) {
ctx->writer_flags |= WRITER_HAS_MORE;
}
return LWM2M_STATUS_OK;
}
/*---------------------------------------------------------------------------*/
static lwm2m_status_t
lwm2m_callback(lwm2m_object_instance_t *object,
lwm2m_context_t *ctx)
{
if(ctx->level <= 2) {
return LWM2M_STATUS_ERROR;
}
/* Only support for read at the moment */
if(ctx->operation == LWM2M_OP_READ) {
switch(ctx->resource_id) {
case 10000:
{
char str[30];
snprintf(str, 30, "hello-%d", (int)ctx->object_instance_id);
lwm2m_object_write_string(ctx, str, strlen(str));
}
break;
case 11000:
LOG_DBG("Preparing object write\n");
lwm2m_object_write_opaque_stream(ctx, MAX_SIZE, opaque_callback);
break;
default:
return LWM2M_STATUS_NOT_FOUND;
}
}
return LWM2M_STATUS_OK;
}
/*---------------------------------------------------------------------------*/
static void
setup_instance(lwm2m_object_instance_t *instance, uint16_t instance_id)
{
instance->object_id = generic_object.impl->object_id;
instance->instance_id = instance_id;
instance->callback = lwm2m_callback;
instance->resource_ids = resources;
instance->resource_count = sizeof(resources) / sizeof(lwm2m_resource_id_t);
}
/*---------------------------------------------------------------------------*/
static lwm2m_object_instance_t *
get_by_id(uint16_t instance_id, lwm2m_status_t *status)
{
lwm2m_object_instance_t *instance = NULL;
if(status != NULL) {
*status = LWM2M_STATUS_OK;
}
if(instance_id < NUMBER_OF_INSTANCES) {
instance = lwm2m_engine_get_instance_buffer();
if(instance == NULL) {
return NULL;
}
/* We are fine - update instance variable */
setup_instance(instance, instance_id);
}
return instance;
}
/*---------------------------------------------------------------------------*/
static lwm2m_object_instance_t *
get_first(lwm2m_status_t *status)
{
return get_by_id(0, status);
}
/*---------------------------------------------------------------------------*/
static lwm2m_object_instance_t *
get_next(lwm2m_object_instance_t *instance, lwm2m_status_t *status)
{
return get_by_id(instance->instance_id + 1, status);
}
/*---------------------------------------------------------------------------*/
static lwm2m_object_impl_t generic_object_impl = {
.object_id = 4712,
.get_first = get_first,
.get_next = get_next,
.get_by_id = get_by_id
};
/*---------------------------------------------------------------------------*/
void
lwm2m_generic_object_test_init(void)
{
generic_object.impl = &generic_object_impl;
lwm2m_engine_add_generic_object(&generic_object);
}
/*---------------------------------------------------------------------------*/

View File

@ -1,86 +0,0 @@
/*
* Copyright (c) 2016, SICS Swedish ICT AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Generic Control
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "coap-engine.h"
#include "ipso-control-template.h"
#include <stdint.h>
#include <string.h>
#include <stdio.h>
static lwm2m_status_t set_value(ipso_control_t *control, uint8_t value);
static lwm2m_status_t set_light_value(ipso_control_t *control, uint8_t value);
/* Name, Object ID, Instance ID, set_value callback */
IPSO_CONTROL(test_control, 3306, 0, set_value);
IPSO_CONTROL(light_control, 3311, 0, set_light_value);
/*---------------------------------------------------------------------------*/
static lwm2m_status_t
set_value(ipso_control_t *control, uint8_t value)
{
/* do something with the value! */
printf("Value set to: %u before: %u\n", value,
ipso_control_get_value(control));
return LWM2M_STATUS_OK;
}
/*---------------------------------------------------------------------------*/
static lwm2m_status_t
set_light_value(ipso_control_t *control, uint8_t value)
{
/* do something with the value! */
printf("Light value set to: %u before: %u\n", value,
ipso_control_get_value(control));
return LWM2M_STATUS_OK;
}
/*---------------------------------------------------------------------------*/
void
ipso_control_test_init(void)
{
ipso_control_add(&test_control);
ipso_control_add(&light_control);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 2016, SICS Swedish ICT AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup ipso-objects
* @{
*/
/**
* \file
* Implementation of OMA LWM2M / IPSO Generic Sensor
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include "lwm2m-object.h"
#include "lwm2m-engine.h"
#include "coap-engine.h"
#include "ipso-sensor-template.h"
#include <stdint.h>
#include <string.h>
static uint32_t temp = 19000;
static uint32_t hum = 30000;
static lwm2m_status_t get_temp_value(const ipso_sensor_t *sensor, int32_t *value);
static lwm2m_status_t get_hum_value(const ipso_sensor_t *sensor, int32_t *value);
IPSO_SENSOR(temp_sensor, 3303, get_temp_value,
.max_range = 120000, /* milli celcius */
.min_range = -30000, /* milli celcius */
.unit = "Cel",
.update_interval = 10
);
IPSO_SENSOR(temp_sensor2, 3303, get_temp_value,
.max_range = 120000, /* milli celcius */
.min_range = -30000, /* milli celcius */
.unit = "Cel",
.update_interval = 10
);
/*---------------------------------------------------------------------------*/
IPSO_SENSOR(hum_sensor, 3304, get_hum_value,
.instance_id = 12,
.max_range = 100000, /* milli */
.min_range = 0, /* milli */
.unit = "%",
.update_interval = 10
);
/*---------------------------------------------------------------------------*/
static lwm2m_status_t
get_temp_value(const ipso_sensor_t *sensor, int32_t *value)
{
*value = temp++;
return LWM2M_STATUS_OK;
}
/*---------------------------------------------------------------------------*/
static lwm2m_status_t
get_hum_value(const ipso_sensor_t *sensor, int32_t *value)
{
*value = hum++;
return LWM2M_STATUS_OK;
}
/*---------------------------------------------------------------------------*/
void
ipso_sensor_temp_init(void)
{
ipso_sensor_add(&temp_sensor);
ipso_sensor_add(&temp_sensor2);
ipso_sensor_add(&hum_sensor);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -1,201 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* An OMA LWM2M standalone example to demonstrate how to use
* the Contiki OMA LWM2M library from a native application.
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "lwm2m-engine.h"
#include "lwm2m-rd-client.h"
#include "lwm2m-firmware.h"
#include "lwm2m-server.h"
#include "lwm2m-security.h"
#include "lwm2m-device.h"
#include "coap.h"
#include "coap-timer.h"
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define PSK_DEFAULT_IDENTITY "Client_identity"
#define PSK_DEFAULT_KEY "secretPSK"
#define WITH_TEST_NOTIFICATION 1
void ipso_sensor_temp_init(void);
void ipso_control_test_init(void);
void ipso_blockwise_test_init(void);
void lwm2m_generic_object_test_init(void);
/* set this above zero to get auto deregister */
static int deregister = -1;
/*---------------------------------------------------------------------------*/
#if WITH_TEST_NOTIFICATION
static void
callback(coap_timer_t *timer)
{
/* Automatic notification on device timer for test!*/
lwm2m_notify_observers("3/0/13");
coap_timer_reset(timer, 10000);
if(deregister > 0) {
deregister--;
if(deregister == 0) {
printf("Deregistering.\n");
lwm2m_rd_client_deregister();
}
}
}
#endif /* WITH_TEST_NOTIFICATION */
/*---------------------------------------------------------------------------*/
static void
session_callback(struct lwm2m_session_info *si, int state)
{
printf("Got Session Callback!!! %d\n", state);
}
/*---------------------------------------------------------------------------*/
#ifndef LWM2M_DEFAULT_RD_SERVER
/* Default to leshan.eclipse.org */
#ifdef WITH_DTLS
#define LWM2M_DEFAULT_RD_SERVER "coaps://5.39.83.206"
#else
#define LWM2M_DEFAULT_RD_SERVER "coap://5.39.83.206"
#endif
#endif /* LWM2M_DEFAULT_RD_SERVER */
/*---------------------------------------------------------------------------*/
void
start_application(int argc, char *argv[])
{
const char *default_server = LWM2M_DEFAULT_RD_SERVER;
coap_endpoint_t server_ep;
int has_server_ep = 0;
char *name = "abcde";
if(argc > 1) {
default_server = argv[1];
}
if(argc > 2) {
name = argv[2];
}
if(default_server != NULL && *default_server != '\0') {
if(coap_endpoint_parse(default_server, strlen(default_server), &server_ep) == 0) {
fprintf(stderr, "failed to parse the server address '%s'\n", default_server);
exit(1);
}
has_server_ep = 1;
}
/* Example using network timer */
#if WITH_TEST_NOTIFICATION
{
static coap_timer_t nt;
coap_timer_set_callback(&nt, callback);
coap_timer_set(&nt, 10000);
}
#endif /* WITH_TEST_NOTIFICATION */
/* Initialize the OMA LWM2M engine */
lwm2m_engine_init();
ipso_sensor_temp_init();
ipso_control_test_init();
ipso_blockwise_test_init();
lwm2m_generic_object_test_init();
/* Register default LWM2M objects */
lwm2m_device_init();
lwm2m_firmware_init();
lwm2m_security_init();
lwm2m_server_init();
if(has_server_ep) {
/* start RD client */
printf("Starting RD client to register at ");
coap_endpoint_print(&server_ep);
printf("\n");
#ifdef WITH_DTLS
#if COAP_DTLS_KEYSTORE_CONF_WITH_LWM2M
#if defined(PSK_DEFAULT_IDENTITY) && defined(PSK_DEFAULT_KEY)
{
lwm2m_security_server_t *server;
/* Register new server with instance id, server id, lifetime in seconds */
if(!lwm2m_server_add(0, 1, 600)) {
printf("failed to add server object\n");
}
server = lwm2m_security_add_server(0, 1,
(uint8_t *)default_server,
strlen(default_server));
if(server == NULL) {
printf("failed to add security object\n");
} else {
if(lwm2m_security_set_server_psk(server,
(uint8_t *)PSK_DEFAULT_IDENTITY,
strlen(PSK_DEFAULT_IDENTITY),
(uint8_t *)PSK_DEFAULT_KEY,
strlen(PSK_DEFAULT_KEY))) {
printf("registered security object for endpoint %s\n",
default_server);
} else {
printf("failed to register security object\n");
}
}
}
#endif /* defined(PSK_DEFAULT_IDENTITY) && defined(PSK_DEFAULT_KEY) */
#endif /* COAP_DTLS_KEYSTORE_CONF_WITH_LWM2M */
#endif /* WITH_DTLS */
#define BOOTSTRAP 0
#if BOOTSTRAP
lwm2m_rd_client_register_with_bootstrap_server(&server_ep);
lwm2m_rd_client_use_bootstrap_server(1);
#else /* BOOTSTRAP */
lwm2m_rd_client_register_with_server(&server_ep);
#endif /* BOOTSTRAP */
lwm2m_rd_client_use_registration_server(1);
lwm2m_rd_client_init(name);
lwm2m_rd_client_set_session_callback(session_callback);
} else {
fprintf(stderr, "No registration server specified.\n");
}
printf("COAP MAX PACKET: %d (BLOCK:%d)\n", COAP_MAX_PACKET_SIZE, COAP_MAX_BLOCK_SIZE);
}
/*---------------------------------------------------------------------------*/

View File

@ -1,103 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Example posix implementation of CoAP timer driver.
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "coap-timer.h"
#include <sys/time.h>
/* Log configuration */
#include "coap-log.h"
#define LOG_MODULE "posix-timer"
#define LOG_LEVEL LOG_LEVEL_WARN
/* The maximal time allowed to move forward between updates */
#define MAX_TIME_CHANGE_MSEC 360000UL
static uint64_t uptime_msec = 0;
static uint64_t last_msec;
/*---------------------------------------------------------------------------*/
static uint64_t
uptime(void)
{
struct timeval tv;
uint64_t t;
if(gettimeofday(&tv, NULL)) {
LOG_WARN("*** failed to retrieve system time\n");
return last_msec;
}
t = tv.tv_sec * (uint64_t)1000;
t += tv.tv_usec / (uint64_t)1000;
if(last_msec == 0) {
/* No update first time */
} else if(t < last_msec) {
/* System time has moved backwards */
LOG_WARN("*** system time has moved backwards %lu msec\n",
(unsigned long)(last_msec - t));
} else if(t - last_msec > MAX_TIME_CHANGE_MSEC) {
/* Too large jump forward in system time */
LOG_WARN("*** system time has moved forward %lu msec\n",
(unsigned long)(t - last_msec));
uptime_msec += 1000UL;
} else {
uptime_msec += t - last_msec;
}
last_msec = t;
return uptime_msec;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
uptime();
}
/*---------------------------------------------------------------------------*/
static void
update(void)
{
}
/*---------------------------------------------------------------------------*/
const coap_timer_driver_t coap_timer_native_driver = {
.init = init,
.uptime = uptime,
.update = update,
};
/*---------------------------------------------------------------------------*/

View File

@ -1,213 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Simple posix main loop with support functions.
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "lwm2m-engine.h"
#include "lwm2m-rd-client.h"
#include "coap-timer.h"
#include <unistd.h>
#include <sys/select.h>
#include <errno.h>
#include <err.h>
#include <stdio.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef SELECT_CONF_MAX
#define SELECT_MAX SELECT_CONF_MAX
#else
#define SELECT_MAX 8
#endif
static const struct select_callback *select_callback[SELECT_MAX];
static int select_max = 0;
static int is_stdin_open = 1;
static void (* stdin_callback)(const char *line);
static char stdin_buffer[2048];
static uint16_t stdin_count;
/*---------------------------------------------------------------------------*/
int
select_set_callback(int fd, const struct select_callback *callback)
{
int i;
if(fd >= 0 && fd < SELECT_MAX) {
/* Check that the callback functions are set */
if(callback != NULL &&
(callback->set_fd == NULL || callback->handle_fd == NULL)) {
callback = NULL;
}
select_callback[fd] = callback;
/* Update fd max */
if(callback != NULL) {
if(fd > select_max) {
select_max = fd;
}
} else {
select_max = 0;
for(i = SELECT_MAX - 1; i > 0; i--) {
if(select_callback[i] != NULL) {
select_max = i;
break;
}
}
}
return 1;
}
fprintf(stderr, "*** failed to set callback for fd %d\n", fd);
return 0;
}
/*---------------------------------------------------------------------------*/
void
select_set_stdin_callback(void (* line_read)(const char *line))
{
stdin_callback = line_read;
}
/*---------------------------------------------------------------------------*/
static int
stdin_set_fd(fd_set *rset, fd_set *wset)
{
if(is_stdin_open) {
FD_SET(STDIN_FILENO, rset);
}
return 1;
}
/*---------------------------------------------------------------------------*/
static void
stdin_handle_fd(fd_set *rset, fd_set *wset)
{
ssize_t ret;
char c;
if(is_stdin_open && FD_ISSET(STDIN_FILENO, rset)) {
ret = read(STDIN_FILENO, &c, 1);
if(ret > 0) {
if(c == '\r') {
/* Ignore CR */
} else if(c == '\n' || stdin_count >= sizeof(stdin_buffer) - 1) {
stdin_buffer[stdin_count] = 0;
if(stdin_count > 0 && stdin_callback != NULL) {
stdin_callback(stdin_buffer);
} else {
fprintf(stderr, "STDIN: %s\n", stdin_buffer);
}
stdin_count = 0;
} else {
stdin_buffer[stdin_count++] = (char)c;
}
} else if(ret == 0) {
/* Standard in closed */
is_stdin_open = 0;
fprintf(stderr, "*** stdin closed\n");
stdin_count = 0;
if(stdin_callback) {
stdin_buffer[0] = 0;
stdin_callback(stdin_buffer);
}
} else if(errno != EAGAIN) {
err(1, "stdin: read");
}
}
}
/*---------------------------------------------------------------------------*/
const static struct select_callback stdin_fd = {
stdin_set_fd, stdin_handle_fd
};
/*---------------------------------------------------------------------------*/
int
main(int argc, char *argv[])
{
uint64_t next_time;
fd_set fdr, fdw;
int maxfd, retval, i;
struct timeval tv;
/* Make standard output unbuffered. */
setvbuf(stdout, (char *)NULL, _IONBF, 0);
select_set_callback(STDIN_FILENO, &stdin_fd);
/* Start the application */
start_application(argc, argv);
while(1) {
tv.tv_sec = 0;
tv.tv_usec = 250;
next_time = coap_timer_time_to_next_expiration();
if(next_time > 0) {
tv.tv_sec = next_time / 1000;
tv.tv_usec = (next_time % 1000) * 1000;
if(tv.tv_usec == 0 && tv.tv_sec == 0) {
/*
* CoAP timer time resolution is milliseconds. Avoid millisecond
* busy loops.
*/
tv.tv_usec = 250;
}
}
FD_ZERO(&fdr);
FD_ZERO(&fdw);
maxfd = 0;
for(i = 0; i <= select_max; i++) {
if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) {
maxfd = i;
}
}
retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv);
if(retval < 0) {
if(errno != EINTR) {
perror("select");
}
} else if(retval > 0) {
/* timeout => retval == 0 */
for(i = 0; i <= maxfd; i++) {
if(select_callback[i] != NULL) {
select_callback[i]->handle_fd(&fdr, &fdw);
}
}
}
/* Process network timers */
for(retval = 0; retval < 5 && coap_timer_run(); retval++);
}
return 0;
}
/*---------------------------------------------------------------------------*/

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2016, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Simple posix main loop with support functions.
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef POSIX_MAIN_H_
#define POSIX_MAIN_H_
#include <inttypes.h>
#include <sys/select.h>
typedef struct select_callback {
int (* set_fd)(fd_set *fdr, fd_set *fdw);
void (* handle_fd)(fd_set *fdr, fd_set *fdw);
} select_callback_t;
int select_set_callback(int fd, const select_callback_t *callback);
void select_set_stdin_callback(void (* line_read)(const char *text));
void start_application(int argc, char *argv[]);
#endif /* POSIX_MAIN_H_ */

View File

@ -1,57 +0,0 @@
/*
* Copyright (c) 2017, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* tinyDTLS support for LWM2M standalone
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef DTLS_SUPPORT_CONF_H_
#define DTLS_SUPPORT_CONF_H_
#include "coap-endpoint.h"
#include "coap-timer.h"
typedef coap_endpoint_t session_t;
typedef struct {
coap_timer_t retransmit_timer;
} dtls_support_context_state_t;
#define DTLS_SUPPORT_CONF_CONTEXT_STATE dtls_support_context_state_t
#define DTLS_TICKS_PER_SECOND 1000
typedef uint64_t dtls_tick_t;
#endif /* DTLS_SUPPORT_CONF_H_ */

View File

@ -1,303 +0,0 @@
/*
* Copyright (c) 2017, SICS, Swedish ICT AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/**
* \file
* Posix support for TinyDTLS
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "tinydtls.h"
#include "coap-timer.h"
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define DEBUG DEBUG_NONE
#include "dtls_debug.h"
#if DEBUG
#define PRINTEP(ep) coap_endpoint_print(ep)
#else /* DEBUG */
#define PRINTEP(ep)
#endif /* DEBUG */
extern char *loglevels[];
/*---------------------------------------------------------------------------*/
static inline size_t
print_timestamp(char *s, size_t len)
{
#ifdef HAVE_TIME_H
time_t t;
struct tm *tmp;
t = time(NULL);
tmp = localtime(&t);
return strftime(s, len, "%b %d %H:%M:%S", tmp);
#else /* alternative implementation: just print the timestamp */
uint64_t t;
t = coap_timer_uptime();
return snprintf(s, len, "%u.%03u",
(unsigned int)(t / 1000),
(unsigned int)(t % 1000));
#endif /* HAVE_TIME_H */
}
/*---------------------------------------------------------------------------*/
#include <pthread.h>
static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
static dtls_cipher_context_t cipher_context;
#define LOCK(P) pthread_mutex_lock(P)
#define UNLOCK(P) pthread_mutex_unlock(P)
/*---------------------------------------------------------------------------*/
dtls_cipher_context_t *
dtls_cipher_context_acquire(void)
{
LOCK(&cipher_context_mutex);
return &cipher_context;
}
/*---------------------------------------------------------------------------*/
void
dtls_cipher_context_release(dtls_cipher_context_t *c)
{
/* just one single context for now */
UNLOCK(&cipher_context_mutex);
}
/*---------------------------------------------------------------------------*/
dtls_context_t *
dtls_context_acquire(void)
{
return (dtls_context_t *)malloc(sizeof(dtls_context_t));
}
/*---------------------------------------------------------------------------*/
void
dtls_context_release(dtls_context_t *context)
{
free(context);
}
/*---------------------------------------------------------------------------*/
#ifndef NDEBUG
size_t
dsrv_print_addr(const session_t *addr, char *buf, size_t len)
{
return 0;
}
#endif /* NDEBUG */
/*---------------------------------------------------------------------------*/
#ifdef HAVE_VPRINTF
void
dsrv_log(log_t level, char *format, ...)
{
static char timebuf[32];
va_list ap;
FILE *log_fd;
if(dtls_get_log_level() < level) {
return;
}
log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout;
if(print_timestamp(timebuf, sizeof(timebuf))) {
fprintf(log_fd, "%s ", timebuf);
}
if(level <= DTLS_LOG_DEBUG) {
fprintf(log_fd, "%s ", loglevels[level]);
}
va_start(ap, format);
vfprintf(log_fd, format, ap);
va_end(ap);
fflush(log_fd);
}
#endif /* HAVE_VPRINTF */
/*---------------------------------------------------------------------------*/
void
dtls_dsrv_hexdump_log(log_t level, const char *name,
const unsigned char *buf, size_t length, int extend)
{
static char timebuf[32];
FILE *log_fd;
int n = 0;
if(dtls_get_log_level() < level) {
return;
}
log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout;
if(print_timestamp(timebuf, sizeof(timebuf))) {
fprintf(log_fd, "%s ", timebuf);
}
if(level <= DTLS_LOG_DEBUG) {
fprintf(log_fd, "%s ", loglevels[level]);
}
if(extend) {
fprintf(log_fd, "%s: (%zu bytes):\n", name, length);
while(length--) {
if(n % 16 == 0) {
fprintf(log_fd, "%08X ", n);
}
fprintf(log_fd, "%02X ", *buf++);
n++;
if(n % 8 == 0) {
if(n % 16 == 0) {
fprintf(log_fd, "\n");
} else {
fprintf(log_fd, " ");
}
}
}
} else {
fprintf(log_fd, "%s: (%zu bytes): ", name, length);
while(length--) {
fprintf(log_fd, "%02X", *buf++);
}
}
fprintf(log_fd, "\n");
fflush(log_fd);
}
/*---------------------------------------------------------------------------*/
/* --------- time support ----------- */
void
dtls_ticks(dtls_tick_t *t)
{
*t = coap_timer_uptime();
}
/*---------------------------------------------------------------------------*/
int
dtls_fill_random(uint8_t *buf, size_t len)
{
FILE *urandom = fopen("/dev/urandom", "r");
if(!urandom) {
dtls_emerg("cannot initialize PRNG\n");
return 0;
}
if(fread(buf, 1, len, urandom) != len) {
dtls_emerg("cannot initialize PRNG\n");
fclose(urandom);
return 0;
}
fclose(urandom);
return 1;
}
/*---------------------------------------------------------------------------*/
/* message retransmission */
/*---------------------------------------------------------------------------*/
static void
dtls_retransmit_callback(coap_timer_t *timer)
{
dtls_context_t *ctx;
uint64_t now;
uint64_t next;
ctx = coap_timer_get_user_data(timer);
now = coap_timer_uptime();
/* Just one retransmission per timer scheduling */
dtls_check_retransmit(ctx, &next, 0);
/* need to set timer to some value even if no nextpdu is available */
if(next != 0) {
coap_timer_set(timer, next <= now ? 1 : next - now);
}
}
/*---------------------------------------------------------------------------*/
void
dtls_set_retransmit_timer(dtls_context_t *ctx, unsigned int timeout)
{
coap_timer_set_callback(&ctx->support.retransmit_timer,
dtls_retransmit_callback);
coap_timer_set_user_data(&ctx->support.retransmit_timer, ctx);
coap_timer_set(&ctx->support.retransmit_timer, timeout);
}
/*---------------------------------------------------------------------------*/
/* Implementation of session functions */
void
dtls_session_init(session_t *session)
{
memset(session, 0, sizeof(session_t));
}
/*---------------------------------------------------------------------------*/
int
dtls_session_equals(const session_t *a, const session_t *b)
{
coap_endpoint_t *e1 = (coap_endpoint_t *)a;
coap_endpoint_t *e2 = (coap_endpoint_t *)b;
PRINTF(" **** EP:");
PRINTEP(e1);
PRINTF(" =?= ");
PRINTEP(e2);
PRINTF(" => %d\n", coap_endpoint_cmp(e1, e2));
return coap_endpoint_cmp(e1, e2);
}
/*---------------------------------------------------------------------------*/
void *
dtls_session_get_address(const session_t *a)
{
/* improve this to only contain the addressing info */
return (void *)a;
}
/*---------------------------------------------------------------------------*/
int
dtls_session_get_address_size(const session_t *a)
{
/* improve this to only contain the addressing info */
return sizeof(session_t);
}
/*---------------------------------------------------------------------------*/
void
dtls_session_print(const session_t *a)
{
coap_endpoint_print((const coap_endpoint_t *)a);
}
/*---------------------------------------------------------------------------*/
/* The init */
void
dtls_support_init(void)
{
}
/*---------------------------------------------------------------------------*/