Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
a824722862
300 changed files with 32381 additions and 1731 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,6 +24,7 @@
|
||||||
*.c128
|
*.c128
|
||||||
*.c64
|
*.c64
|
||||||
*.cc2538dk
|
*.cc2538dk
|
||||||
|
*.srf06-cc26xx
|
||||||
*.ev-aducrf101mkxz
|
*.ev-aducrf101mkxz
|
||||||
*.report
|
*.report
|
||||||
summary
|
summary
|
||||||
|
|
|
@ -48,6 +48,13 @@ before_script:
|
||||||
arm-none-eabi-gcc --version ;
|
arm-none-eabi-gcc --version ;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
## Download and extract cc26xxware
|
||||||
|
- if [ ${BUILD_ARCH:-0} = arm ] ; then
|
||||||
|
wget http://www.ti.com/lit/sw/swrc296/swrc296.zip &&
|
||||||
|
unzip swrc296.zip &&
|
||||||
|
export TI_CC26XXWARE=cc26xxware_2_20_06_14829 ;
|
||||||
|
fi
|
||||||
|
|
||||||
## Install RL78 GCC toolchain
|
## Install RL78 GCC toolchain
|
||||||
- sudo apt-get install libncurses5:i386 zlib1g:i386
|
- sudo apt-get install libncurses5:i386 zlib1g:i386
|
||||||
- $WGET http://adamdunkels.github.io/contiki-fork/gnurl78-v13.02-elf_1-2_i386.deb &&
|
- $WGET http://adamdunkels.github.io/contiki-fork/gnurl78-v13.02-elf_1-2_i386.deb &&
|
||||||
|
@ -115,6 +122,6 @@ env:
|
||||||
- BUILD_TYPE='compile-8051-ports' BUILD_CATEGORY='compile' BUILD_ARCH='8051'
|
- BUILD_TYPE='compile-8051-ports' BUILD_CATEGORY='compile' BUILD_ARCH='8051'
|
||||||
- BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs'
|
- BUILD_TYPE='compile-arm-apcs-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm-apcs'
|
||||||
- BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502'
|
- BUILD_TYPE='compile-6502-ports' BUILD_CATEGORY='compile' BUILD_ARCH='6502'
|
||||||
# - BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm'
|
- BUILD_TYPE='compile-arm-ports' BUILD_CATEGORY='compile' BUILD_ARCH='arm'
|
||||||
- BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja'
|
- BUILD_TYPE='slip-radio' MAKE_TARGETS='cooja'
|
||||||
- BUILD_TYPE='llsec' MAKE_TARGETS='cooja'
|
- BUILD_TYPE='llsec' MAKE_TARGETS='cooja'
|
||||||
|
|
|
@ -88,7 +88,7 @@ makestrings(void)
|
||||||
uip_getdraddr(&addr);
|
uip_getdraddr(&addr);
|
||||||
makeaddr(&addr, gateway);
|
makeaddr(&addr, gateway);
|
||||||
|
|
||||||
addrptr = resolv_getserver();
|
addrptr = uip_nameserver_get(0);
|
||||||
if(addrptr != NULL) {
|
if(addrptr != NULL) {
|
||||||
makeaddr(addrptr, dnsserver);
|
makeaddr(addrptr, dnsserver);
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ dhcpc_configured(const struct dhcpc_state *s)
|
||||||
uip_sethostaddr(&s->ipaddr);
|
uip_sethostaddr(&s->ipaddr);
|
||||||
uip_setnetmask(&s->netmask);
|
uip_setnetmask(&s->netmask);
|
||||||
uip_setdraddr(&s->default_router);
|
uip_setdraddr(&s->default_router);
|
||||||
resolv_conf(&s->dnsaddr);
|
uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME);
|
||||||
set_statustext("Configured.");
|
set_statustext("Configured.");
|
||||||
process_post(PROCESS_CURRENT(), SHOWCONFIG, NULL);
|
process_post(PROCESS_CURRENT(), SHOWCONFIG, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
er-coap_src = er-coap.c er-coap-engine.c er-coap-transactions.c er-coap-observe.c er-coap-separate.c er-coap-res-well-known-core.c er-coap-block1.c
|
er-coap_src = er-coap.c er-coap-engine.c er-coap-transactions.c \
|
||||||
|
er-coap-observe.c er-coap-separate.c er-coap-res-well-known-core.c \
|
||||||
|
er-coap-block1.c er-coap-observe-client.c
|
||||||
|
|
||||||
# Erbium will implement the REST Engine
|
# Erbium will implement the REST Engine
|
||||||
CFLAGS += -DREST=coap_rest_implementation
|
CFLAGS += -DREST=coap_rest_implementation
|
||||||
|
|
|
@ -253,6 +253,16 @@ coap_receive(void)
|
||||||
}
|
}
|
||||||
/* if(ACKed transaction) */
|
/* if(ACKed transaction) */
|
||||||
transaction = NULL;
|
transaction = NULL;
|
||||||
|
|
||||||
|
#if COAP_OBSERVE_CLIENT
|
||||||
|
/* if observe notification */
|
||||||
|
if((message->type == COAP_TYPE_CON || message->type == COAP_TYPE_NON)
|
||||||
|
&& IS_OPTION(message, COAP_OPTION_OBSERVE)) {
|
||||||
|
PRINTF("Observe [%u]\n", message->observe);
|
||||||
|
coap_handle_notification(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport,
|
||||||
|
message);
|
||||||
|
}
|
||||||
|
#endif /* COAP_OBSERVE_CLIENT */
|
||||||
} /* request or response */
|
} /* request or response */
|
||||||
} /* parsed correctly */
|
} /* parsed correctly */
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "er-coap-transactions.h"
|
#include "er-coap-transactions.h"
|
||||||
#include "er-coap-observe.h"
|
#include "er-coap-observe.h"
|
||||||
#include "er-coap-separate.h"
|
#include "er-coap-separate.h"
|
||||||
|
#include "er-coap-observe-client.h"
|
||||||
|
|
||||||
#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT)
|
#define SERVER_LISTEN_PORT UIP_HTONS(COAP_SERVER_PORT)
|
||||||
|
|
||||||
|
|
342
apps/er-coap/er-coap-observe-client.c
Normal file
342
apps/er-coap/er-coap-observe-client.c
Normal file
|
@ -0,0 +1,342 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Daniele Alessandrelli.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \file
|
||||||
|
* Extension to Erbium for enabling CoAP observe clients
|
||||||
|
* \author
|
||||||
|
* Daniele Alessandrelli <daniele.alessandrelli@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "er-coap.h"
|
||||||
|
#include "er-coap-observe-client.h"
|
||||||
|
|
||||||
|
/* Compile this code only if client-side support for CoAP Observe is required */
|
||||||
|
#if COAP_OBSERVE_CLIENT
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
#if DEBUG
|
||||||
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:" \
|
||||||
|
"%02x%02x:%02x%02x:%02x%02x:%02x%02x]", \
|
||||||
|
((uint8_t *)addr)[0], ((uint8_t *)addr)[1], \
|
||||||
|
((uint8_t *)addr)[2], ((uint8_t *)addr)[3], \
|
||||||
|
((uint8_t *)addr)[4], ((uint8_t *)addr)[5], \
|
||||||
|
((uint8_t *)addr)[6], ((uint8_t *)addr)[7], \
|
||||||
|
((uint8_t *)addr)[8], ((uint8_t *)addr)[9], \
|
||||||
|
((uint8_t *)addr)[10], ((uint8_t *)addr)[11], \
|
||||||
|
((uint8_t *)addr)[12], ((uint8_t *)addr)[13], \
|
||||||
|
((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||||
|
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", \
|
||||||
|
(lladdr)->addr[0], (lladdr)->addr[1], \
|
||||||
|
(lladdr)->addr[2], (lladdr)->addr[3], \
|
||||||
|
(lladdr)->addr[4], (lladdr)->addr[5])
|
||||||
|
#else
|
||||||
|
#define PRINTF(...)
|
||||||
|
#define PRINT6ADDR(addr)
|
||||||
|
#define PRINTLLADDR(addr)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES);
|
||||||
|
LIST(obs_subjects_list);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static size_t
|
||||||
|
get_token(void *packet, const uint8_t **token)
|
||||||
|
{
|
||||||
|
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||||
|
|
||||||
|
*token = coap_pkt->token;
|
||||||
|
|
||||||
|
return coap_pkt->token_len;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
set_token(void *packet, const uint8_t *token, size_t token_len)
|
||||||
|
{
|
||||||
|
coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
|
||||||
|
|
||||||
|
coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
|
||||||
|
memcpy(coap_pkt->token, token, coap_pkt->token_len);
|
||||||
|
|
||||||
|
return coap_pkt->token_len;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
coap_observee_t *
|
||||||
|
coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
const uint8_t *token, size_t token_len, const char *url,
|
||||||
|
notification_callback_t notification_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
coap_observee_t *o;
|
||||||
|
|
||||||
|
/* Remove existing observe relationship, if any. */
|
||||||
|
coap_obs_remove_observee_by_url(addr, port, url);
|
||||||
|
o = memb_alloc(&obs_subjects_memb);
|
||||||
|
if(o) {
|
||||||
|
o->url = url;
|
||||||
|
uip_ipaddr_copy(&o->addr, addr);
|
||||||
|
o->port = port;
|
||||||
|
o->token_len = token_len;
|
||||||
|
memcpy(o->token, token, token_len);
|
||||||
|
/* o->last_mid = 0; */
|
||||||
|
o->notification_callback = notification_callback;
|
||||||
|
o->data = data;
|
||||||
|
/* stimer_set(&o->refresh_timer, COAP_OBSERVING_REFRESH_INTERVAL); */
|
||||||
|
PRINTF("Adding obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||||
|
o->token[1]);
|
||||||
|
list_add(obs_subjects_list, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
coap_obs_remove_observee(coap_observee_t *o)
|
||||||
|
{
|
||||||
|
PRINTF("Removing obs_subject for /%s [0x%02X%02X]\n", o->url, o->token[0],
|
||||||
|
o->token[1]);
|
||||||
|
memb_free(&obs_subjects_memb, o);
|
||||||
|
list_remove(obs_subjects_list, o);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
coap_observee_t *
|
||||||
|
coap_get_obs_subject_by_token(const uint8_t *token, size_t token_len)
|
||||||
|
{
|
||||||
|
coap_observee_t *obs = NULL;
|
||||||
|
|
||||||
|
for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs;
|
||||||
|
obs = obs->next) {
|
||||||
|
PRINTF("Looking for token 0x%02X%02X\n", token[0], token[1]);
|
||||||
|
if(obs->token_len == token_len
|
||||||
|
&& memcmp(obs->token, token, token_len) == 0) {
|
||||||
|
return obs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
uint8_t *token, size_t token_len)
|
||||||
|
{
|
||||||
|
int removed = 0;
|
||||||
|
coap_observee_t *obs = NULL;
|
||||||
|
|
||||||
|
for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs;
|
||||||
|
obs = obs->next) {
|
||||||
|
PRINTF("Remove check Token 0x%02X%02X\n", token[0], token[1]);
|
||||||
|
if(uip_ipaddr_cmp(&obs->addr, addr)
|
||||||
|
&& obs->port == port
|
||||||
|
&& obs->token_len == token_len
|
||||||
|
&& memcmp(obs->token, token, token_len) == 0) {
|
||||||
|
coap_obs_remove_observee(obs);
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
const char *url)
|
||||||
|
{
|
||||||
|
int removed = 0;
|
||||||
|
coap_observee_t *obs = NULL;
|
||||||
|
|
||||||
|
for(obs = (coap_observee_t *)list_head(obs_subjects_list); obs;
|
||||||
|
obs = obs->next) {
|
||||||
|
PRINTF("Remove check URL %s\n", url);
|
||||||
|
if(uip_ipaddr_cmp(&obs->addr, addr)
|
||||||
|
&& obs->port == port
|
||||||
|
&& (obs->url == url || memcmp(obs->url, url, strlen(obs->url)) == 0)) {
|
||||||
|
coap_obs_remove_observee(obs);
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
simple_reply(coap_message_type_t type, uip_ip6addr_t *addr, uint16_t port,
|
||||||
|
coap_packet_t *notification)
|
||||||
|
{
|
||||||
|
static coap_packet_t response[1];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
coap_init_message(response, type, NO_ERROR, notification->mid);
|
||||||
|
len = coap_serialize_message(response, uip_appdata);
|
||||||
|
coap_send_message(addr, port, uip_appdata, len);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static coap_notification_flag_t
|
||||||
|
classify_notification(void *response, int first)
|
||||||
|
{
|
||||||
|
coap_packet_t *pkt;
|
||||||
|
|
||||||
|
pkt = (coap_packet_t *)response;
|
||||||
|
if(!pkt) {
|
||||||
|
PRINTF("no response\n");
|
||||||
|
return NO_REPLY_FROM_SERVER;
|
||||||
|
}
|
||||||
|
PRINTF("server replied\n");
|
||||||
|
if(!IS_RESPONSE_CODE_2_XX(pkt)) {
|
||||||
|
PRINTF("error response code\n");
|
||||||
|
return ERROR_RESPONSE_CODE;
|
||||||
|
}
|
||||||
|
if(!IS_OPTION(pkt, COAP_OPTION_OBSERVE)) {
|
||||||
|
PRINTF("server does not support observe\n");
|
||||||
|
return OBSERVE_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
if(first) {
|
||||||
|
return OBSERVE_OK;
|
||||||
|
}
|
||||||
|
return NOTIFICATION_OK;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
coap_handle_notification(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
coap_packet_t *notification)
|
||||||
|
{
|
||||||
|
coap_packet_t *pkt;
|
||||||
|
const uint8_t *token;
|
||||||
|
int token_len;
|
||||||
|
coap_observee_t *obs;
|
||||||
|
coap_notification_flag_t flag;
|
||||||
|
uint32_t observe;
|
||||||
|
|
||||||
|
PRINTF("coap_handle_notification()\n");
|
||||||
|
pkt = (coap_packet_t *)notification;
|
||||||
|
token_len = get_token(pkt, &token);
|
||||||
|
PRINTF("Getting token\n");
|
||||||
|
if(0 == token_len) {
|
||||||
|
PRINTF("Error while handling coap observe notification: "
|
||||||
|
"no token in message\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PRINTF("Getting observee info\n");
|
||||||
|
obs = coap_get_obs_subject_by_token(token, token_len);
|
||||||
|
if(NULL == obs) {
|
||||||
|
PRINTF("Error while handling coap observe notification: "
|
||||||
|
"no matching token found\n");
|
||||||
|
simple_reply(COAP_TYPE_RST, addr, port, notification);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(notification->type == COAP_TYPE_CON) {
|
||||||
|
simple_reply(COAP_TYPE_ACK, addr, port, notification);
|
||||||
|
}
|
||||||
|
if(obs->notification_callback != NULL) {
|
||||||
|
flag = classify_notification(notification, 0);
|
||||||
|
/* TODO: the following mechanism for discarding duplicates is too trivial */
|
||||||
|
/* refer to Observe RFC for a better solution */
|
||||||
|
if(flag == NOTIFICATION_OK) {
|
||||||
|
coap_get_header_observe(notification, &observe);
|
||||||
|
if(observe == obs->last_observe) {
|
||||||
|
PRINTF("Discarding duplicate\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
obs->last_observe = observe;
|
||||||
|
}
|
||||||
|
obs->notification_callback(obs, notification, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static void
|
||||||
|
handle_obs_registration_response(void *data, void *response)
|
||||||
|
{
|
||||||
|
coap_observee_t *obs;
|
||||||
|
notification_callback_t notification_callback;
|
||||||
|
coap_notification_flag_t flag;
|
||||||
|
|
||||||
|
PRINTF("handle_obs_registration_response(): ");
|
||||||
|
obs = (coap_observee_t *)data;
|
||||||
|
notification_callback = obs->notification_callback;
|
||||||
|
flag = classify_notification(response, 1);
|
||||||
|
if(notification_callback) {
|
||||||
|
notification_callback(obs, response, flag);
|
||||||
|
}
|
||||||
|
if(flag != OBSERVE_OK) {
|
||||||
|
coap_obs_remove_observee(obs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
uint8_t
|
||||||
|
coap_generate_token(uint8_t **token_ptr)
|
||||||
|
{
|
||||||
|
static uint8_t token = 0;
|
||||||
|
|
||||||
|
token++;
|
||||||
|
/* FIXME: we should check that this token is not already used */
|
||||||
|
*token_ptr = (uint8_t *)&token;
|
||||||
|
return sizeof(token);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
coap_observee_t *
|
||||||
|
coap_obs_request_registration(uip_ipaddr_t *addr, uint16_t port, char *uri,
|
||||||
|
notification_callback_t notification_callback,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
coap_packet_t request[1];
|
||||||
|
coap_transaction_t *t;
|
||||||
|
uint8_t *token;
|
||||||
|
uint8_t token_len;
|
||||||
|
coap_observee_t *obs;
|
||||||
|
|
||||||
|
obs = NULL;
|
||||||
|
coap_init_message(request, COAP_TYPE_CON, COAP_GET, coap_get_mid());
|
||||||
|
coap_set_header_uri_path(request, uri);
|
||||||
|
coap_set_header_observe(request, 0);
|
||||||
|
token_len = coap_generate_token(&token);
|
||||||
|
set_token(request, token, token_len);
|
||||||
|
t = coap_new_transaction(request->mid, addr, port);
|
||||||
|
if(t) {
|
||||||
|
obs = coap_obs_add_observee(addr, port, (uint8_t *)token, token_len, uri,
|
||||||
|
notification_callback, data);
|
||||||
|
if(obs) {
|
||||||
|
t->callback = handle_obs_registration_response;
|
||||||
|
t->callback_data = obs;
|
||||||
|
t->packet_len = coap_serialize_message(request, t->packet);
|
||||||
|
coap_send_transaction(t);
|
||||||
|
} else {
|
||||||
|
PRINTF("Could not allocate obs_subject resource buffer");
|
||||||
|
coap_clear_transaction(t);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PRINTF("Could not allocate transaction buffer");
|
||||||
|
}
|
||||||
|
return obs;
|
||||||
|
}
|
||||||
|
#endif /* COAP_OBSERVE_CLIENT */
|
121
apps/er-coap/er-coap-observe-client.h
Normal file
121
apps/er-coap/er-coap-observe-client.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Daniele Alessandrelli.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \file
|
||||||
|
* Extension to Erbium for enabling CoAP observe clients
|
||||||
|
* \author
|
||||||
|
* Daniele Alessandrelli <daniele.alessandrelli@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COAP_OBSERVING_CLIENT_H_
|
||||||
|
#define COAP_OBSERVING_CLIENT_H_
|
||||||
|
|
||||||
|
#include "er-coap.h"
|
||||||
|
#include "er-coap-transactions.h"
|
||||||
|
|
||||||
|
#ifndef COAP_OBSERVE_CLIENT
|
||||||
|
#define COAP_OBSERVE_CLIENT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COAP_CONF_MAX_OBSERVEES
|
||||||
|
#define COAP_MAX_OBSERVEES COAP_CONF_MAX_OBSERVEES
|
||||||
|
#else
|
||||||
|
#define COAP_MAX_OBSERVEES 4
|
||||||
|
#endif /* COAP_CONF_MAX_OBSERVEES */
|
||||||
|
|
||||||
|
#if COAP_MAX_OPEN_TRANSACTIONS < COAP_MAX_OBSERVEES
|
||||||
|
#warning "COAP_MAX_OPEN_TRANSACTIONS smaller than COAP_MAX_OBSERVEES: " \
|
||||||
|
"this may be a problem"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IS_RESPONSE_CODE_2_XX(message) (64 < message->code \
|
||||||
|
&& message->code < 128)
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
typedef enum {
|
||||||
|
OBSERVE_OK,
|
||||||
|
NOTIFICATION_OK,
|
||||||
|
OBSERVE_NOT_SUPPORTED,
|
||||||
|
ERROR_RESPONSE_CODE,
|
||||||
|
NO_REPLY_FROM_SERVER,
|
||||||
|
} coap_notification_flag_t;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
typedef struct coap_observee_s coap_observee_t;
|
||||||
|
|
||||||
|
typedef void (*notification_callback_t)(coap_observee_t *subject,
|
||||||
|
void *notification,
|
||||||
|
coap_notification_flag_t);
|
||||||
|
|
||||||
|
struct coap_observee_s {
|
||||||
|
coap_observee_t *next; /* for LIST */
|
||||||
|
uip_ipaddr_t addr;
|
||||||
|
uint16_t port;
|
||||||
|
const char *url;
|
||||||
|
uint8_t token_len;
|
||||||
|
uint8_t token[COAP_TOKEN_LEN];
|
||||||
|
void *data; /* generic pointer for storing user data */
|
||||||
|
notification_callback_t notification_callback;
|
||||||
|
uint32_t last_observe;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
coap_observee_t *coap_obs_add_observee(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
const uint8_t *token, size_t token_len,
|
||||||
|
const char *url,
|
||||||
|
notification_callback_t
|
||||||
|
notification_callback, void *data);
|
||||||
|
|
||||||
|
void coap_obs_remove_observee(coap_observee_t *o);
|
||||||
|
|
||||||
|
coap_observee_t *coap_obs_get_observee_by_token(const uint8_t *token,
|
||||||
|
size_t token_len);
|
||||||
|
|
||||||
|
int coap_obs_remove_observee_by_token(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
uint8_t *token, size_t token_len);
|
||||||
|
|
||||||
|
int coap_obs_remove_observee_by_url(uip_ipaddr_t *addr, uint16_t port,
|
||||||
|
const char *url);
|
||||||
|
|
||||||
|
void coap_handle_notification(uip_ipaddr_t *, uint16_t port,
|
||||||
|
coap_packet_t *notification);
|
||||||
|
|
||||||
|
coap_observee_t *coap_obs_request_registration(uip_ipaddr_t *addr,
|
||||||
|
uint16_t port, char *uri,
|
||||||
|
notification_callback_t
|
||||||
|
notification_callback,
|
||||||
|
void *data);
|
||||||
|
/* TODO: this function may be moved to er-coap.c */
|
||||||
|
uint8_t coap_generate_token(uint8_t **token_ptr);
|
||||||
|
|
||||||
|
#endif /* COAP_OBSERVING_CLIENT_H_ */
|
1
apps/mqtt/Makefile.mqtt
Normal file
1
apps/mqtt/Makefile.mqtt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
mqtt_src = mqtt.c
|
1484
apps/mqtt/mqtt.c
Normal file
1484
apps/mqtt/mqtt.c
Normal file
File diff suppressed because it is too large
Load diff
509
apps/mqtt/mqtt.h
Normal file
509
apps/mqtt/mqtt.h
Normal file
|
@ -0,0 +1,509 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
* 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 HOLDERS AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \addtogroup apps
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \defgroup mqtt-engine An implementation of MQTT v3.1
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* This application is an engine for MQTT v3.1. It supports QoS Levels 0 and 1.
|
||||||
|
*
|
||||||
|
* MQTT is a Client Server publish/subscribe messaging transport protocol.
|
||||||
|
* It is light weight, open, simple, and designed so as to be easy to implement.
|
||||||
|
* These characteristics make it ideal for use in many situations, including
|
||||||
|
* constrained environments such as for communication in Machine to Machine
|
||||||
|
* (M2M) and Internet of Things (IoT) contexts where a small code footprint is
|
||||||
|
* required and/or network bandwidth is at a premium.
|
||||||
|
*
|
||||||
|
* The protocol runs over TCP/IP, more specifically tcp_socket.
|
||||||
|
* Its features include:
|
||||||
|
*
|
||||||
|
* - Use of the publish/subscribe message pattern which provides
|
||||||
|
* one-to-many message distribution and decoupling of applications.
|
||||||
|
* - A messaging transport that is agnostic to the content of the payload.
|
||||||
|
* Three qualities of service for message delivery:
|
||||||
|
* -- "At most once" (0), where messages are delivered according to the best
|
||||||
|
* efforts of the operating environment. Message loss can occur.
|
||||||
|
* This level could be used, for example, with ambient sensor data where it
|
||||||
|
* does not matter if an individual reading is lost as the next one will be
|
||||||
|
* published soon after.
|
||||||
|
* --"At least once" (1), where messages are assured to arrive but duplicates
|
||||||
|
* can occur.
|
||||||
|
* -- "Exactly once" (2), where message are assured to arrive exactly once.
|
||||||
|
* This level could be used, for example, with billing systems where duplicate
|
||||||
|
* or lost messages could lead to incorrect charges being applied. This QoS
|
||||||
|
* level is currently not supported in this implementation.
|
||||||
|
*
|
||||||
|
* - A small transport overhead and protocol exchanges minimized to reduce
|
||||||
|
* network traffic.
|
||||||
|
* - A mechanism, Last Will, to notify interested parties when an abnormal
|
||||||
|
* disconnection occurs.
|
||||||
|
*
|
||||||
|
* The protocol specification and other useful information can be found
|
||||||
|
* here: http://mqtt.org
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Header file for the Contiki MQTT engine
|
||||||
|
*
|
||||||
|
* \author
|
||||||
|
* Texas Instruments
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef MQTT_H_
|
||||||
|
#define MQTT_H_
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
#include "contiki-lib.h"
|
||||||
|
#include "lib/random.h"
|
||||||
|
#include "sys/ctimer.h"
|
||||||
|
#include "sys/etimer.h"
|
||||||
|
#include "net/rpl/rpl.h"
|
||||||
|
#include "net/ip/uip.h"
|
||||||
|
#include "net/ipv6/uip-ds6.h"
|
||||||
|
#include "dev/leds.h"
|
||||||
|
|
||||||
|
#include "tcp-socket.h"
|
||||||
|
#include "udp-socket.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Protocol constants */
|
||||||
|
#define MQTT_CLIENT_ID_MAX_LEN 23
|
||||||
|
|
||||||
|
/* Size of the underlying TCP buffers */
|
||||||
|
#define MQTT_TCP_INPUT_BUFF_SIZE 512
|
||||||
|
#define MQTT_TCP_OUTPUT_BUFF_SIZE 512
|
||||||
|
|
||||||
|
#define MQTT_INPUT_BUFF_SIZE 512
|
||||||
|
#define MQTT_MAX_TOPIC_LENGTH 64
|
||||||
|
#define MQTT_MAX_TOPICS_PER_SUBSCRIBE 1
|
||||||
|
|
||||||
|
#define MQTT_FHDR_SIZE 1
|
||||||
|
#define MQTT_MAX_REMAINING_LENGTH_BYTES 4
|
||||||
|
#define MQTT_PROTOCOL_VERSION 3
|
||||||
|
#define MQTT_PROTOCOL_NAME "MQIsdp"
|
||||||
|
#define MQTT_TOPIC_MAX_LENGTH 128
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Debug configuration, this is similar but not exactly like the Debugging
|
||||||
|
* System discussion at https://github.com/contiki-os/contiki/wiki.
|
||||||
|
*/
|
||||||
|
#define DEBUG_MQTT 0
|
||||||
|
|
||||||
|
#if DEBUG_MQTT == 1
|
||||||
|
#define DBG(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DBG(...)
|
||||||
|
#endif /* DEBUG */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
extern process_event_t mqtt_update_event;
|
||||||
|
|
||||||
|
/* Forward declaration */
|
||||||
|
struct mqtt_connection;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MQTT_RETAIN_OFF,
|
||||||
|
MQTT_RETAIN_ON,
|
||||||
|
} mqtt_retain_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief MQTT engine events
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
MQTT_EVENT_CONNECTED,
|
||||||
|
MQTT_EVENT_DISCONNECTED,
|
||||||
|
|
||||||
|
MQTT_EVENT_SUBACK,
|
||||||
|
MQTT_EVENT_UNSUBACK,
|
||||||
|
MQTT_EVENT_PUBLISH,
|
||||||
|
MQTT_EVENT_PUBACK,
|
||||||
|
|
||||||
|
/* Errors */
|
||||||
|
MQTT_EVENT_ERROR = 0x80,
|
||||||
|
MQTT_EVENT_PROTOCOL_ERROR,
|
||||||
|
MQTT_EVENT_CONNECTION_REFUSED_ERROR,
|
||||||
|
MQTT_EVENT_DNS_ERROR,
|
||||||
|
MQTT_EVENT_NOT_IMPLEMENTED_ERROR,
|
||||||
|
/* Add more */
|
||||||
|
} mqtt_event_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MQTT_STATUS_OK,
|
||||||
|
|
||||||
|
MQTT_STATUS_OUT_QUEUE_FULL,
|
||||||
|
|
||||||
|
/* Errors */
|
||||||
|
MQTT_STATUS_ERROR = 0x80,
|
||||||
|
MQTT_STATUS_NOT_CONNECTED_ERROR,
|
||||||
|
MQTT_STATUS_INVALID_ARGS_ERROR,
|
||||||
|
MQTT_STATUS_DNS_ERROR,
|
||||||
|
} mqtt_status_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MQTT_QOS_LEVEL_0,
|
||||||
|
MQTT_QOS_LEVEL_1,
|
||||||
|
MQTT_QOS_LEVEL_2,
|
||||||
|
} mqtt_qos_level_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MQTT_QOS_STATE_NO_ACK,
|
||||||
|
MQTT_QOS_STATE_GOT_ACK,
|
||||||
|
|
||||||
|
/* Expand for QoS 2 */
|
||||||
|
} mqtt_qos_state_t;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* This is the state of the connection itself.
|
||||||
|
*
|
||||||
|
* N.B. The order is important because of runtime checks on how far the
|
||||||
|
* connection has proceeded.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
MQTT_CONN_STATE_ERROR,
|
||||||
|
MQTT_CONN_STATE_DNS_ERROR,
|
||||||
|
MQTT_CONN_STATE_DISCONNECTING,
|
||||||
|
|
||||||
|
MQTT_CONN_STATE_NOT_CONNECTED,
|
||||||
|
MQTT_CONN_STATE_DNS_LOOKUP,
|
||||||
|
MQTT_CONN_STATE_TCP_CONNECTING,
|
||||||
|
MQTT_CONN_STATE_TCP_CONNECTED,
|
||||||
|
MQTT_CONN_STATE_CONNECTING_TO_BROKER,
|
||||||
|
MQTT_CONN_STATE_CONNECTED_TO_BROKER,
|
||||||
|
MQTT_CONN_STATE_SENDING_MQTT_DISCONNECT,
|
||||||
|
MQTT_CONN_STATE_ABORT_IMMEDIATE,
|
||||||
|
} mqtt_conn_state_t;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct mqtt_string {
|
||||||
|
char *string;
|
||||||
|
uint16_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that the pairing mid <-> QoS level only applies one-to-one if we only
|
||||||
|
* allow the subscription of one topic at a time. Otherwise we will have an
|
||||||
|
* ordered list of QoS levels corresponding to the order of topics.
|
||||||
|
*
|
||||||
|
* This could be part of a union of event data structures.
|
||||||
|
*/
|
||||||
|
struct mqtt_suback_event {
|
||||||
|
uint16_t mid;
|
||||||
|
mqtt_qos_level_t qos_level;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the MQTT message that is exposed to the end user. */
|
||||||
|
struct mqtt_message {
|
||||||
|
uint32_t mid;
|
||||||
|
char topic[MQTT_MAX_TOPIC_LENGTH + 1]; /* +1 for string termination */
|
||||||
|
|
||||||
|
uint8_t *payload_chunk;
|
||||||
|
uint16_t payload_chunk_length;
|
||||||
|
|
||||||
|
uint8_t first_chunk;
|
||||||
|
uint16_t payload_length;
|
||||||
|
uint16_t payload_left;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This struct represents a packet received from the MQTT server. */
|
||||||
|
struct mqtt_in_packet {
|
||||||
|
/* Used by the list interface, must be first in the struct. */
|
||||||
|
struct mqtt_connection *next;
|
||||||
|
|
||||||
|
/* Total bytes read so far. Compared to the remaining length to to decide when
|
||||||
|
* we've read the payload. */
|
||||||
|
uint32_t byte_counter;
|
||||||
|
uint8_t packet_received;
|
||||||
|
|
||||||
|
uint8_t fhdr;
|
||||||
|
uint16_t remaining_length;
|
||||||
|
uint16_t mid;
|
||||||
|
|
||||||
|
/* Helper variables needed to decode the remaining_length */
|
||||||
|
uint8_t remaining_multiplier;
|
||||||
|
uint8_t has_remaining_length;
|
||||||
|
uint8_t remaining_length_bytes;
|
||||||
|
|
||||||
|
/* Not the same as payload in the MQTT sense, it also contains the variable
|
||||||
|
* header.
|
||||||
|
*/
|
||||||
|
uint8_t payload_pos;
|
||||||
|
uint8_t payload[MQTT_INPUT_BUFF_SIZE];
|
||||||
|
|
||||||
|
/* Message specific data */
|
||||||
|
uint16_t topic_len;
|
||||||
|
uint16_t topic_pos;
|
||||||
|
uint8_t topic_len_received;
|
||||||
|
uint8_t topic_received;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This struct represents a packet sent to the MQTT server. */
|
||||||
|
struct mqtt_out_packet {
|
||||||
|
uint8_t fhdr;
|
||||||
|
uint32_t remaining_length;
|
||||||
|
uint8_t remaining_length_enc[MQTT_MAX_REMAINING_LENGTH_BYTES];
|
||||||
|
uint8_t remaining_length_enc_bytes;
|
||||||
|
uint16_t mid;
|
||||||
|
char *topic;
|
||||||
|
uint16_t topic_length;
|
||||||
|
uint8_t *payload;
|
||||||
|
uint32_t payload_size;
|
||||||
|
mqtt_qos_level_t qos;
|
||||||
|
mqtt_qos_state_t qos_state;
|
||||||
|
mqtt_retain_t retain;
|
||||||
|
};
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief MQTT event callback function
|
||||||
|
* \param m A pointer to a MQTT connection
|
||||||
|
* \param event The event number
|
||||||
|
* \param data A user-defined pointer
|
||||||
|
*
|
||||||
|
* The MQTT socket event callback function gets called whenever there is an
|
||||||
|
* event on a MQTT connection, such as the connection getting connected
|
||||||
|
* or closed.
|
||||||
|
*/
|
||||||
|
typedef void (*mqtt_event_callback_t)(struct mqtt_connection *m,
|
||||||
|
mqtt_event_t event,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
typedef void (*mqtt_topic_callback_t)(struct mqtt_connection *m,
|
||||||
|
struct mqtt_message *msg);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
struct mqtt_will {
|
||||||
|
struct mqtt_string topic;
|
||||||
|
struct mqtt_string message;
|
||||||
|
mqtt_qos_level_t qos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mqtt_credentials {
|
||||||
|
struct mqtt_string username;
|
||||||
|
struct mqtt_string password;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mqtt_connection {
|
||||||
|
/* Used by the list interface, must be first in the struct */
|
||||||
|
struct mqtt_connection *next;
|
||||||
|
struct timer t;
|
||||||
|
|
||||||
|
struct mqtt_string client_id;
|
||||||
|
|
||||||
|
uint8_t connect_vhdr_flags;
|
||||||
|
uint8_t auto_reconnect;
|
||||||
|
|
||||||
|
uint16_t keep_alive;
|
||||||
|
struct ctimer keep_alive_timer;
|
||||||
|
uint8_t waiting_for_pingresp;
|
||||||
|
|
||||||
|
struct mqtt_will will;
|
||||||
|
struct mqtt_credentials credentials;
|
||||||
|
|
||||||
|
mqtt_conn_state_t state;
|
||||||
|
mqtt_event_callback_t event_callback;
|
||||||
|
|
||||||
|
/* Internal data */
|
||||||
|
uint16_t mid_counter;
|
||||||
|
|
||||||
|
/* Used for communication between MQTT API and APP */
|
||||||
|
uint8_t out_queue_full;
|
||||||
|
struct process *app_process;
|
||||||
|
|
||||||
|
/* Outgoing data related */
|
||||||
|
uint8_t *out_buffer_ptr;
|
||||||
|
uint8_t out_buffer[MQTT_TCP_OUTPUT_BUFF_SIZE];
|
||||||
|
uint8_t out_buffer_sent;
|
||||||
|
struct mqtt_out_packet out_packet;
|
||||||
|
struct pt out_proto_thread;
|
||||||
|
uint32_t out_write_pos;
|
||||||
|
uint16_t max_segment_size;
|
||||||
|
|
||||||
|
/* Incoming data related */
|
||||||
|
uint8_t in_buffer[MQTT_TCP_INPUT_BUFF_SIZE];
|
||||||
|
struct mqtt_in_packet in_packet;
|
||||||
|
struct mqtt_message in_publish_msg;
|
||||||
|
|
||||||
|
/* TCP related information */
|
||||||
|
char *server_host;
|
||||||
|
uip_ipaddr_t server_ip;
|
||||||
|
uint16_t server_port;
|
||||||
|
struct tcp_socket socket;
|
||||||
|
};
|
||||||
|
/* This is the API exposed to the user. */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Initializes the MQTT engine.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param app_process A pointer to the application process handling the MQTT
|
||||||
|
* connection.
|
||||||
|
* \param client_id A pointer to the MQTT client ID.
|
||||||
|
* \param event_callback Callback function responsible for handling the
|
||||||
|
* callback from MQTT engine.
|
||||||
|
* \param max_segment_size The TCP segment size to use for this MQTT/TCP
|
||||||
|
* connection.
|
||||||
|
* \return MQTT_STATUS_OK or MQTT_STATUS_INVALID_ARGS_ERROR
|
||||||
|
*
|
||||||
|
* This function initializes the MQTT engine and shall be called before any
|
||||||
|
* other MQTT function.
|
||||||
|
*/
|
||||||
|
mqtt_status_t mqtt_register(struct mqtt_connection *conn,
|
||||||
|
struct process *app_process,
|
||||||
|
char *client_id,
|
||||||
|
mqtt_event_callback_t event_callback,
|
||||||
|
uint16_t max_segment_size);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Connects to a MQTT broker.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param host IP address of the broker to connect to.
|
||||||
|
* \param port Port of the broker to connect to, default is MQTT port is 1883.
|
||||||
|
* \param keep_alive Keep alive timer in seconds. Used by broker to handle
|
||||||
|
* client disc. Defines the maximum time interval between two messages
|
||||||
|
* from the client. Shall be min 1.5 x report interval.
|
||||||
|
* \return MQTT_STATUS_OK or an error status
|
||||||
|
*
|
||||||
|
* This function connects to a MQTT broker.
|
||||||
|
*/
|
||||||
|
mqtt_status_t mqtt_connect(struct mqtt_connection *conn,
|
||||||
|
char *host,
|
||||||
|
uint16_t port,
|
||||||
|
uint16_t keep_alive);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Disconnects from a MQTT broker.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
*
|
||||||
|
* This function disconnects from a MQTT broker.
|
||||||
|
*/
|
||||||
|
void mqtt_disconnect(struct mqtt_connection *conn);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Subscribes to a MQTT topic.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param mid A pointer to message ID.
|
||||||
|
* \param topic A pointer to the topic to subscribe to.
|
||||||
|
* \param qos_level Quality Of Service level to use. Currently supports 0, 1.
|
||||||
|
* \return MQTT_STATUS_OK or some error status
|
||||||
|
*
|
||||||
|
* This function subscribes to a topic on a MQTT broker.
|
||||||
|
*/
|
||||||
|
mqtt_status_t mqtt_subscribe(struct mqtt_connection *conn,
|
||||||
|
uint16_t *mid,
|
||||||
|
char *topic,
|
||||||
|
mqtt_qos_level_t qos_level);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Unsubscribes from a MQTT topic.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param mid A pointer to message ID.
|
||||||
|
* \param topic A pointer to the topic to unsubscribe from.
|
||||||
|
* \return MQTT_STATUS_OK or some error status
|
||||||
|
*
|
||||||
|
* This function unsubscribes from a topic on a MQTT broker.
|
||||||
|
*/
|
||||||
|
mqtt_status_t mqtt_unsubscribe(struct mqtt_connection *conn,
|
||||||
|
uint16_t *mid,
|
||||||
|
char *topic);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Publish to a MQTT topic.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param mid A pointer to message ID.
|
||||||
|
* \param topic A pointer to the topic to subscribe to.
|
||||||
|
* \param payload A pointer to the topic payload.
|
||||||
|
* \param payload_size Payload size.
|
||||||
|
* \param qos_level Quality Of Service level to use. Currently supports 0, 1.
|
||||||
|
* \param retain If the RETAIN flag is set to 1, in a PUBLISH Packet sent by a
|
||||||
|
* Client to a Server, the Server MUST store the Application Message
|
||||||
|
* and its QoS, so that it can be delivered to future subscribers whose
|
||||||
|
* subscriptions match its topic name
|
||||||
|
* \return MQTT_STATUS_OK or some error status
|
||||||
|
*
|
||||||
|
* This function publishes to a topic on a MQTT broker.
|
||||||
|
*/
|
||||||
|
mqtt_status_t mqtt_publish(struct mqtt_connection *conn,
|
||||||
|
uint16_t *mid,
|
||||||
|
char *topic,
|
||||||
|
uint8_t *payload,
|
||||||
|
uint32_t payload_size,
|
||||||
|
mqtt_qos_level_t qos_level,
|
||||||
|
mqtt_retain_t retain);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Set the user name and password for a MQTT client.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param username A pointer to the user name.
|
||||||
|
* \param password A pointer to the password.
|
||||||
|
*
|
||||||
|
* This function sets clients user name and password to use when connecting to
|
||||||
|
* a MQTT broker.
|
||||||
|
*/
|
||||||
|
void mqtt_set_username_password(struct mqtt_connection *conn,
|
||||||
|
char *username,
|
||||||
|
char *password);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Set the last will topic and message for a MQTT client.
|
||||||
|
* \param conn A pointer to the MQTT connection.
|
||||||
|
* \param topic A pointer to the Last Will topic.
|
||||||
|
* \param message A pointer to the Last Will message (payload).
|
||||||
|
* \param qos The desired QoS level.
|
||||||
|
*
|
||||||
|
* This function sets clients Last Will topic and message (payload).
|
||||||
|
* If the Will Flag is set to 1 (using the function) this indicates that,
|
||||||
|
* if the Connect request is accepted, a Will Message MUST be stored on the
|
||||||
|
* Server and associated with the Network Connection. The Will Message MUST
|
||||||
|
* be published when the Network Connection is subsequently closed.
|
||||||
|
*
|
||||||
|
* This functionality can be used to get notified that a device has
|
||||||
|
* disconnected from the broker.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void mqtt_set_last_will(struct mqtt_connection *conn,
|
||||||
|
char *topic,
|
||||||
|
char *message,
|
||||||
|
mqtt_qos_level_t qos);
|
||||||
|
|
||||||
|
#define mqtt_connected(conn) \
|
||||||
|
((conn)->state == MQTT_CONN_STATE_CONNECTED_TO_BROKER ? 1 : 0)
|
||||||
|
|
||||||
|
#define mqtt_ready(conn) \
|
||||||
|
(!(conn)->out_queue_full && mqtt_connected((conn)))
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#endif /* MQTT_H_ */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
|
@ -113,7 +113,7 @@ makestrings(void)
|
||||||
makeaddr(&addr, gateway);
|
makeaddr(&addr, gateway);
|
||||||
|
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
addrptr = resolv_getserver();
|
addrptr = uip_nameserver_get(0);
|
||||||
if(addrptr != NULL) {
|
if(addrptr != NULL) {
|
||||||
makeaddr(addrptr, dnsserver);
|
makeaddr(addrptr, dnsserver);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ apply_tcpipconfig(void)
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
nullterminate(dnsserver);
|
nullterminate(dnsserver);
|
||||||
if(uiplib_ipaddrconv(dnsserver, &addr)) {
|
if(uiplib_ipaddrconv(dnsserver, &addr)) {
|
||||||
resolv_conf(&addr);
|
uip_nameserver_update(&addr, UIP_NAMESERVER_INFINITE_LIFETIME);
|
||||||
}
|
}
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file Shell command for downloading files from a remote node.
|
* \file
|
||||||
|
*
|
||||||
|
* Shell command for downloading files from a remote node.
|
||||||
* Example usage:
|
* Example usage:
|
||||||
* 'download <node addr> <filename> | write <local_filename'.
|
* 'download \<node addr\> \<filename\> | write \<local_filename\>'.
|
||||||
*
|
*
|
||||||
* \author Luca Mottola <luca@sics.se>, Fredrik Osterlind <fros@sics.se>
|
* \author Luca Mottola <luca@sics.se>, Fredrik Osterlind <fros@sics.se>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -212,10 +212,10 @@ static struct protected_mem_t {
|
||||||
coffee_page_t next_free;
|
coffee_page_t next_free;
|
||||||
char gc_wait;
|
char gc_wait;
|
||||||
} protected_mem;
|
} protected_mem;
|
||||||
static struct file * const coffee_files = protected_mem.coffee_files;
|
static struct file *const coffee_files = protected_mem.coffee_files;
|
||||||
static struct file_desc * const coffee_fd_set = protected_mem.coffee_fd_set;
|
static struct file_desc *const coffee_fd_set = protected_mem.coffee_fd_set;
|
||||||
static coffee_page_t * const next_free = &protected_mem.next_free;
|
static coffee_page_t *const next_free = &protected_mem.next_free;
|
||||||
static char * const gc_wait = &protected_mem.gc_wait;
|
static char *const gc_wait = &protected_mem.gc_wait;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -359,7 +359,6 @@ isolate_pages(coffee_page_t start, coffee_page_t skip_pages)
|
||||||
}
|
}
|
||||||
PRINTF("Coffee: Isolated %u pages starting in sector %d\n",
|
PRINTF("Coffee: Isolated %u pages starting in sector %d\n",
|
||||||
(unsigned)skip_pages, (int)start / COFFEE_PAGES_PER_SECTOR);
|
(unsigned)skip_pages, (int)start / COFFEE_PAGES_PER_SECTOR);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -1179,7 +1178,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
PRINTF("Extended the file at page %u\n", (unsigned)file->page);
|
PRINTF("Extended the file at page %u\n", (unsigned)file->page);
|
||||||
}
|
}
|
||||||
#if COFFEE_IO_SEMANTICS
|
#if COFFEE_IO_SEMANTICS
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if COFFEE_MICRO_LOGS
|
#if COFFEE_MICRO_LOGS
|
||||||
|
@ -1239,7 +1238,7 @@ cfs_write(int fd, const void *buf, unsigned size)
|
||||||
COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset));
|
COFFEE_WRITE(buf, size, absolute_offset(file->page, fdp->offset));
|
||||||
fdp->offset += size;
|
fdp->offset += size;
|
||||||
#if COFFEE_MICRO_LOGS
|
#if COFFEE_MICRO_LOGS
|
||||||
}
|
}
|
||||||
#endif /* COFFEE_MICRO_LOGS */
|
#endif /* COFFEE_MICRO_LOGS */
|
||||||
|
|
||||||
if(fdp->offset > file->end) {
|
if(fdp->offset > file->end) {
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "net/ip/uiplib.h"
|
#include "net/ip/uiplib.h"
|
||||||
#include "net/ip/uip-udp-packet.h"
|
#include "net/ip/uip-udp-packet.h"
|
||||||
#include "net/ip/simple-udp.h"
|
#include "net/ip/simple-udp.h"
|
||||||
|
#include "net/ip/uip-nameserver.h"
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
#include "net/ipv6/uip-icmp6.h"
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
|
|
|
@ -201,6 +201,7 @@ void ctk_draw_clear_window(struct ctk_window *window,
|
||||||
* drawn, in screen coordinates (line 1 is the first line below the
|
* drawn, in screen coordinates (line 1 is the first line below the
|
||||||
* menus)
|
* menus)
|
||||||
*
|
*
|
||||||
|
* \param draw_borders The border style
|
||||||
*/
|
*/
|
||||||
void ctk_draw_window(struct ctk_window *window,
|
void ctk_draw_window(struct ctk_window *window,
|
||||||
unsigned char focus,
|
unsigned char focus,
|
||||||
|
@ -318,7 +319,7 @@ extern unsigned char ctk_draw_windowborder_width,
|
||||||
/**
|
/**
|
||||||
* The character used for the Return/Enter key.
|
* The character used for the Return/Enter key.
|
||||||
*
|
*
|
||||||
* \define #define CH_ENTER '\n'
|
* \#define CH_ENTER '\n'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,7 +77,7 @@ unsigned short crc16_add(unsigned char b, unsigned short crc);
|
||||||
* \brief Calculate the CRC16 over a data area
|
* \brief Calculate the CRC16 over a data area
|
||||||
* \param data Pointer to the data
|
* \param data Pointer to the data
|
||||||
* \param datalen The length of the data
|
* \param datalen The length of the data
|
||||||
* \param crc The accumulated CRC that is to be updated (or zero).
|
* \param acc The accumulated CRC that is to be updated (or zero).
|
||||||
* \return The CRC16 checksum.
|
* \return The CRC16 checksum.
|
||||||
*
|
*
|
||||||
* This function calculates the CRC16 checksum of a data area.
|
* This function calculates the CRC16 checksum of a data area.
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include "net/ip/tcpip.h"
|
#include "net/ip/tcpip.h"
|
||||||
#include "net/ip/resolv.h"
|
#include "net/ip/resolv.h"
|
||||||
#include "net/ip/uip-udp-packet.h"
|
#include "net/ip/uip-udp-packet.h"
|
||||||
|
#include "net/ip/uip-nameserver.h"
|
||||||
#include "lib/random.h"
|
#include "lib/random.h"
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
|
@ -227,17 +228,6 @@ struct dns_hdr {
|
||||||
uint16_t numextrarr;
|
uint16_t numextrarr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** These default values for the DNS server are Google's public DNS:
|
|
||||||
* <https://developers.google.com/speed/public-dns/docs/using>
|
|
||||||
*/
|
|
||||||
static uip_ipaddr_t resolv_default_dns_server =
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
{ { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 } };
|
|
||||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
{ { 8, 8, 8, 8 } };
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
|
|
||||||
/** \internal The DNS answer message structure. */
|
/** \internal The DNS answer message structure. */
|
||||||
struct dns_answer {
|
struct dns_answer {
|
||||||
/* DNS answer record starts with either a domain name or a pointer
|
/* DNS answer record starts with either a domain name or a pointer
|
||||||
|
@ -269,6 +259,7 @@ struct namemap {
|
||||||
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
#endif /* RESOLV_SUPPORTS_RECORD_EXPIRATION */
|
||||||
uip_ipaddr_t ipaddr;
|
uip_ipaddr_t ipaddr;
|
||||||
uint8_t err;
|
uint8_t err;
|
||||||
|
uint8_t server;
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
int is_mdns:1, is_probe:1;
|
int is_mdns:1, is_probe:1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -637,6 +628,21 @@ mdns_prep_host_announce_packet(void)
|
||||||
}
|
}
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static char
|
||||||
|
try_next_server(struct namemap *namemapptr)
|
||||||
|
{
|
||||||
|
#if VERBOSE_DEBUG
|
||||||
|
printf("server %d\n", namemapptr->server);
|
||||||
|
#endif
|
||||||
|
namemapptr->server++;
|
||||||
|
if(uip_nameserver_get(namemapptr->server) != NULL) {
|
||||||
|
namemapptr->retries = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
namemapptr->server = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \internal
|
/** \internal
|
||||||
* Runs through the list of names to see if there are any that have
|
* Runs through the list of names to see if there are any that have
|
||||||
* not yet been queried and, if so, sends out a query.
|
* not yet been queried and, if so, sends out a query.
|
||||||
|
@ -666,6 +672,9 @@ check_entries(void)
|
||||||
if(++namemapptr->retries == RESOLV_CONF_MAX_RETRIES)
|
if(++namemapptr->retries == RESOLV_CONF_MAX_RETRIES)
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
{
|
{
|
||||||
|
/* Try the next server (if possible) before failing. Otherwise
|
||||||
|
simply mark the entry as failed. */
|
||||||
|
if(try_next_server(namemapptr) == 0) {
|
||||||
/* STATE_ERROR basically means "not found". */
|
/* STATE_ERROR basically means "not found". */
|
||||||
namemapptr->state = STATE_ERROR;
|
namemapptr->state = STATE_ERROR;
|
||||||
|
|
||||||
|
@ -677,6 +686,7 @@ check_entries(void)
|
||||||
resolv_found(namemapptr->name, NULL);
|
resolv_found(namemapptr->name, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
namemapptr->tmr = namemapptr->retries * namemapptr->retries * 3;
|
namemapptr->tmr = namemapptr->retries * namemapptr->retries * 3;
|
||||||
|
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
|
@ -747,7 +757,9 @@ check_entries(void)
|
||||||
} else {
|
} else {
|
||||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||||
(query - (uint8_t *) uip_appdata),
|
(query - (uint8_t *) uip_appdata),
|
||||||
&resolv_default_dns_server, UIP_HTONS(DNS_PORT));
|
(const uip_ipaddr_t *)
|
||||||
|
uip_nameserver_get(namemapptr->server),
|
||||||
|
UIP_HTONS(DNS_PORT));
|
||||||
|
|
||||||
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
||||||
namemapptr->name);
|
namemapptr->name);
|
||||||
|
@ -755,7 +767,8 @@ check_entries(void)
|
||||||
#else /* RESOLV_CONF_SUPPORTS_MDNS */
|
#else /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||||
(query - (uint8_t *) uip_appdata),
|
(query - (uint8_t *) uip_appdata),
|
||||||
&resolv_default_dns_server, UIP_HTONS(DNS_PORT));
|
uip_nameserver_get(namemapptr->server),
|
||||||
|
UIP_HTONS(DNS_PORT));
|
||||||
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
||||||
namemapptr->name);
|
namemapptr->name);
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
|
@ -1041,11 +1054,28 @@ newdata(void)
|
||||||
uip_ipaddr_copy(&namemapptr->ipaddr, (uip_ipaddr_t *) ans->ipaddr);
|
uip_ipaddr_copy(&namemapptr->ipaddr, (uip_ipaddr_t *) ans->ipaddr);
|
||||||
|
|
||||||
resolv_found(namemapptr->name, &namemapptr->ipaddr);
|
resolv_found(namemapptr->name, &namemapptr->ipaddr);
|
||||||
|
break;
|
||||||
|
|
||||||
skip_to_next_answer:
|
skip_to_next_answer:
|
||||||
queryptr = (unsigned char *)skip_name(queryptr) + 10 + uip_htons(ans->len);
|
queryptr = (unsigned char *)skip_name(queryptr) + 10 + uip_htons(ans->len);
|
||||||
--nanswers;
|
--nanswers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Got to this point there's no answer, try next nameserver if available
|
||||||
|
since this one doesn't know the answer */
|
||||||
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
|
if(nanswers == 0 && UIP_UDP_BUF->srcport != UIP_HTONS(MDNS_PORT)
|
||||||
|
&& hdr->id != 0)
|
||||||
|
#else
|
||||||
|
if(nanswers == 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if(try_next_server(namemapptr)) {
|
||||||
|
namemapptr->state = STATE_ASKING;
|
||||||
|
process_post(&resolv_process, PROCESS_EVENT_TIMER, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
|
@ -1405,31 +1435,6 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
|
||||||
* Obtain the currently configured DNS server.
|
|
||||||
*
|
|
||||||
* \return A pointer to a 4-byte representation of the IP address of
|
|
||||||
* the currently configured DNS server or NULL if no DNS server has
|
|
||||||
* been configured.
|
|
||||||
*/
|
|
||||||
uip_ipaddr_t *
|
|
||||||
resolv_getserver(void)
|
|
||||||
{
|
|
||||||
return &resolv_default_dns_server;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* Configure a DNS server.
|
|
||||||
*
|
|
||||||
* \param dnsserver A pointer to a 4-byte representation of the IP
|
|
||||||
* address of the DNS server to be configured.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
resolv_conf(const uip_ipaddr_t * dnsserver)
|
|
||||||
{
|
|
||||||
uip_ipaddr_copy(&resolv_default_dns_server, dnsserver);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Callback function which is called when a hostname is found.
|
* Callback function which is called when a hostname is found.
|
||||||
*
|
*
|
||||||
|
|
|
@ -57,11 +57,6 @@
|
||||||
*/
|
*/
|
||||||
CCIF extern process_event_t resolv_event_found;
|
CCIF extern process_event_t resolv_event_found;
|
||||||
|
|
||||||
/* Functions. */
|
|
||||||
CCIF void resolv_conf(const uip_ipaddr_t * dnsserver);
|
|
||||||
|
|
||||||
CCIF uip_ipaddr_t *resolv_getserver(void);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/** Hostname is fresh and usable. This response is cached and will eventually
|
/** Hostname is fresh and usable. This response is cached and will eventually
|
||||||
* expire to RESOLV_STATUS_EXPIRED.*/
|
* expire to RESOLV_STATUS_EXPIRED.*/
|
||||||
|
@ -95,6 +90,7 @@ enum {
|
||||||
|
|
||||||
typedef uint8_t resolv_status_t;
|
typedef uint8_t resolv_status_t;
|
||||||
|
|
||||||
|
/* Functions. */
|
||||||
CCIF resolv_status_t resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr);
|
CCIF resolv_status_t resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr);
|
||||||
|
|
||||||
CCIF void resolv_query(const char *name);
|
CCIF void resolv_query(const char *name);
|
||||||
|
|
|
@ -142,7 +142,7 @@ int simple_udp_sendto(struct simple_udp_connection *c,
|
||||||
* \param data A pointer to the data to be sent
|
* \param data A pointer to the data to be sent
|
||||||
* \param datalen The length of the data
|
* \param datalen The length of the data
|
||||||
* \param to The IP address of the receiver
|
* \param to The IP address of the receiver
|
||||||
* \param port The UDP port of the receiver, in host byte order
|
* \param to_port The UDP port of the receiver, in host byte order
|
||||||
*
|
*
|
||||||
* This function sends a UDP packet to a specified IP
|
* This function sends a UDP packet to a specified IP
|
||||||
* address and UDP port. The packet will be sent with the
|
* address and UDP port. The packet will be sent with the
|
||||||
|
|
234
core/net/ip/uip-nameserver.c
Normal file
234
core/net/ip/uip-nameserver.c
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* uIP Name Server interface
|
||||||
|
* \author Víctor Ariño <victor.arino@tado.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, tado° GmbH.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "contiki-net.h"
|
||||||
|
|
||||||
|
#include "lib/list.h"
|
||||||
|
#include "lib/memb.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
/** \brief Nameserver record */
|
||||||
|
typedef struct uip_nameserver_record {
|
||||||
|
struct uip_nameserver_record *next;
|
||||||
|
uip_ipaddr_t ip;
|
||||||
|
uint32_t added;
|
||||||
|
uint32_t lifetime;
|
||||||
|
} uip_nameserver_record;
|
||||||
|
|
||||||
|
/** \brief Initialization flag */
|
||||||
|
static uint8_t initialized = 0;
|
||||||
|
|
||||||
|
/** \name List and memory block
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
LIST(dns);
|
||||||
|
MEMB(dnsmemb, uip_nameserver_record, UIP_NAMESERVER_POOL_SIZE);
|
||||||
|
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
static uip_ipaddr_t serveraddr;
|
||||||
|
static uint32_t serverlifetime;
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** \brief Expiration time in seconds */
|
||||||
|
#define DNS_EXPIRATION(r) \
|
||||||
|
(((UIP_NAMESERVER_INFINITE_LIFETIME - r->added) <= r->lifetime) ? \
|
||||||
|
UIP_NAMESERVER_INFINITE_LIFETIME : r->added + r->lifetime)
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* Initialize the module variables
|
||||||
|
*/
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
static CC_INLINE void
|
||||||
|
init(void)
|
||||||
|
{
|
||||||
|
list_init(dns);
|
||||||
|
memb_init(&dnsmemb);
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime)
|
||||||
|
{
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
register uip_nameserver_record *e;
|
||||||
|
|
||||||
|
if(initialized == 0) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(e = list_head(dns); e != NULL; e = list_item_next(e)) {
|
||||||
|
if(uip_ipaddr_cmp(&e->ip, nameserver)) {
|
||||||
|
break;
|
||||||
|
/* RFC6106: In case there's no more space, the new servers should replace
|
||||||
|
* the the eldest ones */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e == NULL) {
|
||||||
|
if((e = memb_alloc(&dnsmemb)) != NULL) {
|
||||||
|
list_add(dns, e);
|
||||||
|
} else {
|
||||||
|
uip_nameserver_record *p;
|
||||||
|
for(e = list_head(dns), p = list_head(dns); p != NULL;
|
||||||
|
p = list_item_next(p)) {
|
||||||
|
if(DNS_EXPIRATION(p) < DNS_EXPIRATION(e)) {
|
||||||
|
e = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC6106: In case the entry is existing the expiration time must be
|
||||||
|
* updated. Otherwise, new entries are added. */
|
||||||
|
if(e != NULL) {
|
||||||
|
if(lifetime == 0) {
|
||||||
|
memb_free(&dnsmemb, e);
|
||||||
|
list_remove(dns, e);
|
||||||
|
} else {
|
||||||
|
e->added = clock_seconds();
|
||||||
|
e->lifetime = lifetime;
|
||||||
|
uip_ipaddr_copy(&e->ip, nameserver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
uip_ipaddr_copy(&serveraddr, nameserver);
|
||||||
|
serverlifetime = lifetime;
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
/**
|
||||||
|
* Purge expired records
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
purge(void)
|
||||||
|
{
|
||||||
|
register uip_nameserver_record *e = NULL;
|
||||||
|
uint32_t time = clock_seconds();
|
||||||
|
for(e = list_head(dns); e != NULL; e = list_item_next(e)) {
|
||||||
|
if(DNS_EXPIRATION(e) < time) {
|
||||||
|
list_remove(dns, e);
|
||||||
|
memb_free(&dnsmemb, e);
|
||||||
|
e = list_head(dns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
uip_ipaddr_t *
|
||||||
|
uip_nameserver_get(uint8_t num)
|
||||||
|
{
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
uint8_t i;
|
||||||
|
uip_nameserver_record *e = NULL;
|
||||||
|
|
||||||
|
if(initialized == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
purge();
|
||||||
|
for(i = 1, e = list_head(dns); e != NULL && i <= num;
|
||||||
|
i++, e = list_item_next(e)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e != NULL) {
|
||||||
|
return &e->ip;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
if(num > 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &serveraddr;
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
uint32_t
|
||||||
|
uip_nameserver_next_expiration(void)
|
||||||
|
{
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
register uip_nameserver_record *e = NULL;
|
||||||
|
uint32_t exp = UIP_NAMESERVER_INFINITE_LIFETIME;
|
||||||
|
uint32_t t;
|
||||||
|
|
||||||
|
if(initialized == 0 || list_length(dns) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
purge();
|
||||||
|
for(e = list_head(dns); e != NULL; e = list_item_next(e)) {
|
||||||
|
t = DNS_EXPIRATION(e);
|
||||||
|
if(t < exp) {
|
||||||
|
exp = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exp;
|
||||||
|
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
return serverlifetime;
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
uint16_t
|
||||||
|
uip_nameserver_count(void)
|
||||||
|
{
|
||||||
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
|
if(initialized == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return list_length(dns);
|
||||||
|
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
|
if(uip_is_addr_unspecified(&serveraddr)) {
|
||||||
|
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
|
if(uip_ipaddr_cmp(&serveraddr, &uip_all_zeroes_addr)) {
|
||||||
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
101
core/net/ip/uip-nameserver.h
Normal file
101
core/net/ip/uip-nameserver.h
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* uIP Name Server interface
|
||||||
|
* \author Víctor Ariño <victor.arino@tado.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, tado° GmbH.
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UIP_NAMESERVER_H_
|
||||||
|
#define UIP_NAMESERVER_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name General
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/** \brief Number of Nameservers to keep */
|
||||||
|
#ifndef UIP_CONF_NAMESERVER_POOL_SIZE
|
||||||
|
#define UIP_NAMESERVER_POOL_SIZE 1
|
||||||
|
#else /* UIP_CONF_NAMESERVER_POOL_SIZE */
|
||||||
|
#define UIP_NAMESERVER_POOL_SIZE UIP_CONF_NAMESERVER_POOL_SIZE
|
||||||
|
#endif /* UIP_CONF_NAMESERVER_POOL_SIZE */
|
||||||
|
/** \brief Infinite Lifetime indicator */
|
||||||
|
#define UIP_NAMESERVER_INFINITE_LIFETIME 0xFFFFFFFF
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Nameserver maintenance
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \brief Insert or update a nameserver into/from the pool
|
||||||
|
*
|
||||||
|
* The list is kept according to the RFC6106, which indicates that new entries
|
||||||
|
* will replace old ones (with lower lifetime) and existing entries will update
|
||||||
|
* their lifetimes.
|
||||||
|
*
|
||||||
|
* \param nameserver Pointer to the nameserver ip address
|
||||||
|
* \param lifetime Life time of the given address. Minimum is 0, which is
|
||||||
|
* considered to remove an entry. Maximum is 0xFFFFFFFF which
|
||||||
|
* is considered infinite.
|
||||||
|
*/
|
||||||
|
void uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get a Nameserver ip address given in RA
|
||||||
|
*
|
||||||
|
* \param num The number of the nameserver to obtain, starting at 0 and going
|
||||||
|
* up to the pool size.
|
||||||
|
*/
|
||||||
|
uip_ipaddr_t *uip_nameserver_get(uint8_t num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get next expiration time
|
||||||
|
*
|
||||||
|
* The least expiration time is returned
|
||||||
|
*/
|
||||||
|
uint32_t uip_nameserver_next_expiration(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the number of recorded name servers
|
||||||
|
*/
|
||||||
|
uint16_t uip_nameserver_count(void);
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* UIP_NAMESERVER_H_ */
|
||||||
|
/** @} */
|
|
@ -350,7 +350,7 @@ void uip_setipid(uint16_t id);
|
||||||
* Periodic processing for a connection identified by its number.
|
* Periodic processing for a connection identified by its number.
|
||||||
*
|
*
|
||||||
* This function does the necessary periodic processing (timers,
|
* This function does the necessary periodic processing (timers,
|
||||||
* polling) for a uIP TCP conneciton, and should be called when the
|
* polling) for a uIP TCP connection, and should be called when the
|
||||||
* periodic uIP timer goes off. It should be called for every
|
* periodic uIP timer goes off. It should be called for every
|
||||||
* connection, regardless of whether they are open of closed.
|
* connection, regardless of whether they are open of closed.
|
||||||
*
|
*
|
||||||
|
@ -393,8 +393,10 @@ void uip_setipid(uint16_t id);
|
||||||
uip_process(UIP_TIMER); } while (0)
|
uip_process(UIP_TIMER); } while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Macro to determine whether a specific uIP connection is active
|
||||||
*
|
*
|
||||||
*
|
* \param conn The connection's number
|
||||||
|
* \retval 0 Connection closed
|
||||||
*/
|
*/
|
||||||
#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
|
#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED)
|
||||||
|
|
||||||
|
@ -489,7 +491,7 @@ void uip_reass_over(void);
|
||||||
/**
|
/**
|
||||||
* The uIP packet buffer.
|
* The uIP packet buffer.
|
||||||
*
|
*
|
||||||
* The uip_buf array is used to hold incoming and outgoing
|
* The uip_aligned_buf array is used to hold incoming and outgoing
|
||||||
* packets. The device driver should place incoming data into this
|
* packets. The device driver should place incoming data into this
|
||||||
* buffer. When sending data, the device driver should read the link
|
* buffer. When sending data, the device driver should read the link
|
||||||
* level headers and the TCP/IP headers from this buffer. The size of
|
* level headers and the TCP/IP headers from this buffer. The size of
|
||||||
|
@ -519,6 +521,8 @@ typedef union {
|
||||||
} uip_buf_t;
|
} uip_buf_t;
|
||||||
|
|
||||||
CCIF extern uip_buf_t uip_aligned_buf;
|
CCIF extern uip_buf_t uip_aligned_buf;
|
||||||
|
|
||||||
|
/** Macro to access uip_aligned_buf as an array of bytes */
|
||||||
#define uip_buf (uip_aligned_buf.u8)
|
#define uip_buf (uip_aligned_buf.u8)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1097,7 +1101,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Check if an address is a broadcast address for a network.
|
* Check if an address is a broadcast address for a network.
|
||||||
*
|
*
|
||||||
* Checks if an address is the broadcast address for a network. The
|
* Checks if an address is the broadcast address for a network. The
|
||||||
|
@ -2172,7 +2176,7 @@ CCIF extern uip_lladdr_t uip_lladdr;
|
||||||
*
|
*
|
||||||
* See RFC1071.
|
* See RFC1071.
|
||||||
*
|
*
|
||||||
* \param buf A pointer to the buffer over which the checksum is to be
|
* \param data A pointer to the buffer over which the checksum is to be
|
||||||
* computed.
|
* computed.
|
||||||
*
|
*
|
||||||
* \param len The length of the buffer over which the checksum is to
|
* \param len The length of the buffer over which the checksum is to
|
||||||
|
@ -2180,7 +2184,7 @@ CCIF extern uip_lladdr_t uip_lladdr;
|
||||||
*
|
*
|
||||||
* \return The Internet checksum of the buffer.
|
* \return The Internet checksum of the buffer.
|
||||||
*/
|
*/
|
||||||
uint16_t uip_chksum(uint16_t *buf, uint16_t len);
|
uint16_t uip_chksum(uint16_t *data, uint16_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the IP header checksum of the packet header in uip_buf.
|
* Calculate the IP header checksum of the packet header in uip_buf.
|
||||||
|
|
|
@ -93,7 +93,7 @@ void uip_add32(uint8_t *op32, uint16_t op16);
|
||||||
* \note This function is not called in the current version of uIP,
|
* \note This function is not called in the current version of uIP,
|
||||||
* but future versions might make use of it.
|
* but future versions might make use of it.
|
||||||
*
|
*
|
||||||
* \param buf A pointer to the buffer over which the checksum is to be
|
* \param data A pointer to the buffer over which the checksum is to be
|
||||||
* computed.
|
* computed.
|
||||||
*
|
*
|
||||||
* \param len The length of the buffer over which the checksum is to
|
* \param len The length of the buffer over which the checksum is to
|
||||||
|
@ -101,7 +101,7 @@ void uip_add32(uint8_t *op32, uint16_t op16);
|
||||||
*
|
*
|
||||||
* \return The Internet checksum of the buffer.
|
* \return The Internet checksum of the buffer.
|
||||||
*/
|
*/
|
||||||
uint16_t uip_chksum(uint16_t *buf, uint16_t len);
|
uint16_t uip_chksum(uint16_t *data, uint16_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the IP header checksum of the packet header in uip_buf.
|
* Calculate the IP header checksum of the packet header in uip_buf.
|
||||||
|
|
|
@ -75,18 +75,9 @@
|
||||||
#include "net/ipv4/uip_arp.h"
|
#include "net/ipv4/uip_arp.h"
|
||||||
#include "net/ip/uip_arch.h"
|
#include "net/ip/uip_arch.h"
|
||||||
|
|
||||||
#if !NETSTACK_CONF_WITH_IPV6 /* If NETSTACK_CONF_WITH_IPV6 is defined, we compile the
|
|
||||||
uip6.c file instead of this one. Therefore
|
|
||||||
this #ifndef removes the entire compilation
|
|
||||||
output of the uip.c file */
|
|
||||||
|
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
#include "net/ipv4/uip-neighbor.h"
|
#include "net/ipv4/uip-neighbor.h"
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Variable definitions. */
|
/* Variable definitions. */
|
||||||
|
|
||||||
|
@ -699,7 +690,7 @@ uip_process(uint8_t flag)
|
||||||
}
|
}
|
||||||
goto drop;
|
goto drop;
|
||||||
|
|
||||||
/* Check if we were invoked because of the perodic timer fireing. */
|
/* Check if we were invoked because of the periodic timer firing. */
|
||||||
} else if(flag == UIP_TIMER) {
|
} else if(flag == UIP_TIMER) {
|
||||||
#if UIP_REASSEMBLY
|
#if UIP_REASSEMBLY
|
||||||
if(uip_reasstmr != 0) {
|
if(uip_reasstmr != 0) {
|
||||||
|
@ -851,7 +842,7 @@ uip_process(uint8_t flag)
|
||||||
that the packet has been corrupted in transit. If the size of
|
that the packet has been corrupted in transit. If the size of
|
||||||
uip_len is larger than the size reported in the IP packet header,
|
uip_len is larger than the size reported in the IP packet header,
|
||||||
the packet has been padded and we set uip_len to the correct
|
the packet has been padded and we set uip_len to the correct
|
||||||
value.. */
|
value. */
|
||||||
|
|
||||||
if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
|
if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
|
||||||
uip_len = (BUF->len[0] << 8) + BUF->len[1];
|
uip_len = (BUF->len[0] << 8) + BUF->len[1];
|
||||||
|
@ -891,7 +882,7 @@ uip_process(uint8_t flag)
|
||||||
|
|
||||||
if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
|
if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr)) {
|
||||||
/* If we are configured to use ping IP address configuration and
|
/* If we are configured to use ping IP address configuration and
|
||||||
hasn't been assigned an IP address yet, we accept all ICMP
|
haven't been assigned an IP address yet, we accept all ICMP
|
||||||
packets. */
|
packets. */
|
||||||
#if UIP_PINGADDRCONF && !NETSTACK_CONF_WITH_IPV6
|
#if UIP_PINGADDRCONF && !NETSTACK_CONF_WITH_IPV6
|
||||||
if(BUF->proto == UIP_PROTO_ICMP) {
|
if(BUF->proto == UIP_PROTO_ICMP) {
|
||||||
|
@ -1252,7 +1243,7 @@ uip_process(uint8_t flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we didn't find and active connection that expected the packet,
|
/* If we didn't find an active connection that expected the packet,
|
||||||
either this packet is an old duplicate, or this is a SYN packet
|
either this packet is an old duplicate, or this is a SYN packet
|
||||||
destined for a connection in LISTEN. If the SYN flag isn't set,
|
destined for a connection in LISTEN. If the SYN flag isn't set,
|
||||||
it is an old packet and we send a RST. */
|
it is an old packet and we send a RST. */
|
||||||
|
@ -1441,7 +1432,7 @@ uip_process(uint8_t flag)
|
||||||
uip_flags = 0;
|
uip_flags = 0;
|
||||||
/* We do a very naive form of TCP reset processing; we just accept
|
/* We do a very naive form of TCP reset processing; we just accept
|
||||||
any RST and kill our connection. We should in fact check if the
|
any RST and kill our connection. We should in fact check if the
|
||||||
sequence number of this reset is wihtin our advertised window
|
sequence number of this reset is within our advertised window
|
||||||
before we accept the reset. */
|
before we accept the reset. */
|
||||||
if(BUF->flags & TCP_RST) {
|
if(BUF->flags & TCP_RST) {
|
||||||
uip_connr->tcpstateflags = UIP_CLOSED;
|
uip_connr->tcpstateflags = UIP_CLOSED;
|
||||||
|
@ -1973,6 +1964,4 @@ uip_send(const void *data, int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
|
|
||||||
/** @}*/
|
/** @}*/
|
||||||
|
|
|
@ -29,18 +29,13 @@
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup roll-tm
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* This file implements IPv6 MCAST forwarding according to the
|
* Implementation of the ROLL TM multicast engine
|
||||||
* algorithm described in the "MCAST Forwarding Using Trickle"
|
|
||||||
* internet draft.
|
|
||||||
*
|
|
||||||
* The current version of the draft can always be found in
|
|
||||||
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
|
||||||
*
|
|
||||||
* This implementation is based on the draft version stored in
|
|
||||||
* ROLL_TM_VER
|
|
||||||
*
|
|
||||||
* \author
|
* \author
|
||||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
@ -1440,6 +1435,9 @@ init()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief The ROLL TM engine driver
|
||||||
|
*/
|
||||||
const struct uip_mcast6_driver roll_tm_driver = {
|
const struct uip_mcast6_driver roll_tm_driver = {
|
||||||
"ROLL TM",
|
"ROLL TM",
|
||||||
init,
|
init,
|
||||||
|
@ -1447,3 +1445,4 @@ const struct uip_mcast6_driver roll_tm_driver = {
|
||||||
in,
|
in,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -30,8 +30,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \addtogroup uip6-multicast
|
||||||
* Header file for IPv6 multicast according to the algorithm in the
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \defgroup roll-tm ROLL Trickle Multicast
|
||||||
|
*
|
||||||
|
* IPv6 multicast according to the algorithm in the
|
||||||
* "MCAST Forwarding Using Trickle" internet draft.
|
* "MCAST Forwarding Using Trickle" internet draft.
|
||||||
*
|
*
|
||||||
* The current version of the draft can always be found in
|
* The current version of the draft can always be found in
|
||||||
|
@ -45,7 +50,11 @@
|
||||||
* Due to very significant changes between draft versions 1 and 2,
|
* Due to very significant changes between draft versions 1 and 2,
|
||||||
* MPL will be implemented as a separate engine and this file here
|
* MPL will be implemented as a separate engine and this file here
|
||||||
* will provide legacy support for Draft v1.
|
* will provide legacy support for Draft v1.
|
||||||
*
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Header file for the implementation of the ROLL-TM multicast engine
|
||||||
* \author
|
* \author
|
||||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
@ -60,9 +69,9 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Protocol Constants */
|
/* Protocol Constants */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#define ROLL_TM_VER 1 /* Supported Draft Version */
|
#define ROLL_TM_VER 1 /**< Supported Draft Version */
|
||||||
#define ROLL_TM_ICMP_CODE 0 /* ICMPv6 code field */
|
#define ROLL_TM_ICMP_CODE 0 /**< ROLL TM ICMPv6 code field */
|
||||||
#define ROLL_TM_IP_HOP_LIMIT 0xFF /* Hop limit for ICMP messages */
|
#define ROLL_TM_IP_HOP_LIMIT 0xFF /**< Hop limit for ICMP messages */
|
||||||
#define ROLL_TM_INFINITE_REDUNDANCY 0xFF
|
#define ROLL_TM_INFINITE_REDUNDANCY 0xFF
|
||||||
#define ROLL_TM_DGRAM_OUT 0
|
#define ROLL_TM_DGRAM_OUT 0
|
||||||
#define ROLL_TM_DGRAM_IN 1
|
#define ROLL_TM_DGRAM_IN 1
|
||||||
|
@ -153,7 +162,7 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Configuration */
|
/* Configuration */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/**
|
||||||
* Number of Sliding Windows
|
* Number of Sliding Windows
|
||||||
* In essence: How many unique sources of simultaneous multicast traffic do we
|
* In essence: How many unique sources of simultaneous multicast traffic do we
|
||||||
* want to support for our lowpan
|
* want to support for our lowpan
|
||||||
|
@ -166,7 +175,7 @@
|
||||||
#define ROLL_TM_WINS 2
|
#define ROLL_TM_WINS 2
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/**
|
||||||
* Maximum Number of Buffered Multicast Messages
|
* Maximum Number of Buffered Multicast Messages
|
||||||
* This buffer is shared across all Seed IDs, therefore a new very active Seed
|
* This buffer is shared across all Seed IDs, therefore a new very active Seed
|
||||||
* may eventually occupy all slots. It would make little sense (if any) to
|
* may eventually occupy all slots. It would make little sense (if any) to
|
||||||
|
@ -178,7 +187,7 @@
|
||||||
#define ROLL_TM_BUFF_NUM 6
|
#define ROLL_TM_BUFF_NUM 6
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/**
|
||||||
* Use Short Seed IDs [short: 2, long: 16 (default)]
|
* Use Short Seed IDs [short: 2, long: 16 (default)]
|
||||||
* It can be argued that we should (and it would be easy to) support both at
|
* It can be argued that we should (and it would be easy to) support both at
|
||||||
* the same time but the draft doesn't list this as a MUST so we opt for
|
* the same time but the draft doesn't list this as a MUST so we opt for
|
||||||
|
@ -190,7 +199,7 @@
|
||||||
#define ROLL_TM_SHORT_SEEDS 0
|
#define ROLL_TM_SHORT_SEEDS 0
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/**
|
||||||
* Destination address for our ICMPv6 advertisements. The draft gives us a
|
* Destination address for our ICMPv6 advertisements. The draft gives us a
|
||||||
* choice between LL all-nodes or LL all-routers
|
* choice between LL all-nodes or LL all-routers
|
||||||
*
|
*
|
||||||
|
@ -202,7 +211,7 @@
|
||||||
#define ROLL_TM_DEST_ALL_NODES 0
|
#define ROLL_TM_DEST_ALL_NODES 0
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/*
|
/**
|
||||||
* M param for our outgoing messages
|
* M param for our outgoing messages
|
||||||
* By default, we set the M bit (conservative). Define this as 0 to clear the
|
* By default, we set the M bit (conservative). Define this as 0 to clear the
|
||||||
* M bit in our outgoing messages (aggressive)
|
* M bit in our outgoing messages (aggressive)
|
||||||
|
@ -215,10 +224,21 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Stats datatype */
|
/* Stats datatype */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief Multicast stats extension for the ROLL TM engine
|
||||||
|
*/
|
||||||
struct roll_tm_stats {
|
struct roll_tm_stats {
|
||||||
|
/** Number of received ICMP datagrams */
|
||||||
UIP_MCAST6_STATS_DATATYPE icmp_in;
|
UIP_MCAST6_STATS_DATATYPE icmp_in;
|
||||||
|
|
||||||
|
/** Number of ICMP datagrams sent */
|
||||||
UIP_MCAST6_STATS_DATATYPE icmp_out;
|
UIP_MCAST6_STATS_DATATYPE icmp_out;
|
||||||
|
|
||||||
|
/** Number of malformed ICMP datagrams seen by us */
|
||||||
UIP_MCAST6_STATS_DATATYPE icmp_bad;
|
UIP_MCAST6_STATS_DATATYPE icmp_bad;
|
||||||
};
|
};
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* ROLL_TM_H_ */
|
#endif /* ROLL_TM_H_ */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -29,12 +29,14 @@
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup smrf-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* This file implements 'Stateless Multicast RPL Forwarding' (SMRF)
|
* This file implements 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
*
|
*
|
||||||
* It will only work in RPL networks in MOP 3 "Storing with Multicast"
|
|
||||||
*
|
|
||||||
* \author
|
* \author
|
||||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
@ -199,6 +201,9 @@ out()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief The SMRF engine driver
|
||||||
|
*/
|
||||||
const struct uip_mcast6_driver smrf_driver = {
|
const struct uip_mcast6_driver smrf_driver = {
|
||||||
"SMRF",
|
"SMRF",
|
||||||
init,
|
init,
|
||||||
|
@ -206,3 +211,4 @@ const struct uip_mcast6_driver smrf_driver = {
|
||||||
in,
|
in,
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -29,9 +29,19 @@
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \defgroup smrf-multicast 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
|
*
|
||||||
|
* SMRF will only work in RPL networks in MOP 3 "Storing with Multicast"
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Header file for 'Stateless Multicast RPL Forwarding' (SMRF)
|
* Header file for the SMRF forwarding engine
|
||||||
*
|
*
|
||||||
* \author
|
* \author
|
||||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
@ -71,5 +81,8 @@ struct smrf_stats {
|
||||||
uint16_t mcast_bad;
|
uint16_t mcast_bad;
|
||||||
uint16_t mcast_dropped;
|
uint16_t mcast_dropped;
|
||||||
};
|
};
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* SMRF_H_ */
|
#endif /* SMRF_H_ */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Header file with definition of multicast engine constants
|
* Header file with definition of multicast engine constants
|
||||||
|
@ -43,8 +47,9 @@
|
||||||
#ifndef UIP_MCAST6_ENGINES_H_
|
#ifndef UIP_MCAST6_ENGINES_H_
|
||||||
#define UIP_MCAST6_ENGINES_H_
|
#define UIP_MCAST6_ENGINES_H_
|
||||||
|
|
||||||
#define UIP_MCAST6_ENGINE_NONE 0 /* Selecting this disables mcast */
|
#define UIP_MCAST6_ENGINE_NONE 0 /**< Selecting this disables mcast */
|
||||||
#define UIP_MCAST6_ENGINE_SMRF 1
|
#define UIP_MCAST6_ENGINE_SMRF 1 /**< The SMRF engine */
|
||||||
#define UIP_MCAST6_ENGINE_ROLL_TM 2
|
#define UIP_MCAST6_ENGINE_ROLL_TM 2 /**< The ROLL TM engine */
|
||||||
|
|
||||||
#endif /* UIP_MCAST6_ENGINES_H_ */
|
#endif /* UIP_MCAST6_ENGINES_H_ */
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -28,6 +28,10 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Multicast routing table manipulation
|
* Multicast routing table manipulation
|
||||||
|
@ -128,3 +132,4 @@ uip_mcast6_route_init()
|
||||||
list_init(mcast_route_list);
|
list_init(mcast_route_list);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -28,9 +28,13 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Multicast routing table manipulation
|
* Header file for multicast routing table manipulation
|
||||||
*
|
*
|
||||||
* \author
|
* \author
|
||||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
|
@ -45,18 +49,48 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \brief An entry in the multicast routing table */
|
/** \brief An entry in the multicast routing table */
|
||||||
typedef struct uip_mcast6_route {
|
typedef struct uip_mcast6_route {
|
||||||
struct uip_mcast6_route *next;
|
struct uip_mcast6_route *next; /**< Routes are arranged in a linked list */
|
||||||
uip_ipaddr_t group;
|
uip_ipaddr_t group; /**< The multicast group */
|
||||||
uint32_t lifetime; /* seconds */
|
uint32_t lifetime; /**< Entry lifetime seconds */
|
||||||
void *dag; /* Pointer to an rpl_dag_t struct */
|
void *dag; /**< Pointer to an rpl_dag_t struct */
|
||||||
} uip_mcast6_route_t;
|
} uip_mcast6_route_t;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name Multicast Routing Table Manipulation */
|
/** \name Multicast Routing Table Manipulation */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Lookup a multicast route
|
||||||
|
* \param group A pointer to the multicast group to be searched for
|
||||||
|
* \return A pointer to the new routing entry, or NULL if the route could not
|
||||||
|
* be found
|
||||||
|
*/
|
||||||
uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group);
|
uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Add a multicast route
|
||||||
|
* \param group A pointer to the multicast group to be added
|
||||||
|
* \return A pointer to the new route, or NULL if the route could not be added
|
||||||
|
*/
|
||||||
uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group);
|
uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group);
|
||||||
void uip_mcast6_route_rm(uip_mcast6_route_t *defrt);
|
|
||||||
|
/**
|
||||||
|
* \brief Remove a multicast route
|
||||||
|
* \param route A pointer to the route to be removed
|
||||||
|
*/
|
||||||
|
void uip_mcast6_route_rm(uip_mcast6_route_t *route);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieve the count of multicast routes
|
||||||
|
* \return The number of multicast routes
|
||||||
|
*/
|
||||||
int uip_mcast6_route_count(void);
|
int uip_mcast6_route_count(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieve a pointer to the start of the multicast routes list
|
||||||
|
* \return A pointer to the start of the multicast routes
|
||||||
|
*
|
||||||
|
* If the multicast routes list is empty, this function will return NULL
|
||||||
|
*/
|
||||||
uip_mcast6_route_t *uip_mcast6_route_list_head(void);
|
uip_mcast6_route_t *uip_mcast6_route_list_head(void);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
|
@ -73,3 +107,4 @@ void uip_mcast6_route_init(void);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* UIP_MCAST6_ROUTE_H_ */
|
#endif /* UIP_MCAST6_ROUTE_H_ */
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* IPv6 multicast forwarding stats maintenance
|
* IPv6 multicast forwarding stats maintenance
|
||||||
|
@ -47,3 +51,4 @@ uip_mcast6_stats_init(void *stats)
|
||||||
uip_mcast6_stats.engine_stats = stats;
|
uip_mcast6_stats.engine_stats = stats;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6-multicast
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Header file for IPv6 multicast forwarding stats maintenance
|
* Header file for IPv6 multicast forwarding stats maintenance
|
||||||
|
@ -56,15 +60,35 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Stats datatype */
|
/* Stats datatype */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \brief A data structure used to maintain multicast stats
|
||||||
|
*
|
||||||
|
* Each engine can extend this structure via the engine_stats field
|
||||||
|
*/
|
||||||
typedef struct uip_mcast6_stats {
|
typedef struct uip_mcast6_stats {
|
||||||
|
/** Count of unique datagrams received */
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_in_unique;
|
UIP_MCAST6_STATS_DATATYPE mcast_in_unique;
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_in_all; /* At layer 3 */
|
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_in_ours; /* Unique and we are a group member */
|
/** Count of all datagrams received */
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_fwd; /* Forwarded by us but we are not the seed */
|
UIP_MCAST6_STATS_DATATYPE mcast_in_all;
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_out; /* We are the seed */
|
|
||||||
|
/** Count of datagrams received for a group that we have joined */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_in_ours;
|
||||||
|
|
||||||
|
/** Count of datagrams forwarded by us but we are not the seed */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_fwd;
|
||||||
|
|
||||||
|
/** Count of multicast datagrams originated by us */
|
||||||
|
UIP_MCAST6_STATS_DATATYPE mcast_out;
|
||||||
|
|
||||||
|
/** Count of malformed multicast datagrams seen by us */
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_bad;
|
UIP_MCAST6_STATS_DATATYPE mcast_bad;
|
||||||
|
|
||||||
|
/** Count of multicast datagrams correclty formed but dropped by us */
|
||||||
UIP_MCAST6_STATS_DATATYPE mcast_dropped;
|
UIP_MCAST6_STATS_DATATYPE mcast_dropped;
|
||||||
void *engine_stats; /* Opaque pointer to an engine's additional stats */
|
|
||||||
|
/** Opaque pointer to an engine's additional stats */
|
||||||
|
void *engine_stats;
|
||||||
} uip_mcast6_stats_t;
|
} uip_mcast6_stats_t;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Access macros */
|
/* Access macros */
|
||||||
|
@ -89,3 +113,5 @@ extern uip_mcast6_stats_t uip_mcast6_stats;
|
||||||
void uip_mcast6_stats_init(void *stats);
|
void uip_mcast6_stats_init(void *stats);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#endif /* UIP_MCAST6_STATS_H_ */
|
#endif /* UIP_MCAST6_STATS_H_ */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -30,9 +30,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \addtogroup uip6
|
||||||
* This header file contains configuration directives for uIPv6
|
* @{
|
||||||
* multicast support.
|
*/
|
||||||
|
/**
|
||||||
|
* \defgroup uip6-multicast IPv6 Multicast Forwarding
|
||||||
*
|
*
|
||||||
* We currently support 2 engines:
|
* We currently support 2 engines:
|
||||||
* - 'Stateless Multicast RPL Forwarding' (SMRF)
|
* - 'Stateless Multicast RPL Forwarding' (SMRF)
|
||||||
|
@ -42,6 +44,14 @@
|
||||||
* in the internet draft:
|
* in the internet draft:
|
||||||
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
|
||||||
*
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* This header file contains configuration directives for uIPv6
|
||||||
|
* multicast support.
|
||||||
|
*
|
||||||
* \author
|
* \author
|
||||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||||
*/
|
*/
|
||||||
|
@ -83,7 +93,11 @@
|
||||||
* Multicast API. Similar to NETSTACK, each engine must define a driver and
|
* Multicast API. Similar to NETSTACK, each engine must define a driver and
|
||||||
* populate the fields with suitable function pointers
|
* populate the fields with suitable function pointers
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \brief The data structure used to represent a multicast engine
|
||||||
|
*/
|
||||||
struct uip_mcast6_driver {
|
struct uip_mcast6_driver {
|
||||||
|
/** The driver's name */
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
/** Initialize the multicast engine */
|
/** Initialize the multicast engine */
|
||||||
|
@ -110,6 +124,7 @@ struct uip_mcast6_driver {
|
||||||
*
|
*
|
||||||
* \return 0: Drop, 1: Deliver
|
* \return 0: Drop, 1: Deliver
|
||||||
*
|
*
|
||||||
|
*
|
||||||
* When a datagram with a multicast destination address is received,
|
* When a datagram with a multicast destination address is received,
|
||||||
* the forwarding logic in core is bypassed. Instead, we let the
|
* the forwarding logic in core is bypassed. Instead, we let the
|
||||||
* multicast engine handle forwarding internally if and as necessary.
|
* multicast engine handle forwarding internally if and as necessary.
|
||||||
|
@ -158,5 +173,7 @@ extern const struct uip_mcast6_driver UIP_MCAST6;
|
||||||
#error "Check the value of UIP_CONF_IPV6_RPL in conf files."
|
#error "Check the value of UIP_CONF_IPV6_RPL in conf files."
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#endif /* UIP_MCAST6_H_ */
|
#endif /* UIP_MCAST6_H_ */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -234,7 +234,7 @@ struct sicslowpan_addr_context {
|
||||||
* \brief check whether we can compress the IID in
|
* \brief check whether we can compress the IID in
|
||||||
* address 'a' to 16 bits.
|
* address 'a' to 16 bits.
|
||||||
* This is used for unicast addresses only, and is true
|
* This is used for unicast addresses only, and is true
|
||||||
* if the address is on the format <PREFIX>::0000:00ff:fe00:XXXX
|
* if the address is on the format \<PREFIX\>::0000:00ff:fe00:XXXX
|
||||||
* NOTE: we currently assume 64-bits prefixes
|
* NOTE: we currently assume 64-bits prefixes
|
||||||
*/
|
*/
|
||||||
#define sicslowpan_is_iid_16_bit_compressable(a) \
|
#define sicslowpan_is_iid_16_bit_compressable(a) \
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
||||||
|
@ -38,11 +43,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uip6
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
|
||||||
|
@ -38,11 +43,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uip6
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UIP_DS6_NEIGHBOR_H_
|
#ifndef UIP_DS6_NEIGHBOR_H_
|
||||||
#define UIP_DS6_NEIGHBOR_H_
|
#define UIP_DS6_NEIGHBOR_H_
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ typedef struct uip_ds6_nbr {
|
||||||
uint8_t nscount;
|
uint8_t nscount;
|
||||||
uint8_t isrouter;
|
uint8_t isrouter;
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
|
uint16_t link_metric;
|
||||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||||
struct uip_packetqueue_handle packethandle;
|
struct uip_packetqueue_handle packethandle;
|
||||||
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
|
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
|
||||||
|
|
|
@ -29,6 +29,15 @@
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Routing table manipulation
|
||||||
|
*/
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
|
|
||||||
|
@ -269,9 +278,16 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
|
||||||
one first. */
|
one first. */
|
||||||
r = uip_ds6_route_lookup(ipaddr);
|
r = uip_ds6_route_lookup(ipaddr);
|
||||||
if(r != NULL) {
|
if(r != NULL) {
|
||||||
|
uip_ipaddr_t *current_nexthop;
|
||||||
|
current_nexthop = uip_ds6_route_nexthop(r);
|
||||||
|
if(uip_ipaddr_cmp(nexthop, current_nexthop)) {
|
||||||
|
/* no need to update route - already correct! */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
PRINTF("uip_ds6_route_add: old route for ");
|
PRINTF("uip_ds6_route_add: old route for ");
|
||||||
PRINT6ADDR(ipaddr);
|
PRINT6ADDR(ipaddr);
|
||||||
PRINTF(" found, deleting it\n");
|
PRINTF(" found, deleting it\n");
|
||||||
|
|
||||||
uip_ds6_route_rm(r);
|
uip_ds6_route_rm(r);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -629,3 +645,4 @@ uip_ds6_defrt_periodic(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -29,6 +29,14 @@
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Header file for routing table manipulation
|
||||||
|
*/
|
||||||
#ifndef UIP_DS6_ROUTE_H
|
#ifndef UIP_DS6_ROUTE_H
|
||||||
#define UIP_DS6_ROUTE_H
|
#define UIP_DS6_ROUTE_H
|
||||||
|
|
||||||
|
@ -158,3 +166,4 @@ uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* UIP_DS6_ROUTE_H */
|
#endif /* UIP_DS6_ROUTE_H */
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -28,20 +28,20 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* IPv6 data structures handling functions.
|
* IPv6 data structure manipulation.
|
||||||
* Comprises part of the Neighbor discovery (RFC 4861)
|
* Comprises part of the Neighbor discovery (RFC 4861)
|
||||||
* and auto configuration (RFC 4862) state machines.
|
* and auto configuration (RFC 4862) state machines.
|
||||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||||
* \author Julien Abeille <jabeille@cisco.com>
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uip6
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Network interface and stateless autoconfiguration (RFC 4862)
|
* Header file for IPv6-related data structures
|
||||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||||
* \author Julien Abeille <jabeille@cisco.com>
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,15 +31,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \addtogroup uip6
|
||||||
* ICMPv6 echo request and error messages (RFC 4443)
|
* @{
|
||||||
* \author Julien Abeille <jabeille@cisco.com>
|
|
||||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup uip6
|
* \file
|
||||||
* @{
|
* ICMPv6 (RFC 4443) implementation, with message and error handling
|
||||||
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -31,15 +31,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \addtogroup uip6
|
||||||
* ICMPv6 echo request and error messages (RFC 4443)
|
* @{
|
||||||
* \author Julien Abeille <jabeille@cisco.com>
|
|
||||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup uip6
|
* \file
|
||||||
* @{
|
* Header file for ICMPv6 message and error handing (RFC 4443)
|
||||||
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ICMP6_H_
|
#ifndef ICMP6_H_
|
||||||
|
|
|
@ -56,6 +56,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* Neighbor discovery (RFC 4861)
|
* Neighbor discovery (RFC 4861)
|
||||||
|
@ -63,15 +68,11 @@
|
||||||
* \author Julien Abeille <jabeille@cisco.com>
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uip6
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "net/ipv6/uip-icmp6.h"
|
#include "net/ipv6/uip-icmp6.h"
|
||||||
#include "net/ipv6/uip-nd6.h"
|
#include "net/ipv6/uip-nd6.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
|
#include "net/ip/uip-nameserver.h"
|
||||||
#include "lib/random.h"
|
#include "lib/random.h"
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
@ -112,6 +113,7 @@ void uip_log(char *msg);
|
||||||
#define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
#define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||||
#define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
#define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||||
#define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
#define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||||
|
#define UIP_ND6_OPT_RDNSS_BUF ((uip_nd6_opt_dns *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
static uint8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/
|
static uint8_t nd6_opt_offset; /** Offset from the end of the icmpv6 header to the option in uip_buf*/
|
||||||
|
@ -715,6 +717,29 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
|
||||||
|
|
||||||
uip_len += UIP_ND6_OPT_MTU_LEN;
|
uip_len += UIP_ND6_OPT_MTU_LEN;
|
||||||
nd6_opt_offset += UIP_ND6_OPT_MTU_LEN;
|
nd6_opt_offset += UIP_ND6_OPT_MTU_LEN;
|
||||||
|
|
||||||
|
#if UIP_ND6_RA_RDNSS
|
||||||
|
if(uip_nameserver_count() > 0) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip;
|
||||||
|
uip_ipaddr_t *dns = NULL;
|
||||||
|
UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS;
|
||||||
|
UIP_ND6_OPT_RDNSS_BUF->reserved = 0;
|
||||||
|
UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration();
|
||||||
|
if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
|
||||||
|
UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds();
|
||||||
|
}
|
||||||
|
while((dns = uip_nameserver_get(i)) != NULL) {
|
||||||
|
uip_ipaddr_copy(ip++, dns);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1);
|
||||||
|
PRINTF("%d nameservers reported\n", i);
|
||||||
|
uip_len += UIP_ND6_OPT_RDNSS_BUF->len << 3;
|
||||||
|
nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << 3;
|
||||||
|
}
|
||||||
|
#endif /* UIP_ND6_RA_RDNSS */
|
||||||
|
|
||||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||||
|
|
||||||
|
@ -938,6 +963,23 @@ ra_input(void)
|
||||||
/* End of autonomous flag related processing */
|
/* End of autonomous flag related processing */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#if UIP_ND6_RA_RDNSS
|
||||||
|
case UIP_ND6_OPT_RDNSS:
|
||||||
|
if(UIP_ND6_RA_BUF->flags_reserved & (UIP_ND6_O_FLAG << 6)) {
|
||||||
|
PRINTF("Processing RDNSS option\n");
|
||||||
|
uint8_t naddr = (UIP_ND6_OPT_RDNSS_BUF->len - 1) / 2;
|
||||||
|
uip_ipaddr_t *ip = (uip_ipaddr_t *)(&UIP_ND6_OPT_RDNSS_BUF->ip);
|
||||||
|
PRINTF("got %d nameservers\n", naddr);
|
||||||
|
while(naddr-- > 0) {
|
||||||
|
PRINTF(" nameserver: ");
|
||||||
|
PRINT6ADDR(ip);
|
||||||
|
PRINTF(" lifetime: %lx\n", uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime));
|
||||||
|
uip_nameserver_update(ip, uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime));
|
||||||
|
ip++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* UIP_ND6_RA_RDNSS */
|
||||||
default:
|
default:
|
||||||
PRINTF("ND option not supported in RA");
|
PRINTF("ND option not supported in RA");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,15 +31,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \addtogroup uip6
|
||||||
* Neighbor discovery (RFC 4861)
|
* @{
|
||||||
* \author Julien Abeille <jabeille@cisco.com>
|
|
||||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup uip6
|
* \file
|
||||||
* @{
|
* Header file for IPv6 Neighbor discovery (RFC 4861)
|
||||||
|
* \author Julien Abeille <jabeille@cisco.com>
|
||||||
|
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UIP_ND6_H_
|
#ifndef UIP_ND6_H_
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
#define UIP_ND6_MIN_RA_INTERVAL UIP_CONF_ND6_MIN_RA_INTERVAL
|
#define UIP_ND6_MIN_RA_INTERVAL UIP_CONF_ND6_MIN_RA_INTERVAL
|
||||||
#endif
|
#endif
|
||||||
#define UIP_ND6_M_FLAG 0
|
#define UIP_ND6_M_FLAG 0
|
||||||
#define UIP_ND6_O_FLAG 0
|
#define UIP_ND6_O_FLAG (UIP_ND6_RA_RDNSS || UIP_ND6_RA_DNSSL)
|
||||||
#define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL
|
#define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL
|
||||||
|
|
||||||
#define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/
|
#define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/
|
||||||
|
@ -139,6 +139,23 @@
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
|
/** \name RFC 6106 RA DNS Options Constants */
|
||||||
|
/** @{ */
|
||||||
|
#ifndef UIP_CONF_ND6_RA_RDNSS
|
||||||
|
#define UIP_ND6_RA_RDNSS 0
|
||||||
|
#else
|
||||||
|
#define UIP_ND6_RA_RDNSS UIP_CONF_ND6_RA_RDNSS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UIP_CONF_ND6_RA_DNSSL
|
||||||
|
#define UIP_ND6_RA_DNSSL 0
|
||||||
|
#else
|
||||||
|
#error Not implemented
|
||||||
|
#define UIP_ND6_RA_DNSSL UIP_CONF_ND6_RA_DNSSL
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
/** \name ND6 option types */
|
/** \name ND6 option types */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
#define UIP_ND6_OPT_SLLAO 1
|
#define UIP_ND6_OPT_SLLAO 1
|
||||||
|
@ -146,6 +163,8 @@
|
||||||
#define UIP_ND6_OPT_PREFIX_INFO 3
|
#define UIP_ND6_OPT_PREFIX_INFO 3
|
||||||
#define UIP_ND6_OPT_REDIRECTED_HDR 4
|
#define UIP_ND6_OPT_REDIRECTED_HDR 4
|
||||||
#define UIP_ND6_OPT_MTU 5
|
#define UIP_ND6_OPT_MTU 5
|
||||||
|
#define UIP_ND6_OPT_RDNSS 25
|
||||||
|
#define UIP_ND6_OPT_DNSSL 31
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** \name ND6 option types */
|
/** \name ND6 option types */
|
||||||
|
@ -168,6 +187,8 @@
|
||||||
#define UIP_ND6_OPT_HDR_LEN 2
|
#define UIP_ND6_OPT_HDR_LEN 2
|
||||||
#define UIP_ND6_OPT_PREFIX_INFO_LEN 32
|
#define UIP_ND6_OPT_PREFIX_INFO_LEN 32
|
||||||
#define UIP_ND6_OPT_MTU_LEN 8
|
#define UIP_ND6_OPT_MTU_LEN 8
|
||||||
|
#define UIP_ND6_OPT_RDNSS_LEN 1
|
||||||
|
#define UIP_ND6_OPT_DNSSL_LEN 1
|
||||||
|
|
||||||
|
|
||||||
/* Length of TLLAO and SLLAO options, it is L2 dependant */
|
/* Length of TLLAO and SLLAO options, it is L2 dependant */
|
||||||
|
@ -290,6 +311,15 @@ typedef struct uip_nd6_opt_mtu {
|
||||||
uint32_t mtu;
|
uint32_t mtu;
|
||||||
} uip_nd6_opt_mtu;
|
} uip_nd6_opt_mtu;
|
||||||
|
|
||||||
|
/** \brief ND option RDNSS */
|
||||||
|
typedef struct uip_nd6_opt_dns {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t len;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint32_t lifetime;
|
||||||
|
uip_ipaddr_t ip;
|
||||||
|
} uip_nd6_opt_dns;
|
||||||
|
|
||||||
/** \struct Redirected header option */
|
/** \struct Redirected header option */
|
||||||
typedef struct uip_nd6_opt_redirected_hdr {
|
typedef struct uip_nd6_opt_redirected_hdr {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
|
|
@ -31,6 +31,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \addtogroup uip6
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file
|
* \file
|
||||||
* The uIP TCP/IPv6 stack code.
|
* The uIP TCP/IPv6 stack code.
|
||||||
|
@ -40,11 +45,6 @@
|
||||||
* \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
|
* \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* \addtogroup uip6
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uIP is a small implementation of the IP, UDP and TCP protocols (as
|
* uIP is a small implementation of the IP, UDP and TCP protocols (as
|
||||||
* well as some basic ICMP stuff). The implementation couples the IP,
|
* well as some basic ICMP stuff). The implementation couples the IP,
|
||||||
|
@ -105,7 +105,10 @@ struct uip_stats uip_stat;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @{ \name Layer 2 variables */
|
/**
|
||||||
|
* \name Layer 2 variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** Host L2 address */
|
/** Host L2 address */
|
||||||
#if UIP_CONF_LL_802154
|
#if UIP_CONF_LL_802154
|
||||||
|
@ -116,7 +119,10 @@ uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @{ \name Layer 3 variables */
|
/**
|
||||||
|
* \name Layer 3 variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \brief Type of the next header in IPv6 header or extension headers
|
* \brief Type of the next header in IPv6 header or extension headers
|
||||||
|
@ -141,7 +147,8 @@ uint8_t uip_ext_opt_offset = 0;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Buffers */
|
/* Buffers */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name Buffer defines
|
/**
|
||||||
|
* \name Buffer defines
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
|
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
|
||||||
|
@ -161,7 +168,8 @@ uint8_t uip_ext_opt_offset = 0;
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||||
/** @} */
|
/** @} */
|
||||||
/** \name Buffer variables
|
/**
|
||||||
|
* \name Buffer variables
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Packet buffer for incoming and outgoing packets */
|
/** Packet buffer for incoming and outgoing packets */
|
||||||
|
@ -185,7 +193,10 @@ uint16_t uip_len, uip_slen;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @{ \name General variables */
|
/**
|
||||||
|
* \name General variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* The uip_flags variable is used for communication between the TCP/IP stack
|
/* The uip_flags variable is used for communication between the TCP/IP stack
|
||||||
|
@ -209,7 +220,8 @@ static uint16_t lastport;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* TCP */
|
/* TCP */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name TCP defines
|
/**
|
||||||
|
* \name TCP defines
|
||||||
*@{
|
*@{
|
||||||
*/
|
*/
|
||||||
/* Structures and definitions. */
|
/* Structures and definitions. */
|
||||||
|
@ -227,7 +239,8 @@ static uint16_t lastport;
|
||||||
|
|
||||||
#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
|
#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */
|
||||||
/** @} */
|
/** @} */
|
||||||
/** \name TCP variables
|
/**
|
||||||
|
* \name TCP variables
|
||||||
*@{
|
*@{
|
||||||
*/
|
*/
|
||||||
#if UIP_TCP
|
#if UIP_TCP
|
||||||
|
@ -248,7 +261,10 @@ static uint16_t tmp16;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @{ \name UDP variables */
|
/**
|
||||||
|
* \name UDP variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
struct uip_udp_conn *uip_udp_conn;
|
struct uip_udp_conn *uip_udp_conn;
|
||||||
|
@ -257,7 +273,10 @@ struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS];
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** @{ \name ICMPv6 variables */
|
/**
|
||||||
|
* \name ICMPv6 variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_CONF_ICMP6
|
#if UIP_CONF_ICMP6
|
||||||
/** single possible icmpv6 "connection" */
|
/** single possible icmpv6 "connection" */
|
||||||
|
|
|
@ -64,12 +64,13 @@ uint32_t anti_replay_get_counter(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initializes the anti-replay information about the sender
|
* \brief Initializes the anti-replay information about the sender
|
||||||
|
* \param info Anti-replay information about the sender
|
||||||
*/
|
*/
|
||||||
void anti_replay_init_info(struct anti_replay_info *info);
|
void anti_replay_init_info(struct anti_replay_info *info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Checks if received frame was replayed
|
* \brief Checks if received frame was replayed
|
||||||
* \param last_counters Anti-replay information about the sender
|
* \param info Anti-replay information about the sender
|
||||||
* \retval 0 <-> received frame was not replayed
|
* \retval 0 <-> received frame was not replayed
|
||||||
*/
|
*/
|
||||||
int anti_replay_was_replayed(struct anti_replay_info *info);
|
int anti_replay_was_replayed(struct anti_replay_info *info);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup llsec802154
|
* \defgroup llsec802154 Link Layer Security Common Functionality
|
||||||
*
|
*
|
||||||
* Common functionality of 802.15.4-compliant llsec_drivers.
|
* Common functionality of 802.15.4-compliant llsec_drivers.
|
||||||
*
|
*
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup noncoresec
|
* \defgroup noncoresec LLSEC driver using a network-wide key (NONCORESEC)
|
||||||
*
|
*
|
||||||
* Noncompromise-resilient 802.15.4 security
|
* Noncompromise-resilient 802.15.4 security
|
||||||
*
|
*
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup nullsec
|
* \defgroup nullsec LLSEC driver with zero security (NULLSEC)
|
||||||
*
|
*
|
||||||
* Insecure link layer security driver.
|
* Insecure link layer security driver.
|
||||||
*
|
*
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup net 802.15.4 frame creation and parsing
|
* \addtogroup net
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -56,10 +56,10 @@ static uint16_t buflen, bufptr;
|
||||||
static uint8_t hdrptr;
|
static uint8_t hdrptr;
|
||||||
|
|
||||||
/* The declarations below ensure that the packet buffer is aligned on
|
/* The declarations below ensure that the packet buffer is aligned on
|
||||||
an even 16-bit boundary. On some platforms (most notably the
|
an even 32-bit boundary. On some platforms (most notably the
|
||||||
msp430), having apotentially misaligned packet buffer may lead to
|
msp430 or OpenRISC), having a potentially misaligned packet buffer may lead to
|
||||||
problems when accessing 16-bit values. */
|
problems when accessing words. */
|
||||||
static uint16_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE) / 2 + 1];
|
static uint32_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE + 3) / 4];
|
||||||
static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned;
|
static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned;
|
||||||
|
|
||||||
static uint8_t *packetbufptr;
|
static uint8_t *packetbufptr;
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
* The abc module sends packets to all local area neighbors. The abc
|
* The abc module sends packets to all local area neighbors. The abc
|
||||||
* module adds no headers to outgoing packets.
|
* module adds no headers to outgoing packets.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section abc-channels Channels
|
||||||
*
|
*
|
||||||
* The abc module uses 1 channel.
|
* The abc module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -131,6 +131,7 @@ void announcement_remove(struct announcement *a);
|
||||||
* \brief Set the value of an announcement
|
* \brief Set the value of an announcement
|
||||||
* \param a A pointer to a struct announcement that has
|
* \param a A pointer to a struct announcement that has
|
||||||
* previously been registered
|
* previously been registered
|
||||||
|
* \param value The new value
|
||||||
*
|
*
|
||||||
* This function sets the value of an announcement that
|
* This function sets the value of an announcement that
|
||||||
* has previously been registered with
|
* has previously been registered with
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
* announcement. THe module announces the announcements that have been
|
* announcement. THe module announces the announcements that have been
|
||||||
* registered with the \ref rimeannouncement "announcement module".
|
* registered with the \ref rimeannouncement "announcement module".
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section bcast-announce-channels Channels
|
||||||
*
|
*
|
||||||
* The broadcast announcement module uses 1 channel.
|
* The broadcast announcement module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
* either directly or indirectly through any of the other
|
* either directly or indirectly through any of the other
|
||||||
* communication primitives that are based on the broadcast primitive.
|
* communication primitives that are based on the broadcast primitive.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section broadcast-channels Channels
|
||||||
*
|
*
|
||||||
* The broadcast module uses 1 channel.
|
* The broadcast module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
* The collect module implements a hop-by-hop reliable data collection
|
* The collect module implements a hop-by-hop reliable data collection
|
||||||
* mechanism.
|
* mechanism.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section collect-channels Channels
|
||||||
*
|
*
|
||||||
* The collect module uses 2 channels; one for neighbor discovery and one
|
* The collect module uses 2 channels; one for neighbor discovery and one
|
||||||
* for data packets.
|
* for data packets.
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
* The polite broadcast module does not add any packet attributes to
|
* The polite broadcast module does not add any packet attributes to
|
||||||
* outgoing packets apart from those added by the upper layer.
|
* outgoing packets apart from those added by the upper layer.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section ipolite-channels Channels
|
||||||
*
|
*
|
||||||
* The ipolite module uses 1 channel.
|
* The ipolite module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
* receiver somewhere in the network.
|
* receiver somewhere in the network.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section mesh-channels Channels
|
||||||
*
|
*
|
||||||
* The mesh module uses 3 channel; one for the multi-hop forwarding
|
* The mesh module uses 3 channel; one for the multi-hop forwarding
|
||||||
* (\ref rimemultihop "multihop") and two for the route disovery (\ref
|
* (\ref rimemultihop "multihop") and two for the route disovery (\ref
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
* process.
|
* process.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section multihop-channels Channels
|
||||||
*
|
*
|
||||||
* The multihop module uses 1 channel.
|
* The multihop module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
* discovery mechanism. A callback is invoked for every incoming
|
* discovery mechanism. A callback is invoked for every incoming
|
||||||
* neighbor discovery message.
|
* neighbor discovery message.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section neighbor-discovery-channels Channels
|
||||||
*
|
*
|
||||||
* The neighbor-discovery module uses 1 channel.
|
* The neighbor-discovery module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
* If the time to live reaches zero, the primitive does not forward
|
* If the time to live reaches zero, the primitive does not forward
|
||||||
* the packet.
|
* the packet.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section netflood-channels Channels
|
||||||
*
|
*
|
||||||
* The netflood module uses 1 channel.
|
* The netflood module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -78,7 +78,7 @@ struct packetqueue {
|
||||||
* This structure holds the state of a packet queue. It is
|
* This structure holds the state of a packet queue. It is
|
||||||
* an opaque structure with no user-visible elements. The
|
* an opaque structure with no user-visible elements. The
|
||||||
* function packetqueue_queuebuf() is used to extract a
|
* function packetqueue_queuebuf() is used to extract a
|
||||||
* \ref queuebuf "queubuf" from the item. The function
|
* "queubuf" from the item. The function
|
||||||
* packetqueue_ptr() is used to extract the opaque pointer
|
* packetqueue_ptr() is used to extract the opaque pointer
|
||||||
* that was registered with the
|
* that was registered with the
|
||||||
* packetqueue_enqueue_packetbuf() function.
|
* packetqueue_enqueue_packetbuf() function.
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
* announcement. THe module announces the announcements that have been
|
* announcement. THe module announces the announcements that have been
|
||||||
* registered with the \ref rimeannouncement "announcement module".
|
* registered with the \ref rimeannouncement "announcement module".
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section polite-announcement-channels Channels
|
||||||
*
|
*
|
||||||
* The polite announcement module uses 1 channel.
|
* The polite announcement module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
* The polite broadcast module does not add any packet attributes to
|
* The polite broadcast module does not add any packet attributes to
|
||||||
* outgoing packets apart from those added by the upper layer.
|
* outgoing packets apart from those added by the upper layer.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section polite-channels Channels
|
||||||
*
|
*
|
||||||
* The polite module uses 1 channel.
|
* The polite module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
* reliable single-hop primitive for the communication between two
|
* reliable single-hop primitive for the communication between two
|
||||||
* single-hop neighbors.
|
* single-hop neighbors.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section rmh-channels Channels
|
||||||
*
|
*
|
||||||
* The rmh module uses 1 channel.
|
* The rmh module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
*
|
*
|
||||||
* The route-discovery module does route discovery for Rime.
|
* The route-discovery module does route discovery for Rime.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section route-discovery-channels Channels
|
||||||
*
|
*
|
||||||
* The ibc module uses 2 channels; one for the flooded route request
|
* The ibc module uses 2 channels; one for the flooded route request
|
||||||
* packets and one for the unicast route replies.
|
* packets and one for the unicast route replies.
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
* The rudolph0 module implements a single-hop reliable bulk data
|
* The rudolph0 module implements a single-hop reliable bulk data
|
||||||
* transfer mechanism.
|
* transfer mechanism.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section rudolph0-channels Channels
|
||||||
*
|
*
|
||||||
* The rudolph0 module uses 2 channels; one for data packets and one
|
* The rudolph0 module uses 2 channels; one for data packets and one
|
||||||
* for NACK and repair packets.
|
* for NACK and repair packets.
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
* The rudolph1 module implements a multi-hop reliable bulk data
|
* The rudolph1 module implements a multi-hop reliable bulk data
|
||||||
* transfer mechanism.
|
* transfer mechanism.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section rudolph1-channels Channels
|
||||||
*
|
*
|
||||||
* The rudolph1 module uses 2 channels; one for data transmissions and
|
* The rudolph1 module uses 2 channels; one for data transmissions and
|
||||||
* one for NACKs and repair packets.
|
* one for NACKs and repair packets.
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
* The rudolph2 module implements a single-hop reliable bulk data
|
* The rudolph2 module implements a single-hop reliable bulk data
|
||||||
* transfer mechanism.
|
* transfer mechanism.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section rudolph2-channels Channels
|
||||||
*
|
*
|
||||||
* The rudolph2 module uses 2 channels; one for data packets and one
|
* The rudolph2 module uses 2 channels; one for data packets and one
|
||||||
* for NACK and repair packets.
|
* for NACK and repair packets.
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
* callback.
|
* callback.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section runicast-channels Channels
|
||||||
*
|
*
|
||||||
* The runicast module uses 1 channel.
|
* The runicast module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
* either the message is canceled or a new message is sent. Messages
|
* either the message is canceled or a new message is sent. Messages
|
||||||
* sent with the stbroadcast module are not identified with a sender ID.
|
* sent with the stbroadcast module are not identified with a sender ID.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section stbroadcast-channels Channels
|
||||||
*
|
*
|
||||||
* The stbroadcast module uses 1 channel.
|
* The stbroadcast module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
* number of retransmissions for a packet as a packet attribute on
|
* number of retransmissions for a packet as a packet attribute on
|
||||||
* outgoing packets.
|
* outgoing packets.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section stunicast-channels Channels
|
||||||
*
|
*
|
||||||
* The stunicast module uses 1 channel.
|
* The stunicast module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
*
|
*
|
||||||
* The trickle module sends a single packet to all nodes on the network.
|
* The trickle module sends a single packet to all nodes on the network.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section trickle-channels Channels
|
||||||
*
|
*
|
||||||
* The trickle module uses 1 channel.
|
* The trickle module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
* single-hop receiver address attribute and discards the packet if
|
* single-hop receiver address attribute and discards the packet if
|
||||||
* the address does not match the address of the node.
|
* the address does not match the address of the node.
|
||||||
*
|
*
|
||||||
* \section channels Channels
|
* \section unicast-channels Channels
|
||||||
*
|
*
|
||||||
* The unicast module uses 1 channel.
|
* The unicast module uses 1 channel.
|
||||||
*
|
*
|
||||||
|
|
|
@ -195,4 +195,16 @@
|
||||||
#define RPL_PREFERENCE 0
|
#define RPL_PREFERENCE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hop-by-hop option
|
||||||
|
* This option control the insertion of the RPL Hop-by-Hop extension header
|
||||||
|
* into packets originating from this node. Incoming Hop-by-hop extension
|
||||||
|
* header are still processed and forwarded.
|
||||||
|
*/
|
||||||
|
#ifdef RPL_CONF_INSERT_HBH_OPTION
|
||||||
|
#define RPL_INSERT_HBH_OPTION RPL_CONF_INSERT_HBH_OPTION
|
||||||
|
#else
|
||||||
|
#define RPL_INSERT_HBH_OPTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* RPL_CONF_H */
|
#endif /* RPL_CONF_H */
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "net/rpl/rpl-private.h"
|
#include "net/rpl/rpl-private.h"
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ipv6/uip-nd6.h"
|
#include "net/ipv6/uip-nd6.h"
|
||||||
|
#include "net/ipv6/uip-ds6-nbr.h"
|
||||||
#include "net/nbr-table.h"
|
#include "net/nbr-table.h"
|
||||||
#include "net/ipv6/multicast/uip-mcast6.h"
|
#include "net/ipv6/multicast/uip-mcast6.h"
|
||||||
#include "lib/list.h"
|
#include "lib/list.h"
|
||||||
|
@ -79,6 +80,19 @@ NBR_TABLE(rpl_parent_t, rpl_parents);
|
||||||
/* Allocate instance table. */
|
/* Allocate instance table. */
|
||||||
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
rpl_instance_t instance_table[RPL_MAX_INSTANCES];
|
||||||
rpl_instance_t *default_instance;
|
rpl_instance_t *default_instance;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uip_ds6_nbr_t *
|
||||||
|
rpl_get_nbr(rpl_parent_t *parent)
|
||||||
|
{
|
||||||
|
linkaddr_t *lladdr = NULL;
|
||||||
|
lladdr = nbr_table_get_lladdr(rpl_parents, parent);
|
||||||
|
if(lladdr != NULL) {
|
||||||
|
return nbr_table_get_from_lladdr(ds6_neighbors, lladdr);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
nbr_callback(void *ptr)
|
nbr_callback(void *ptr)
|
||||||
|
@ -113,9 +127,11 @@ rpl_get_parent_rank(uip_lladdr_t *addr)
|
||||||
uint16_t
|
uint16_t
|
||||||
rpl_get_parent_link_metric(const uip_lladdr_t *addr)
|
rpl_get_parent_link_metric(const uip_lladdr_t *addr)
|
||||||
{
|
{
|
||||||
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (const linkaddr_t *)addr);
|
uip_ds6_nbr_t *nbr;
|
||||||
if(p != NULL) {
|
nbr = nbr_table_get_from_lladdr(ds6_neighbors, (const linkaddr_t *)addr);
|
||||||
return p->link_metric;
|
|
||||||
|
if(nbr != NULL) {
|
||||||
|
return nbr->link_metric;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -568,10 +584,17 @@ rpl_add_parent(rpl_dag_t *dag, rpl_dio_t *dio, uip_ipaddr_t *addr)
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
PRINTF("RPL: rpl_add_parent p NULL\n");
|
PRINTF("RPL: rpl_add_parent p NULL\n");
|
||||||
} else {
|
} else {
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
|
nbr = rpl_get_nbr(p);
|
||||||
|
|
||||||
p->dag = dag;
|
p->dag = dag;
|
||||||
p->rank = dio->rank;
|
p->rank = dio->rank;
|
||||||
p->dtsn = dio->dtsn;
|
p->dtsn = dio->dtsn;
|
||||||
p->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
|
||||||
|
/* Check whether we have a neighbor that has not gotten a link metric yet */
|
||||||
|
if(nbr != NULL && nbr->link_metric == 0) {
|
||||||
|
nbr->link_metric = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
|
}
|
||||||
#if RPL_DAG_MC != RPL_DAG_MC_NONE
|
#if RPL_DAG_MC != RPL_DAG_MC_NONE
|
||||||
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
memcpy(&p->mc, &dio->mc, sizeof(p->mc));
|
||||||
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
||||||
|
@ -766,7 +789,6 @@ rpl_nullify_parent(rpl_parent_t *parent)
|
||||||
/* This function can be called when the preferred parent is NULL, so we
|
/* This function can be called when the preferred parent is NULL, so we
|
||||||
need to handle this condition in order to trigger uip_ds6_defrt_rm. */
|
need to handle this condition in order to trigger uip_ds6_defrt_rm. */
|
||||||
if(parent == dag->preferred_parent || dag->preferred_parent == NULL) {
|
if(parent == dag->preferred_parent || dag->preferred_parent == NULL) {
|
||||||
rpl_set_preferred_parent(dag, NULL);
|
|
||||||
dag->rank = INFINITE_RANK;
|
dag->rank = INFINITE_RANK;
|
||||||
if(dag->joined) {
|
if(dag->joined) {
|
||||||
if(dag->instance->def_route != NULL) {
|
if(dag->instance->def_route != NULL) {
|
||||||
|
@ -776,7 +798,11 @@ rpl_nullify_parent(rpl_parent_t *parent)
|
||||||
uip_ds6_defrt_rm(dag->instance->def_route);
|
uip_ds6_defrt_rm(dag->instance->def_route);
|
||||||
dag->instance->def_route = NULL;
|
dag->instance->def_route = NULL;
|
||||||
}
|
}
|
||||||
|
/* Send no-path DAO only to preferred parent, if any */
|
||||||
|
if(parent == dag->preferred_parent) {
|
||||||
dao_output(parent, RPL_ZERO_LIFETIME);
|
dao_output(parent, RPL_ZERO_LIFETIME);
|
||||||
|
rpl_set_preferred_parent(dag, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,6 +975,7 @@ rpl_join_instance(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RPL_MAX_DAG_PER_INSTANCE > 1
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
|
@ -1028,6 +1055,7 @@ rpl_add_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
rpl_process_parent_event(instance, p);
|
rpl_process_parent_event(instance, p);
|
||||||
p->dtsn = dio->dtsn;
|
p->dtsn = dio->dtsn;
|
||||||
}
|
}
|
||||||
|
#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
|
@ -1037,6 +1065,14 @@ global_repair(uip_ipaddr_t *from, rpl_dag_t *dag, rpl_dio_t *dio)
|
||||||
|
|
||||||
remove_parents(dag, 0);
|
remove_parents(dag, 0);
|
||||||
dag->version = dio->version;
|
dag->version = dio->version;
|
||||||
|
|
||||||
|
/* copy parts of the configuration so that it propagates in the network */
|
||||||
|
dag->instance->dio_intdoubl = dio->dag_intdoubl;
|
||||||
|
dag->instance->dio_intmin = dio->dag_intmin;
|
||||||
|
dag->instance->dio_redundancy = dio->dag_redund;
|
||||||
|
dag->instance->default_lifetime = dio->default_lifetime;
|
||||||
|
dag->instance->lifetime_unit = dio->lifetime_unit;
|
||||||
|
|
||||||
dag->instance->of->reset(dag);
|
dag->instance->of->reset(dag);
|
||||||
dag->min_rank = INFINITE_RANK;
|
dag->min_rank = INFINITE_RANK;
|
||||||
RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out);
|
RPL_LOLLIPOP_INCREMENT(dag->instance->dtsn_out);
|
||||||
|
@ -1215,9 +1251,14 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dag == NULL) {
|
if(dag == NULL) {
|
||||||
|
#if RPL_MAX_DAG_PER_INSTANCE > 1
|
||||||
PRINTF("RPL: Adding new DAG to known instance.\n");
|
PRINTF("RPL: Adding new DAG to known instance.\n");
|
||||||
rpl_add_dag(from, dio);
|
rpl_add_dag(from, dio);
|
||||||
return;
|
return;
|
||||||
|
#else /* RPL_MAX_DAG_PER_INSTANCE > 1 */
|
||||||
|
PRINTF("RPL: Only one instance supported.\n");
|
||||||
|
return;
|
||||||
|
#endif /* RPL_MAX_DAG_PER_INSTANCE > 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,7 @@ rpl_update_header_empty(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#if RPL_INSERT_HBH_OPTION
|
||||||
PRINTF("RPL: No hop-by-hop option found, creating it\n");
|
PRINTF("RPL: No hop-by-hop option found, creating it\n");
|
||||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
|
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE) {
|
||||||
PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n");
|
PRINTF("RPL: Packet too long: impossible to add hop-by-hop option\n");
|
||||||
|
@ -223,6 +224,7 @@ rpl_update_header_empty(void)
|
||||||
}
|
}
|
||||||
set_rpl_opt(uip_ext_opt_offset);
|
set_rpl_opt(uip_ext_opt_offset);
|
||||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,9 +376,11 @@ rpl_invert_header(void)
|
||||||
void
|
void
|
||||||
rpl_insert_header(void)
|
rpl_insert_header(void)
|
||||||
{
|
{
|
||||||
|
#if RPL_INSERT_HBH_OPTION
|
||||||
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
if(default_instance != NULL && !uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||||
rpl_update_header_empty();
|
rpl_update_header_empty();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#define RPL_DIO_GROUNDED 0x80
|
#define RPL_DIO_GROUNDED 0x80
|
||||||
#define RPL_DIO_MOP_SHIFT 3
|
#define RPL_DIO_MOP_SHIFT 3
|
||||||
#define RPL_DIO_MOP_MASK 0x3c
|
#define RPL_DIO_MOP_MASK 0x38
|
||||||
#define RPL_DIO_PREFERENCE_MASK 0x07
|
#define RPL_DIO_PREFERENCE_MASK 0x07
|
||||||
|
|
||||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
@ -778,6 +778,7 @@ dao_input(void)
|
||||||
|
|
||||||
rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
|
rep->state.lifetime = RPL_LIFETIME(instance, lifetime);
|
||||||
rep->state.learned_from = learned_from;
|
rep->state.learned_from = learned_from;
|
||||||
|
rep->state.nopath_received = 0;
|
||||||
|
|
||||||
#if RPL_CONF_MULTICAST
|
#if RPL_CONF_MULTICAST
|
||||||
fwd_dao:
|
fwd_dao:
|
||||||
|
|
|
@ -90,16 +90,22 @@ typedef uint16_t rpl_path_metric_t;
|
||||||
static rpl_path_metric_t
|
static rpl_path_metric_t
|
||||||
calculate_path_metric(rpl_parent_t *p)
|
calculate_path_metric(rpl_parent_t *p)
|
||||||
{
|
{
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
}
|
}
|
||||||
|
nbr = rpl_get_nbr(p);
|
||||||
|
if(nbr == NULL) {
|
||||||
|
return MAX_PATH_COST * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
|
}
|
||||||
#if RPL_DAG_MC == RPL_DAG_MC_NONE
|
#if RPL_DAG_MC == RPL_DAG_MC_NONE
|
||||||
return p->rank + (uint16_t)p->link_metric;
|
{
|
||||||
|
return p->rank + (uint16_t)nbr->link_metric;
|
||||||
|
}
|
||||||
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
|
#elif RPL_DAG_MC == RPL_DAG_MC_ETX
|
||||||
return p->mc.obj.etx + (uint16_t)p->link_metric;
|
return p->mc.obj.etx + (uint16_t)nbr->link_metric;
|
||||||
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
|
#elif RPL_DAG_MC == RPL_DAG_MC_ENERGY
|
||||||
return p->mc.obj.energy.energy_est + (uint16_t)p->link_metric;
|
return p->mc.obj.energy.energy_est + (uint16_t)nbr->link_metric;
|
||||||
#else
|
#else
|
||||||
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
|
#error "Unsupported RPL_DAG_MC configured. See rpl.h."
|
||||||
#endif /* RPL_DAG_MC */
|
#endif /* RPL_DAG_MC */
|
||||||
|
@ -114,9 +120,18 @@ reset(rpl_dag_t *dag)
|
||||||
static void
|
static void
|
||||||
neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
|
neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
|
||||||
{
|
{
|
||||||
uint16_t recorded_etx = p->link_metric;
|
uint16_t recorded_etx = 0;
|
||||||
uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
|
uint16_t packet_etx = numtx * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
uint16_t new_etx;
|
uint16_t new_etx;
|
||||||
|
uip_ds6_nbr_t *nbr = NULL;
|
||||||
|
|
||||||
|
nbr = rpl_get_nbr(p);
|
||||||
|
if(nbr == NULL) {
|
||||||
|
/* No neighbor for this parent - something bad has occurred */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
recorded_etx = nbr->link_metric;
|
||||||
|
|
||||||
/* Do not penalize the ETX when collisions or transmission errors occur. */
|
/* Do not penalize the ETX when collisions or transmission errors occur. */
|
||||||
if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
|
if(status == MAC_TX_OK || status == MAC_TX_NOACK) {
|
||||||
|
@ -139,7 +154,8 @@ neighbor_link_callback(rpl_parent_t *p, int status, int numtx)
|
||||||
(unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
|
(unsigned)(recorded_etx / RPL_DAG_MC_ETX_DIVISOR),
|
||||||
(unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
|
(unsigned)(new_etx / RPL_DAG_MC_ETX_DIVISOR),
|
||||||
(unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR));
|
(unsigned)(packet_etx / RPL_DAG_MC_ETX_DIVISOR));
|
||||||
p->link_metric = new_etx;
|
/* update the link metric for this nbr */
|
||||||
|
nbr->link_metric = new_etx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,14 +164,15 @@ calculate_rank(rpl_parent_t *p, rpl_rank_t base_rank)
|
||||||
{
|
{
|
||||||
rpl_rank_t new_rank;
|
rpl_rank_t new_rank;
|
||||||
rpl_rank_t rank_increase;
|
rpl_rank_t rank_increase;
|
||||||
|
uip_ds6_nbr_t *nbr;
|
||||||
|
|
||||||
if(p == NULL) {
|
if(p == NULL || (nbr = rpl_get_nbr(p)) == NULL) {
|
||||||
if(base_rank == 0) {
|
if(base_rank == 0) {
|
||||||
return INFINITE_RANK;
|
return INFINITE_RANK;
|
||||||
}
|
}
|
||||||
rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
rank_increase = RPL_INIT_LINK_METRIC * RPL_DAG_MC_ETX_DIVISOR;
|
||||||
} else {
|
} else {
|
||||||
rank_increase = p->link_metric;
|
rank_increase = nbr->link_metric;
|
||||||
if(base_rank == 0) {
|
if(base_rank == 0) {
|
||||||
base_rank = p->rank;
|
base_rank = p->rank;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,25 +127,33 @@ best_parent(rpl_parent_t *p1, rpl_parent_t *p2)
|
||||||
{
|
{
|
||||||
rpl_rank_t r1, r2;
|
rpl_rank_t r1, r2;
|
||||||
rpl_dag_t *dag;
|
rpl_dag_t *dag;
|
||||||
|
uip_ds6_nbr_t *nbr1, *nbr2;
|
||||||
|
nbr1 = rpl_get_nbr(p1);
|
||||||
|
nbr2 = rpl_get_nbr(p2);
|
||||||
|
|
||||||
|
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
|
||||||
|
|
||||||
|
if(nbr1 == NULL || nbr2 == NULL) {
|
||||||
|
return dag->preferred_parent;
|
||||||
|
}
|
||||||
|
|
||||||
PRINTF("RPL: Comparing parent ");
|
PRINTF("RPL: Comparing parent ");
|
||||||
PRINT6ADDR(rpl_get_parent_ipaddr(p1));
|
PRINT6ADDR(rpl_get_parent_ipaddr(p1));
|
||||||
PRINTF(" (confidence %d, rank %d) with parent ",
|
PRINTF(" (confidence %d, rank %d) with parent ",
|
||||||
p1->link_metric, p1->rank);
|
nbr1->link_metric, p1->rank);
|
||||||
PRINT6ADDR(rpl_get_parent_ipaddr(p2));
|
PRINT6ADDR(rpl_get_parent_ipaddr(p2));
|
||||||
PRINTF(" (confidence %d, rank %d)\n",
|
PRINTF(" (confidence %d, rank %d)\n",
|
||||||
p2->link_metric, p2->rank);
|
nbr2->link_metric, p2->rank);
|
||||||
|
|
||||||
|
|
||||||
r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
r1 = DAG_RANK(p1->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
||||||
p1->link_metric;
|
nbr1->link_metric;
|
||||||
r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
r2 = DAG_RANK(p2->rank, p1->dag->instance) * RPL_MIN_HOPRANKINC +
|
||||||
p2->link_metric;
|
nbr2->link_metric;
|
||||||
/* Compare two parents by looking both and their rank and at the ETX
|
/* Compare two parents by looking both and their rank and at the ETX
|
||||||
for that parent. We choose the parent that has the most
|
for that parent. We choose the parent that has the most
|
||||||
favourable combination. */
|
favourable combination. */
|
||||||
|
|
||||||
dag = (rpl_dag_t *)p1->dag; /* Both parents must be in the same DAG. */
|
|
||||||
if(r1 < r2 + MIN_DIFFERENCE &&
|
if(r1 < r2 + MIN_DIFFERENCE &&
|
||||||
r1 > r2 - MIN_DIFFERENCE) {
|
r1 > r2 - MIN_DIFFERENCE) {
|
||||||
return dag->preferred_parent;
|
return dag->preferred_parent;
|
||||||
|
|
|
@ -145,7 +145,7 @@ handle_dio_timer(void *ptr)
|
||||||
|
|
||||||
if(instance->dio_send) {
|
if(instance->dio_send) {
|
||||||
/* send DIO if counter is less than desired redundancy */
|
/* send DIO if counter is less than desired redundancy */
|
||||||
if(instance->dio_counter < instance->dio_redundancy) {
|
if(instance->dio_redundancy != 0 && instance->dio_counter < instance->dio_redundancy) {
|
||||||
#if RPL_CONF_STATS
|
#if RPL_CONF_STATS
|
||||||
instance->dio_totsend++;
|
instance->dio_totsend++;
|
||||||
#endif /* RPL_CONF_STATS */
|
#endif /* RPL_CONF_STATS */
|
||||||
|
|
|
@ -76,9 +76,9 @@ rpl_set_mode(enum rpl_mode m)
|
||||||
switching to. */
|
switching to. */
|
||||||
if(m == RPL_MODE_MESH) {
|
if(m == RPL_MODE_MESH) {
|
||||||
|
|
||||||
/* If we switcht to mesh mode, we should send out a DAO message to
|
/* If we switch to mesh mode, we should send out a DAO message to
|
||||||
inform our parent that we now are reachable. Before we do this,
|
inform our parent that we now are reachable. Before we do this,
|
||||||
we must set the mode variable, since DAOs will not be send if
|
we must set the mode variable, since DAOs will not be sent if
|
||||||
we are in feather mode. */
|
we are in feather mode. */
|
||||||
PRINTF("RPL: switching to mesh mode\n");
|
PRINTF("RPL: switching to mesh mode\n");
|
||||||
mode = m;
|
mode = m;
|
||||||
|
|
|
@ -114,7 +114,6 @@ struct rpl_parent {
|
||||||
rpl_metric_container_t mc;
|
rpl_metric_container_t mc;
|
||||||
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
#endif /* RPL_DAG_MC != RPL_DAG_MC_NONE */
|
||||||
rpl_rank_t rank;
|
rpl_rank_t rank;
|
||||||
uint16_t link_metric;
|
|
||||||
uint8_t dtsn;
|
uint8_t dtsn;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
|
@ -251,7 +250,7 @@ rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
|
||||||
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
||||||
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
uint16_t rpl_get_parent_link_metric(const uip_lladdr_t *addr);
|
||||||
void rpl_dag_init(void);
|
void rpl_dag_init(void);
|
||||||
|
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RPL modes
|
* RPL modes
|
||||||
|
|
|
@ -133,7 +133,7 @@
|
||||||
* strings.
|
* strings.
|
||||||
*
|
*
|
||||||
* We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow
|
* We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow
|
||||||
* concatenation of two #defined macros.
|
* concatenation of two \#defined macros.
|
||||||
*/
|
*/
|
||||||
#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2)
|
#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2)
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
*
|
*
|
||||||
* \note The clock library need in many cases not be used
|
* \note The clock library need in many cases not be used
|
||||||
* directly. Rather, the \ref timer "timer library", \ref etimer
|
* directly. Rather, the \ref timer "timer library", \ref etimer
|
||||||
* "event timers", or \ref trimer "rtimer library" should be used.
|
* "event timers", or \ref rtimer "rtimer library" should be used.
|
||||||
*
|
*
|
||||||
* \sa \ref timer "Timer library"
|
* \sa \ref timer "Timer library"
|
||||||
* \sa \ref etimer "Event timers"
|
* \sa \ref etimer "Event timers"
|
||||||
|
|
|
@ -105,7 +105,7 @@ struct dsc {
|
||||||
*
|
*
|
||||||
* \param prgname The name of the program on disk.
|
* \param prgname The name of the program on disk.
|
||||||
*
|
*
|
||||||
* \param initfunc A pointer to the initialization function of the
|
* \param process A pointer to the initialization function of the
|
||||||
* program.
|
* program.
|
||||||
*
|
*
|
||||||
* \param icon A pointer to the CTK icon.
|
* \param icon A pointer to the CTK icon.
|
||||||
|
|
|
@ -267,7 +267,7 @@ do_event(void)
|
||||||
receiver = events[fevent].p;
|
receiver = events[fevent].p;
|
||||||
|
|
||||||
/* Since we have seen the new event, we move pointer upwards
|
/* Since we have seen the new event, we move pointer upwards
|
||||||
and decrese the number of events. */
|
and decrease the number of events. */
|
||||||
fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS;
|
fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS;
|
||||||
--nevents;
|
--nevents;
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ process_post(struct process *p, process_event_t ev, process_data_t data)
|
||||||
if(p == PROCESS_BROADCAST) {
|
if(p == PROCESS_BROADCAST) {
|
||||||
printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current));
|
printf("soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current));
|
||||||
} else {
|
} else {
|
||||||
printf("soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current));
|
printf("soft panic: event queue is full when event %d was posted to %s from %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current));
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
return PROCESS_ERR_FULL;
|
return PROCESS_ERR_FULL;
|
||||||
|
|
|
@ -335,7 +335,7 @@ struct process {
|
||||||
*
|
*
|
||||||
* \param p A pointer to a process structure.
|
* \param p A pointer to a process structure.
|
||||||
*
|
*
|
||||||
* \param arg An argument pointer that can be passed to the new
|
* \param data An argument pointer that can be passed to the new
|
||||||
* process
|
* process
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -76,8 +76,9 @@ timer_set(struct timer *t, clock_time_t interval)
|
||||||
* function will cause the timer to be stable over time, unlike the
|
* function will cause the timer to be stable over time, unlike the
|
||||||
* timer_restart() function.
|
* timer_restart() function.
|
||||||
*
|
*
|
||||||
* \param t A pointer to the timer.
|
* \note Must not be executed before timer expired
|
||||||
*
|
*
|
||||||
|
* \param t A pointer to the timer.
|
||||||
* \sa timer_restart()
|
* \sa timer_restart()
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
|
|
@ -117,7 +117,7 @@ makestrings(void)
|
||||||
makeaddr(&addr, gateway);
|
makeaddr(&addr, gateway);
|
||||||
|
|
||||||
#if WITH_DNS
|
#if WITH_DNS
|
||||||
addrptr = resolv_getserver();
|
addrptr = uip_nameserver_get(0);
|
||||||
if(addrptr != NULL) {
|
if(addrptr != NULL) {
|
||||||
makeaddr(addrptr, dnsserver);
|
makeaddr(addrptr, dnsserver);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ dhcpc_configured(const struct dhcpc_state *s)
|
||||||
uip_setnetmask(&s->netmask);
|
uip_setnetmask(&s->netmask);
|
||||||
uip_setdraddr(&s->default_router);
|
uip_setdraddr(&s->default_router);
|
||||||
#if WITH_DNS
|
#if WITH_DNS
|
||||||
resolv_conf(&s->dnsaddr);
|
uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME);
|
||||||
#endif /* WITH_DNS */
|
#endif /* WITH_DNS */
|
||||||
|
|
||||||
set_statustext("Configured.");
|
set_statustext("Configured.");
|
||||||
|
@ -261,7 +261,7 @@ dhcpc_unconfigured(const struct dhcpc_state *s)
|
||||||
uip_setnetmask(&nulladdr);
|
uip_setnetmask(&nulladdr);
|
||||||
uip_setdraddr(&nulladdr);
|
uip_setdraddr(&nulladdr);
|
||||||
#if WITH_DNS
|
#if WITH_DNS
|
||||||
resolv_conf(&nulladdr);
|
uip_nameserver_update(&nulladdr, UIP_NAMESERVER_INFINITE_LIFETIME);
|
||||||
#endif /* WITH_DNS */
|
#endif /* WITH_DNS */
|
||||||
|
|
||||||
set_statustext("Unconfigured.");
|
set_statustext("Unconfigured.");
|
||||||
|
|
|
@ -105,7 +105,7 @@ config_read(char *filename)
|
||||||
uip_setnetmask(&config.netmask);
|
uip_setnetmask(&config.netmask);
|
||||||
uip_setdraddr(&config.draddr);
|
uip_setdraddr(&config.draddr);
|
||||||
#if WITH_DNS
|
#if WITH_DNS
|
||||||
resolv_conf(&config.resolvaddr);
|
uip_nameserver_update(&config.resolvaddr, UIP_NAMESERVER_INFINITE_LIFETIME);
|
||||||
#endif /* WITH_DNS */
|
#endif /* WITH_DNS */
|
||||||
|
|
||||||
return &config.ethernetcfg;
|
return &config.ethernetcfg;
|
||||||
|
|
|
@ -39,8 +39,8 @@ CROSS_COMPILE = arm-none-eabi-
|
||||||
CC = $(CROSS_COMPILE)gcc
|
CC = $(CROSS_COMPILE)gcc
|
||||||
LD = $(CROSS_COMPILE)gcc
|
LD = $(CROSS_COMPILE)gcc
|
||||||
AS = $(CROSS_COMPILE)gcc
|
AS = $(CROSS_COMPILE)gcc
|
||||||
AR = $(CROSS_COMPILE)ar
|
AR = $(CROSS_COMPILE)gcc-ar
|
||||||
NM = $(CROSS_COMPILE)nm
|
NM = $(CROSS_COMPILE)gcc-nm
|
||||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||||
OBJDUMP = $(CROSS_COMPILE)objdump
|
OBJDUMP = $(CROSS_COMPILE)objdump
|
||||||
STRIP = $(CROSS_COMPILE)strip
|
STRIP = $(CROSS_COMPILE)strip
|
||||||
|
|
|
@ -159,7 +159,7 @@ clock_set_seconds(unsigned long sec)
|
||||||
seconds = sec;
|
seconds = sec;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/*
|
||||||
* Wait for a number of clock ticks.
|
* Wait for a number of clock ticks.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -175,7 +175,7 @@ clock_wait(clock_time_t t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/*
|
||||||
* Delay the CPU for up to 65535*(4000000/F_CPU) microseconds.
|
* Delay the CPU for up to 65535*(4000000/F_CPU) microseconds.
|
||||||
* Copied from _delay_loop_2 in AVR library delay_basic.h, 4 clocks per loop.
|
* Copied from _delay_loop_2 in AVR library delay_basic.h, 4 clocks per loop.
|
||||||
* For accurate short delays, inline _delay_loop_2 in the caller, use a constant
|
* For accurate short delays, inline _delay_loop_2 in the caller, use a constant
|
||||||
|
@ -193,44 +193,44 @@ my_delay_loop_2(uint16_t __count)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
clock_delay_usec(uint16_t howlong)
|
clock_delay_usec(uint16_t dt)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* Accurate delay at any frequency, but introduces a 64 bit intermediate
|
/* Accurate delay at any frequency, but introduces a 64 bit intermediate
|
||||||
* and has a 279 clock overhead.
|
* and has a 279 clock overhead.
|
||||||
*/
|
*/
|
||||||
if(howlong<=(uint16_t)(279000000UL/F_CPU)) return;
|
if(dt<=(uint16_t)(279000000UL/F_CPU)) return;
|
||||||
howlong-=(uint16_t) (279000000UL/F_CPU);
|
dt-=(uint16_t) (279000000UL/F_CPU);
|
||||||
my_delay_loop_2(((uint64_t)(howlong) * (uint64_t) F_CPU) / 4000000ULL);
|
my_delay_loop_2(((uint64_t)(dt) * (uint64_t) F_CPU) / 4000000ULL);
|
||||||
/* Remaining numbers tweaked for the breakpoint CPU frequencies */
|
/* Remaining numbers tweaked for the breakpoint CPU frequencies */
|
||||||
/* Add other frequencies as necessary */
|
/* Add other frequencies as necessary */
|
||||||
#elif F_CPU>=16000000UL
|
#elif F_CPU>=16000000UL
|
||||||
if(howlong<1) return;
|
if(dt<1) return;
|
||||||
my_delay_loop_2((howlong*(uint16_t)(F_CPU/3250000)));
|
my_delay_loop_2((dt*(uint16_t)(F_CPU/3250000)));
|
||||||
#elif F_CPU >= 12000000UL
|
#elif F_CPU >= 12000000UL
|
||||||
if(howlong<2) return;
|
if(dt<2) return;
|
||||||
howlong-=(uint16_t) (3*12000000/F_CPU);
|
dt-=(uint16_t) (3*12000000/F_CPU);
|
||||||
my_delay_loop_2((howlong*(uint16_t)(F_CPU/3250000)));
|
my_delay_loop_2((dt*(uint16_t)(F_CPU/3250000)));
|
||||||
#elif F_CPU >= 8000000UL
|
#elif F_CPU >= 8000000UL
|
||||||
if(howlong<4) return;
|
if(dt<4) return;
|
||||||
howlong-=(uint16_t) (3*8000000/F_CPU);
|
dt-=(uint16_t) (3*8000000/F_CPU);
|
||||||
my_delay_loop_2((howlong*(uint16_t)(F_CPU/2000000))/2);
|
my_delay_loop_2((dt*(uint16_t)(F_CPU/2000000))/2);
|
||||||
#elif F_CPU >= 4000000UL
|
#elif F_CPU >= 4000000UL
|
||||||
if(howlong<5) return;
|
if(dt<5) return;
|
||||||
howlong-=(uint16_t) (4*4000000/F_CPU);
|
dt-=(uint16_t) (4*4000000/F_CPU);
|
||||||
my_delay_loop_2((howlong*(uint16_t)(F_CPU/2000000))/2);
|
my_delay_loop_2((dt*(uint16_t)(F_CPU/2000000))/2);
|
||||||
#elif F_CPU >= 2000000UL
|
#elif F_CPU >= 2000000UL
|
||||||
if(howlong<11) return;
|
if(dt<11) return;
|
||||||
howlong-=(uint16_t) (10*2000000/F_CPU);
|
dt-=(uint16_t) (10*2000000/F_CPU);
|
||||||
my_delay_loop_2((howlong*(uint16_t)(F_CPU/1000000))/4);
|
my_delay_loop_2((dt*(uint16_t)(F_CPU/1000000))/4);
|
||||||
#elif F_CPU >= 1000000UL
|
#elif F_CPU >= 1000000UL
|
||||||
if(howlong<=17) return;
|
if(dt<=17) return;
|
||||||
howlong-=(uint16_t) (17*1000000/F_CPU);
|
dt-=(uint16_t) (17*1000000/F_CPU);
|
||||||
my_delay_loop_2((howlong*(uint16_t)(F_CPU/1000000))/4);
|
my_delay_loop_2((dt*(uint16_t)(F_CPU/1000000))/4);
|
||||||
#else
|
#else
|
||||||
howlong >> 5;
|
dt >> 5;
|
||||||
if (howlong < 1) return;
|
if (dt < 1) return;
|
||||||
my_delay_loop_2(howlong);
|
my_delay_loop_2(dt);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -250,7 +250,7 @@ clock_delay(unsigned int howlong)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* Delay up to 65535 milliseconds.
|
* Delay up to 65535 milliseconds.
|
||||||
* \param dt How many milliseconds to delay.
|
* \param howlong How many milliseconds to delay.
|
||||||
*
|
*
|
||||||
* Neither interrupts nor the watchdog timer is disabled over the delay.
|
* Neither interrupts nor the watchdog timer is disabled over the delay.
|
||||||
* Platforms are not required to implement this call.
|
* Platforms are not required to implement this call.
|
||||||
|
@ -279,7 +279,7 @@ clock_delay_msec(uint16_t howlong)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* Adjust the system current clock time.
|
* Adjust the system current clock time.
|
||||||
* \param dt How many ticks to add
|
* \param howmany How many ticks to add
|
||||||
*
|
*
|
||||||
* Typically used to add ticks after an MCU sleep
|
* Typically used to add ticks after an MCU sleep
|
||||||
* clock_seconds will increment if necessary to reflect the tick addition.
|
* clock_seconds will increment if necessary to reflect the tick addition.
|
||||||
|
|
|
@ -49,8 +49,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef RADIO_H
|
#ifndef RF230BB_H_
|
||||||
#define RADIO_H
|
#define RF230BB_H_
|
||||||
/*============================ INCLUDE =======================================*/
|
/*============================ INCLUDE =======================================*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -225,6 +225,6 @@ uint8_t rf230_get_raw_rssi(void);
|
||||||
|
|
||||||
#define rf230_rssi rf230_get_raw_rssi
|
#define rf230_rssi rf230_get_raw_rssi
|
||||||
|
|
||||||
#endif
|
#endif /* RF230BB_H_ */
|
||||||
/** @} */
|
/** @} */
|
||||||
/*EOF*/
|
/*EOF*/
|
||||||
|
|
|
@ -54,7 +54,7 @@ static unsigned long timer_value;
|
||||||
static volatile CC_AT_DATA clock_time_t count = 0; /* Uptime in ticks */
|
static volatile CC_AT_DATA clock_time_t count = 0; /* Uptime in ticks */
|
||||||
static volatile CC_AT_DATA clock_time_t seconds = 0; /* Uptime in secs */
|
static volatile CC_AT_DATA clock_time_t seconds = 0; /* Uptime in secs */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/*
|
||||||
* Each iteration is ~1.0xy usec, so this function delays for roughly len usec
|
* Each iteration is ~1.0xy usec, so this function delays for roughly len usec
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -68,7 +68,7 @@ clock_delay_usec(uint16_t len)
|
||||||
ENABLE_INTERRUPTS();
|
ENABLE_INTERRUPTS();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/*
|
||||||
* Wait for a multiple of ~8 ms (a tick)
|
* Wait for a multiple of ~8 ms (a tick)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
|
|
@ -52,6 +52,7 @@ CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c
|
||||||
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c
|
||||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||||
|
CONTIKI_CPU_SOURCEFILES += i2c.c
|
||||||
|
|
||||||
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
||||||
|
|
||||||
|
|
|
@ -96,17 +96,17 @@ clock_init(void)
|
||||||
REG(SYS_CTRL_RCGCGPT) |= SYS_CTRL_RCGCGPT_GPT0;
|
REG(SYS_CTRL_RCGCGPT) |= SYS_CTRL_RCGCGPT_GPT0;
|
||||||
|
|
||||||
/* Make sure GPT0 is off */
|
/* Make sure GPT0 is off */
|
||||||
REG(GPT_0_BASE | GPTIMER_CTL) = 0;
|
REG(GPT_0_BASE + GPTIMER_CTL) = 0;
|
||||||
|
|
||||||
|
|
||||||
/* 16-bit */
|
/* 16-bit */
|
||||||
REG(GPT_0_BASE | GPTIMER_CFG) = 0x04;
|
REG(GPT_0_BASE + GPTIMER_CFG) = 0x04;
|
||||||
|
|
||||||
/* One-Shot, Count Down, No Interrupts */
|
/* One-Shot, Count Down, No Interrupts */
|
||||||
REG(GPT_0_BASE | GPTIMER_TAMR) = GPTIMER_TAMR_TAMR_ONE_SHOT;
|
REG(GPT_0_BASE + GPTIMER_TAMR) = GPTIMER_TAMR_TAMR_ONE_SHOT;
|
||||||
|
|
||||||
/* Prescale by 16 (thus, value 15 in TAPR) */
|
/* Prescale by 16 (thus, value 15 in TAPR) */
|
||||||
REG(GPT_0_BASE | GPTIMER_TAPR) = 0x0F;
|
REG(GPT_0_BASE + GPTIMER_TAPR) = 0x0F;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
CCIF clock_time_t
|
CCIF clock_time_t
|
||||||
|
@ -136,20 +136,19 @@ clock_wait(clock_time_t i)
|
||||||
while(clock_time() - start < (clock_time_t)i);
|
while(clock_time() - start < (clock_time_t)i);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/*
|
||||||
* \brief Arch-specific implementation of clock_delay_usec for the cc2538
|
* Arch-specific implementation of clock_delay_usec for the cc2538
|
||||||
* \param len Delay \e len uSecs
|
|
||||||
*
|
*
|
||||||
* See clock_init() for GPT0 Timer A's configuration
|
* See clock_init() for GPT0 Timer A's configuration
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clock_delay_usec(uint16_t len)
|
clock_delay_usec(uint16_t dt)
|
||||||
{
|
{
|
||||||
REG(GPT_0_BASE | GPTIMER_TAILR) = len;
|
REG(GPT_0_BASE + GPTIMER_TAILR) = dt;
|
||||||
REG(GPT_0_BASE | GPTIMER_CTL) |= GPTIMER_CTL_TAEN;
|
REG(GPT_0_BASE + GPTIMER_CTL) |= GPTIMER_CTL_TAEN;
|
||||||
|
|
||||||
/* One-Shot mode: TAEN will be cleared when the timer reaches 0 */
|
/* One-Shot mode: TAEN will be cleared when the timer reaches 0 */
|
||||||
while(REG(GPT_0_BASE | GPTIMER_CTL) & GPTIMER_CTL_TAEN);
|
while(REG(GPT_0_BASE + GPTIMER_CTL) & GPTIMER_CTL_TAEN);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,12 +29,21 @@
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* \addtogroup cc2538
|
* \addtogroup platform
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \defgroup cc2538-platforms TI cc2538-powered platforms
|
||||||
|
*
|
||||||
|
* Documentation for all platforms powered by the TI cc2538 System-on-Chip
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \defgroup cc2538 The TI cc2538 System-on-Chip
|
||||||
|
* CPU-Specific functionality - available to all cc2538-based platforms
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \defgroup cc2538-cpu cc2538 CPU
|
* \defgroup cc2538-cpu cc2538 CPU
|
||||||
*
|
*
|
||||||
* cc2538 CPU-specific functions for the cc2538 core
|
* CPU-specific functions for the cc2538 core
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
|
@ -60,6 +69,8 @@ unsigned long cpu_cpsie(void);
|
||||||
#endif /* CPU_H_ */
|
#endif /* CPU_H_ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue