2016-11-02 13:12:07 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016, Yasuyuki Tanaka
|
|
|
|
* 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 sixtop
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* \file
|
|
|
|
* Neighbor Management for 6top Protocol (6P)
|
|
|
|
* \author
|
|
|
|
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "contiki-lib.h"
|
|
|
|
|
|
|
|
#include "lib/assert.h"
|
|
|
|
#include "net/nbr-table.h"
|
|
|
|
|
|
|
|
#include "sixp.h"
|
|
|
|
|
2017-07-11 15:26:40 +00:00
|
|
|
/* Log configuration */
|
|
|
|
#include "sys/log.h"
|
|
|
|
#define LOG_MODULE "6top"
|
|
|
|
#define LOG_LEVEL LOG_LEVEL_6TOP
|
2016-11-02 13:12:07 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief 6P Neighbor Data Structure (for internal use)
|
|
|
|
*
|
|
|
|
* XXX: for now, we have one nbr object per neighbor, which is shared with
|
|
|
|
* multiple SFs. It's unclear whether we should use a different generation
|
|
|
|
* counter for each SFs.
|
|
|
|
*/
|
|
|
|
typedef struct sixp_nbr {
|
|
|
|
struct sixp_nbr *next;
|
|
|
|
linkaddr_t addr;
|
|
|
|
uint8_t next_seqno;
|
|
|
|
} sixp_nbr_t;
|
|
|
|
|
|
|
|
NBR_TABLE(sixp_nbr_t, sixp_nbrs);
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
sixp_nbr_t *
|
|
|
|
sixp_nbr_find(const linkaddr_t *addr)
|
|
|
|
{
|
|
|
|
assert(addr != NULL);
|
|
|
|
if(addr == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return (sixp_nbr_t *)nbr_table_get_from_lladdr(sixp_nbrs, addr);
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
sixp_nbr_t *
|
|
|
|
sixp_nbr_alloc(const linkaddr_t *addr)
|
|
|
|
{
|
|
|
|
sixp_nbr_t *nbr;
|
|
|
|
|
|
|
|
assert(addr != NULL);
|
|
|
|
if(addr == NULL) {
|
2017-07-11 15:26:40 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_alloc() fails because of invalid argument\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sixp_nbr_find(addr) != NULL) {
|
2017-07-11 15:26:40 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_alloc() fails because of duplication [peer_addr:");
|
|
|
|
LOG_ERR_LLADDR((const linkaddr_t *)addr);
|
|
|
|
LOG_ERR_("]\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((nbr = (sixp_nbr_t *)nbr_table_add_lladdr(sixp_nbrs,
|
|
|
|
addr,
|
|
|
|
NBR_TABLE_REASON_SIXTOP,
|
|
|
|
NULL)) == NULL) {
|
2017-07-11 15:26:40 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_alloc() fails to add nbr because of no memory\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
linkaddr_copy(&nbr->addr, addr);
|
|
|
|
nbr->next_seqno = SIXP_INITIAL_SEQUENCE_NUMBER;
|
|
|
|
|
|
|
|
return nbr;
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
void
|
|
|
|
sixp_nbr_free(sixp_nbr_t *nbr)
|
|
|
|
{
|
|
|
|
assert(nbr != NULL);
|
|
|
|
if(nbr != NULL) {
|
|
|
|
(void)nbr_table_remove(sixp_nbrs, nbr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2018-03-17 22:18:39 +00:00
|
|
|
int
|
|
|
|
sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
|
2016-11-02 13:12:07 +00:00
|
|
|
{
|
|
|
|
assert(nbr != NULL);
|
|
|
|
if(nbr == NULL) {
|
2018-03-17 22:18:39 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_get_next_seqno() fails because of invalid arg\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2018-03-17 22:18:39 +00:00
|
|
|
return nbr->next_seqno;
|
2016-11-02 13:12:07 +00:00
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int
|
2018-03-17 22:18:39 +00:00
|
|
|
sixp_nbr_set_next_seqno(sixp_nbr_t *nbr, uint16_t seqno)
|
2016-11-02 13:12:07 +00:00
|
|
|
{
|
|
|
|
assert(nbr != NULL);
|
|
|
|
if(nbr == NULL) {
|
2018-03-17 22:18:39 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_set_next_seqno() fails because of invalid arg\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2018-03-17 22:18:39 +00:00
|
|
|
nbr->next_seqno = seqno;
|
2017-07-10 02:36:24 +00:00
|
|
|
return 0;
|
2016-11-02 13:12:07 +00:00
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int
|
2018-03-17 22:18:39 +00:00
|
|
|
sixp_nbr_reset_next_seqno(sixp_nbr_t *nbr)
|
2016-11-02 13:12:07 +00:00
|
|
|
{
|
|
|
|
assert(nbr != NULL);
|
|
|
|
if(nbr == NULL) {
|
2018-03-17 22:18:39 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_clear_next_seqno() fails; invalid arg\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2018-03-17 22:18:39 +00:00
|
|
|
nbr->next_seqno = 0;
|
|
|
|
return 0;
|
2016-11-02 13:12:07 +00:00
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int
|
|
|
|
sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr)
|
|
|
|
{
|
|
|
|
assert(nbr != NULL);
|
|
|
|
if(nbr == NULL) {
|
2017-07-11 15:26:40 +00:00
|
|
|
LOG_ERR("6P-nbr: sixp_nbr_increment_next_seqno() fails; invalid arg\n");
|
2016-11-02 13:12:07 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
nbr->next_seqno++;
|
2018-03-17 22:18:39 +00:00
|
|
|
if(nbr->next_seqno == 0) {
|
2016-11-02 13:12:07 +00:00
|
|
|
/*
|
2018-03-17 22:18:39 +00:00
|
|
|
* next_seqno can be 0 only by initialization of nbr or by a CLEAR
|
|
|
|
* transaction.
|
2016-11-02 13:12:07 +00:00
|
|
|
*/
|
2018-03-17 22:18:39 +00:00
|
|
|
nbr->next_seqno = 1;
|
2016-11-02 13:12:07 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int
|
|
|
|
sixp_nbr_init(void)
|
|
|
|
{
|
|
|
|
sixp_nbr_t *nbr, *next_nbr;
|
2018-03-19 19:05:06 +00:00
|
|
|
if(nbr_table_is_registered(sixp_nbrs) == 0) {
|
2016-11-02 13:12:07 +00:00
|
|
|
nbr_table_register(sixp_nbrs, NULL);
|
|
|
|
} else {
|
|
|
|
/* remove all the existing nbrs */
|
|
|
|
nbr = (sixp_nbr_t *)nbr_table_head(sixp_nbrs);
|
|
|
|
while(nbr != NULL) {
|
|
|
|
next_nbr = (sixp_nbr_t *)nbr_table_next(sixp_nbrs, nbr);
|
|
|
|
sixp_nbr_free(nbr);
|
|
|
|
nbr = next_nbr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
/** @} */
|