er-coap: COPIED FROM CETIC 6LBR add cetic tinydtls 'er-coap' communication layer
I would rather have a different way of configuring the communication layer. A way which would not require modifiying the er-coap application. Maybe more like a "disable udp" communication layer thing. And overwrite with something else.
This commit is contained in:
parent
d94efe528a
commit
612cb23759
|
@ -5,4 +5,8 @@ er-coap_src = er-coap.c er-coap-engine.c er-coap-transactions.c \
|
|||
# Erbium will implement the REST Engine
|
||||
CFLAGS += -DREST=coap_rest_implementation
|
||||
|
||||
ifeq ($(WITH_DTLS_COAP),1)
|
||||
er-coap_src += er-coap-dtls.c
|
||||
else
|
||||
er-coap_src += er-coap-udp.c
|
||||
endif
|
||||
|
|
190
apps/er-coap/er-coap-dtls.c
Normal file
190
apps/er-coap/er-coap-dtls.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "er-coap.h"
|
||||
#include "er-coap-engine.h"
|
||||
|
||||
#include "dtls.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "dtls_debug.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if defined DTLS_CONF_IDENTITY_HINT && defined DTLS_CONF_IDENTITY_HINT_LENGTH
|
||||
#define DTLS_IDENTITY_HINT DTLS_CONF_IDENTITY_HINT
|
||||
#define DTLS_IDENTITY_HINT_LENGTH DTLS_CONF_IDENTITY_HINT_LENGTH
|
||||
#else
|
||||
#define DTLS_IDENTITY_HINT "Client_identity"
|
||||
#define DTLS_IDENTITY_HINT_LENGTH 15
|
||||
#endif
|
||||
|
||||
#if defined DTLS_CONF_PSK_KEY && defined DTLS_CONF_PSK_KEY_LENGTH
|
||||
#define DTLS_PSK_KEY_VALUE DTLS_CONF_PSK_KEY
|
||||
#define DTLS_PSK_KEY_VALUE_LENGTH DTLS_CONF_PSK_KEY_LENGTH
|
||||
#else
|
||||
#warning "DTLS: Using default secret key !"
|
||||
#define DTLS_PSK_KEY_VALUE "secretPSK"
|
||||
#define DTLS_PSK_KEY_VALUE_LENGTH 9
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static struct dtls_context_t *dtls_ctx = NULL;
|
||||
|
||||
static int
|
||||
send_to_peer(struct dtls_context_t *ctx,
|
||||
session_t *session, uint8 *data, size_t len);
|
||||
|
||||
static int
|
||||
read_from_peer(struct dtls_context_t *ctx,
|
||||
session_t *session, uint8 *data, size_t len);
|
||||
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);
|
||||
|
||||
static dtls_handler_t dtls_cb = {
|
||||
.write = send_to_peer,
|
||||
.read = read_from_peer,
|
||||
.event = NULL,
|
||||
#ifdef DTLS_PSK
|
||||
.get_psk_info = get_psk_info,
|
||||
#endif
|
||||
#ifdef DTLS_ECC
|
||||
.get_ecdsa_key = NULL,
|
||||
.verify_ecdsa_key = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_init_communication_layer(uint16_t port)
|
||||
{
|
||||
struct uip_udp_conn *udp_conn = NULL;
|
||||
|
||||
dtls_init();
|
||||
dtls_set_log_level(DTLS_LOG_DEBUG);
|
||||
|
||||
udp_conn = udp_new(NULL, 0, NULL);
|
||||
udp_bind(udp_conn, port);
|
||||
|
||||
dtls_ctx = dtls_new_context(udp_conn);
|
||||
if(dtls_ctx) {
|
||||
dtls_set_handler(dtls_ctx, &dtls_cb);
|
||||
}
|
||||
/* new connection with remote host */
|
||||
printf("COAP-DTLS listening on port %u\n", uip_ntohs(udp_conn->lport));
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_send_message(uip_ipaddr_t *addr, uint16_t port, uint8_t *data, uint16_t length)
|
||||
{
|
||||
session_t session;
|
||||
|
||||
dtls_session_init(&session);
|
||||
uip_ipaddr_copy(&session.addr, addr);
|
||||
session.port = port;
|
||||
|
||||
dtls_write(dtls_ctx, &session, data, length);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
coap_handle_receive()
|
||||
{
|
||||
session_t session;
|
||||
|
||||
if(uip_newdata()) {
|
||||
dtls_session_init(&session);
|
||||
uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr);
|
||||
session.port = UIP_UDP_BUF->srcport;
|
||||
|
||||
dtls_handle_message(dtls_ctx, &session, uip_appdata, uip_datalen());
|
||||
}
|
||||
}
|
||||
/* DTLS Specific functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#ifdef DTLS_PSK
|
||||
/* This function is the "key store" for tinyDTLS. It is called to
|
||||
* retrieve a key for the given identiy 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)
|
||||
{
|
||||
|
||||
struct keymap_t {
|
||||
unsigned char *id;
|
||||
size_t id_length;
|
||||
unsigned char *key;
|
||||
size_t key_length;
|
||||
} psk[1] = {
|
||||
{ (unsigned char *)DTLS_IDENTITY_HINT, DTLS_IDENTITY_HINT_LENGTH, (unsigned char *)DTLS_PSK_KEY_VALUE, DTLS_PSK_KEY_VALUE_LENGTH },
|
||||
};
|
||||
if(type == DTLS_PSK_IDENTITY) {
|
||||
if(id_len) {
|
||||
dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id);
|
||||
}
|
||||
|
||||
if(result_length < psk[0].id_length) {
|
||||
dtls_warn("cannot set psk_identity -- buffer too small\n");
|
||||
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
memcpy(result, psk[0].id, psk[0].id_length);
|
||||
return psk[0].id_length;
|
||||
} else if(type == DTLS_PSK_KEY) {
|
||||
if(id) {
|
||||
int i;
|
||||
for(i = 0; i < sizeof(psk) / sizeof(struct keymap_t); i++) {
|
||||
if(id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) {
|
||||
if(result_length < psk[i].key_length) {
|
||||
dtls_warn("buffer too small for PSK");
|
||||
return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
memcpy(result, psk[i].key, psk[i].key_length);
|
||||
return psk[i].key_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static int
|
||||
send_to_peer(struct dtls_context_t *ctx,
|
||||
session_t *session, uint8 *data, size_t len)
|
||||
{
|
||||
|
||||
struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx);
|
||||
|
||||
uip_ipaddr_copy(&conn->ripaddr, &session->addr);
|
||||
conn->rport = session->port;
|
||||
|
||||
uip_udp_packet_send(conn, data, len);
|
||||
|
||||
/* Restore server connection to allow data from any node */
|
||||
memset(&conn->ripaddr, 0, sizeof(conn->ripaddr));
|
||||
memset(&conn->rport, 0, sizeof(conn->rport));
|
||||
|
||||
return len;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static int
|
||||
read_from_peer(struct dtls_context_t *ctx,
|
||||
session_t *session, uint8 *data, size_t len)
|
||||
{
|
||||
uip_len = len;
|
||||
memmove(uip_appdata, data, len);
|
||||
coap_receive(ctx);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue