sixtop: refactoring
- support draft-ietf-6tisch-6top-protocol-03 - maintain a sequence number per neighbor - rename variables and constants - reconsider file structure and file names - make sf-simple part of example - update sixtop/README.md - add regression-tests for 6tisch - apply C-DAC copyright notice - bugfix + cleanup
This commit is contained in:
parent
cc1c763db9
commit
a5fadb2ebe
|
@ -104,3 +104,4 @@ env:
|
|||
- BUILD_TYPE='ipv6' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='base' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='ieee802154' BUILD_CATEGORY='sim'
|
||||
- BUILD_TYPE='6tisch' BUILD_CATEGORY='sim'
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
CONTIKI_PROJECT = node-sixtop
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
PROJECT_SOURCEFILES += sf-simple.c
|
||||
CONTIKI=../../..
|
||||
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
|
||||
|
||||
CONTIKI_WITH_IPV6 = 1
|
||||
MAKE_WITH_ORCHESTRA ?= 0 # force Orchestra from command line
|
||||
MAKE_WITH_SECURITY ?= 0 # force Security from command line
|
||||
|
||||
APPS += orchestra
|
||||
MODULES += core/net/mac/tsch
|
||||
MODULES += core/net/mac/tsch/sixtop
|
||||
|
||||
ifeq ($(MAKE_WITH_ORCHESTRA),1)
|
||||
CFLAGS += -DWITH_ORCHESTRA=1
|
||||
endif
|
||||
MODULES += os/net/mac/tsch
|
||||
MODULES += os/net/mac/tsch/sixtop
|
||||
|
||||
ifeq ($(MAKE_WITH_SECURITY),1)
|
||||
CFLAGS += -DWITH_SECURITY=1
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
*
|
||||
* \author
|
||||
* Simon Duquennoy <simonduq@sics.se>
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Lijo Thomas <lijo@cdac.in>
|
||||
*/
|
||||
|
||||
|
@ -42,9 +42,12 @@
|
|||
#include "net/rpl/rpl.h"
|
||||
#include "net/ipv6/uip-ds6-route.h"
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
#include "net/mac/tsch/tsch-schedule.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
#include "net/rpl/rpl-private.h"
|
||||
#include "net/ip/uip-debug.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
|
||||
#include "sf-simple.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(node_process, "RPL Node");
|
||||
|
@ -72,6 +75,8 @@ net_init(uip_ipaddr_t *br_prefix)
|
|||
PROCESS_THREAD(node_process, ev, data)
|
||||
{
|
||||
static struct etimer et;
|
||||
struct tsch_neighbor *n;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/* 3 possible roles:
|
||||
|
@ -104,6 +109,7 @@ PROCESS_THREAD(node_process, ev, data)
|
|||
|
||||
tsch_set_pan_secured(LLSEC802154_ENABLED && (node_role == role_6dr_sec));
|
||||
is_coordinator = node_role > role_6ln;
|
||||
sixtop_add_sf(&sf_simple_driver);
|
||||
|
||||
if(is_coordinator) {
|
||||
uip_ipaddr_t prefix;
|
||||
|
@ -118,14 +124,17 @@ PROCESS_THREAD(node_process, ev, data)
|
|||
PROCESS_YIELD_UNTIL(etimer_expired(&et));
|
||||
etimer_reset(&et);
|
||||
|
||||
/* Get time-source neighbor */
|
||||
n = tsch_queue_get_time_source();
|
||||
|
||||
if(node_id != 1) {
|
||||
clock_delay(1000);
|
||||
if((added_num_of_links == 1) || (added_num_of_links == 3)) {
|
||||
printf("App : Add a link\n");
|
||||
sixtop_add_links((linkaddr_t *)0xffff, 1);
|
||||
sf_simple_add_links(&n->addr, 1);
|
||||
} else if(added_num_of_links == 5) {
|
||||
printf("App : Delete a link\n");
|
||||
sixtop_remove_link((linkaddr_t *)0xffff);
|
||||
sf_simple_remove_links(&n->addr);
|
||||
}
|
||||
added_num_of_links++;
|
||||
}
|
||||
|
|
|
@ -31,11 +31,6 @@
|
|||
#ifndef __PROJECT_CONF_H__
|
||||
#define __PROJECT_CONF_H__
|
||||
|
||||
/* Set to run orchestra */
|
||||
#ifndef WITH_ORCHESTRA
|
||||
#define WITH_ORCHESTRA 0
|
||||
#endif /* WITH_ORCHESTRA */
|
||||
|
||||
/* Set to enable TSCH security */
|
||||
#ifndef WITH_SECURITY
|
||||
#define WITH_SECURITY 0
|
||||
|
@ -66,7 +61,7 @@
|
|||
|
||||
/* IEEE802.15.4 frame version */
|
||||
#undef FRAME802154_CONF_VERSION
|
||||
#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012
|
||||
#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154_2015
|
||||
|
||||
/* TSCH and RPL callbacks */
|
||||
#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch
|
||||
|
@ -96,10 +91,9 @@
|
|||
/******************* Configure TSCH ********************/
|
||||
/*******************************************************/
|
||||
|
||||
/* TSCH logging. 0: disabled. 1: basic log. 2: with delayed
|
||||
* log messages from interrupt */
|
||||
#undef TSCH_LOG_CONF_LEVEL
|
||||
#define TSCH_LOG_CONF_LEVEL 2
|
||||
/* TSCH logging. */
|
||||
#undef TSCH_LOG_CONF_PER_SLOT
|
||||
#define TSCH_LOG_CONF_PER_SLOT 1
|
||||
|
||||
/* IEEE802.15.4 PANID */
|
||||
#undef IEEE802154_CONF_PANID
|
||||
|
@ -127,19 +121,6 @@
|
|||
|
||||
#endif /* WITH_SECURITY */
|
||||
|
||||
#if WITH_ORCHESTRA
|
||||
|
||||
/* See apps/orchestra/README.md for more Orchestra configuration options */
|
||||
#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0 /* No 6TiSCH minimal schedule */
|
||||
#define TSCH_CONF_WITH_LINK_SELECTOR 1 /* Orchestra requires per-packet link selection */
|
||||
/* Orchestra callbacks */
|
||||
#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source
|
||||
#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready
|
||||
#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added
|
||||
#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed
|
||||
|
||||
#endif /* WITH_ORCHESTRA */
|
||||
|
||||
/*******************************************************/
|
||||
/************* Other system configuration **************/
|
||||
/*******************************************************/
|
||||
|
|
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Yasuyuki Tanaka
|
||||
* Copyright (c) 2016, Centre for Development of Advanced Computing (C-DAC).
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* A 6P Simple Schedule Function
|
||||
* \author
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Lijo Thomas <lijo@cdac.in>
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "contiki-lib.h"
|
||||
|
||||
#include "lib/assert.h"
|
||||
#include "net/mac/tsch/tsch-schedule.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
#include "net/mac/tsch/sixtop/sixp.h"
|
||||
#include "net/mac/tsch/sixtop/sixp-nbr.h"
|
||||
#include "net/mac/tsch/sixtop/sixp-pkt.h"
|
||||
#include "net/mac/tsch/sixtop/sixp-trans.h"
|
||||
|
||||
#include "sf-simple.h"
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/net-debug.h"
|
||||
|
||||
typedef struct {
|
||||
uint16_t timeslot_offset;
|
||||
uint16_t channel_offset;
|
||||
} sf_simple_cell_t;
|
||||
|
||||
static const uint16_t slotframe_handle = 0;
|
||||
static uint8_t res_storage[4 + SF_SIMPLE_MAX_LINKS * 4];
|
||||
static uint8_t req_storage[4 + SF_SIMPLE_MAX_LINKS * 4];
|
||||
|
||||
static void read_cell(const uint8_t *buf, sf_simple_cell_t *cell);
|
||||
static void print_cell_list(const uint8_t *cell_list, uint16_t cell_list_len);
|
||||
static void add_links_to_schedule(const linkaddr_t *peer_addr,
|
||||
uint8_t link_option,
|
||||
const uint8_t *cell_list,
|
||||
uint16_t cell_list_len);
|
||||
static void remove_links_to_schedule(const uint8_t *cell_list,
|
||||
uint16_t cell_list_len);
|
||||
static void add_response_sent_callback(void *arg, uint16_t arg_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_output_status_t status);
|
||||
static void delete_response_sent_callback(void *arg, uint16_t arg_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_output_status_t status);
|
||||
static void add_req_input(const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr);
|
||||
static void delete_req_input(const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr);
|
||||
static void input(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *src_addr);
|
||||
static void request_input(sixp_pkt_cmd_t cmd,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr);
|
||||
static void response_input(sixp_pkt_rc_t rc,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr);
|
||||
|
||||
/*
|
||||
* scheduling policy:
|
||||
* add: if and only if all the requested cells are available, accept the request
|
||||
* delete: if and only if all the requested cells are in use, accept the request
|
||||
*/
|
||||
|
||||
static void
|
||||
read_cell(const uint8_t *buf, sf_simple_cell_t *cell)
|
||||
{
|
||||
cell->timeslot_offset = buf[0] + (buf[1] << 8);
|
||||
cell->channel_offset = buf[2] + (buf[3] << 8);
|
||||
}
|
||||
|
||||
static void
|
||||
print_cell_list(const uint8_t *cell_list, uint16_t cell_list_len)
|
||||
{
|
||||
uint16_t i;
|
||||
sf_simple_cell_t cell;
|
||||
|
||||
for(i = 0; i < (cell_list_len / sizeof(cell)); i++) {
|
||||
read_cell(&cell_list[i], &cell);
|
||||
PRINTF("%u ", cell.timeslot_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_links_to_schedule(const linkaddr_t *peer_addr, uint8_t link_option,
|
||||
const uint8_t *cell_list, uint16_t cell_list_len)
|
||||
{
|
||||
/* add only the first valid cell */
|
||||
|
||||
sf_simple_cell_t cell;
|
||||
struct tsch_slotframe *slotframe;
|
||||
int i;
|
||||
|
||||
assert(cell_list != NULL);
|
||||
|
||||
slotframe = tsch_schedule_get_slotframe_by_handle(slotframe_handle);
|
||||
|
||||
if(slotframe == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < (cell_list_len / sizeof(cell)); i++) {
|
||||
read_cell(&cell_list[i], &cell);
|
||||
if(cell.timeslot_offset == 0xffff) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PRINTF("sf-simple: Schedule link %d as %s with node %u\n",
|
||||
cell.timeslot_offset,
|
||||
link_option == LINK_OPTION_RX ? "RX" : "TX",
|
||||
peer_addr->u8[7]);
|
||||
tsch_schedule_add_link(slotframe,
|
||||
link_option, LINK_TYPE_NORMAL, peer_addr,
|
||||
cell.timeslot_offset, cell.channel_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_links_to_schedule(const uint8_t *cell_list, uint16_t cell_list_len)
|
||||
{
|
||||
/* remove all the cells */
|
||||
|
||||
sf_simple_cell_t cell;
|
||||
struct tsch_slotframe *slotframe;
|
||||
int i;
|
||||
|
||||
assert(cell_list != NULL);
|
||||
|
||||
slotframe = tsch_schedule_get_slotframe_by_handle(slotframe_handle);
|
||||
|
||||
if(slotframe == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < (cell_list_len / sizeof(cell)); i++) {
|
||||
read_cell(&cell_list[i], &cell);
|
||||
if(cell.timeslot_offset == 0xffff) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tsch_schedule_remove_link_by_timeslot(slotframe,
|
||||
cell.timeslot_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_response_sent_callback(void *arg, uint16_t arg_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_output_status_t status)
|
||||
{
|
||||
uint8_t *body = (uint8_t *)arg;
|
||||
uint16_t body_len = arg_len;
|
||||
const uint8_t *cell_list;
|
||||
uint16_t cell_list_len;
|
||||
sixp_nbr_t *nbr;
|
||||
|
||||
assert(body != NULL && dest_addr != NULL);
|
||||
|
||||
if(status == SIXP_OUTPUT_STATUS_SUCCESS &&
|
||||
sixp_pkt_get_cell_list(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
&cell_list, &cell_list_len,
|
||||
body, body_len) == 0 &&
|
||||
(nbr = sixp_nbr_find(dest_addr)) != NULL) {
|
||||
add_links_to_schedule(dest_addr, LINK_OPTION_RX,
|
||||
cell_list, cell_list_len);
|
||||
sixp_nbr_advance_grx(nbr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_response_sent_callback(void *arg, uint16_t arg_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_output_status_t status)
|
||||
{
|
||||
uint8_t *body = (uint8_t *)arg;
|
||||
uint16_t body_len = arg_len;
|
||||
const uint8_t *cell_list;
|
||||
uint16_t cell_list_len;
|
||||
sixp_nbr_t *nbr;
|
||||
|
||||
assert(body != NULL && dest_addr != NULL);
|
||||
|
||||
if(status == SIXP_OUTPUT_STATUS_SUCCESS &&
|
||||
sixp_pkt_get_cell_list(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
&cell_list, &cell_list_len,
|
||||
body, body_len) == 0 &&
|
||||
(nbr = sixp_nbr_find(dest_addr)) != NULL) {
|
||||
remove_links_to_schedule(cell_list, cell_list_len);
|
||||
sixp_nbr_advance_grx(nbr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_req_input(const uint8_t *body, uint16_t body_len, const linkaddr_t *peer_addr)
|
||||
{
|
||||
uint8_t i;
|
||||
sf_simple_cell_t cell;
|
||||
struct tsch_slotframe *slotframe;
|
||||
int feasible_link;
|
||||
uint8_t num_cells;
|
||||
const uint8_t *cell_list;
|
||||
uint16_t cell_list_len;
|
||||
uint16_t res_len;
|
||||
|
||||
assert(body != NULL && peer_addr != NULL);
|
||||
|
||||
if(sixp_pkt_get_num_cells(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
&num_cells,
|
||||
body, body_len) != 0 ||
|
||||
sixp_pkt_get_cell_list(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
&cell_list, &cell_list_len,
|
||||
body, body_len) != 0) {
|
||||
PRINTF("sf-simple: Parse error on add request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PRINTF("sf-simple: Received a 6P Add Request for %d links from node %d with LinkList : ",
|
||||
num_cells, peer_addr->u8[7]);
|
||||
print_cell_list(cell_list, cell_list_len);
|
||||
PRINTF("\n");
|
||||
|
||||
slotframe = tsch_schedule_get_slotframe_by_handle(slotframe_handle);
|
||||
if(slotframe == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(num_cells > 0 && cell_list_len > 0) {
|
||||
memset(res_storage, 0, sizeof(res_storage));
|
||||
res_len = 0;
|
||||
|
||||
/* checking availability for requested slots */
|
||||
for(i = 0, feasible_link = 0;
|
||||
i < cell_list_len && feasible_link < num_cells;
|
||||
i += sizeof(cell)) {
|
||||
read_cell(&cell_list[i], &cell);
|
||||
if(tsch_schedule_get_link_by_timeslot(slotframe,
|
||||
cell.timeslot_offset) == NULL) {
|
||||
sixp_pkt_set_cell_list(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
(uint8_t *)&cell, sizeof(cell),
|
||||
feasible_link,
|
||||
res_storage, sizeof(res_storage));
|
||||
res_len += sizeof(cell);
|
||||
feasible_link++;
|
||||
}
|
||||
}
|
||||
|
||||
if(feasible_link == num_cells) {
|
||||
/* Links are feasible. Create Link Response packet */
|
||||
PRINTF("sf-simple: Send a 6P Response to node %d\n", peer_addr->u8[7]);
|
||||
sixp_output(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
SF_SIMPLE_SFID,
|
||||
res_storage, res_len, peer_addr,
|
||||
add_response_sent_callback, res_storage, res_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_req_input(const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr)
|
||||
{
|
||||
uint8_t i;
|
||||
sf_simple_cell_t cell;
|
||||
struct tsch_slotframe *slotframe;
|
||||
uint8_t num_cells;
|
||||
const uint8_t *cell_list;
|
||||
uint16_t cell_list_len;
|
||||
uint16_t res_len;
|
||||
int removed_link;
|
||||
|
||||
assert(body != NULL && peer_addr != NULL);
|
||||
|
||||
if(sixp_pkt_get_num_cells(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_DELETE,
|
||||
&num_cells,
|
||||
body, body_len) != 0 ||
|
||||
sixp_pkt_get_cell_list(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_DELETE,
|
||||
&cell_list, &cell_list_len,
|
||||
body, body_len) != 0) {
|
||||
PRINTF("sf-simple: Parse error on delete request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PRINTF("sf-simple: Received a 6P Delete Request for %d links from node %d with LinkList : ",
|
||||
num_cells, peer_addr->u8[7]);
|
||||
print_cell_list(cell_list, cell_list_len);
|
||||
PRINTF("\n");
|
||||
|
||||
slotframe = tsch_schedule_get_slotframe_by_handle(slotframe_handle);
|
||||
if(slotframe == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(res_storage, 0, sizeof(res_storage));
|
||||
res_len = 0;
|
||||
|
||||
if(num_cells > 0 && cell_list_len > 0) {
|
||||
/* ensure before delete */
|
||||
for(i = 0, removed_link = 0; i < (cell_list_len / sizeof(cell)); i++) {
|
||||
read_cell(&cell_list[i], &cell);
|
||||
if(tsch_schedule_get_link_by_timeslot(slotframe,
|
||||
cell.timeslot_offset) != NULL) {
|
||||
sixp_pkt_set_cell_list(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
(uint8_t *)&cell, sizeof(cell),
|
||||
removed_link,
|
||||
res_storage, sizeof(res_storage));
|
||||
res_len += sizeof(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Links are feasible. Create Link Response packet */
|
||||
PRINTF("sf-simple: Send a 6P Response to node %d\n", peer_addr->u8[7]);
|
||||
sixp_output(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
SF_SIMPLE_SFID,
|
||||
res_storage, res_len, peer_addr,
|
||||
delete_response_sent_callback, res_storage, res_len);
|
||||
}
|
||||
|
||||
static void
|
||||
input(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t *body, uint16_t body_len, const linkaddr_t *src_addr)
|
||||
{
|
||||
assert(body != NULL && body != NULL);
|
||||
switch(type) {
|
||||
case SIXP_PKT_TYPE_REQUEST:
|
||||
request_input(code.cmd, body, body_len, src_addr);
|
||||
break;
|
||||
case SIXP_PKT_TYPE_RESPONSE:
|
||||
response_input(code.cmd, body, body_len, src_addr);
|
||||
break;
|
||||
default:
|
||||
/* unsupported */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
request_input(sixp_pkt_cmd_t cmd,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr)
|
||||
{
|
||||
assert(body != NULL && peer_addr != NULL);
|
||||
|
||||
switch(cmd) {
|
||||
case SIXP_PKT_CMD_ADD:
|
||||
add_req_input(body, body_len, peer_addr);
|
||||
break;
|
||||
case SIXP_PKT_CMD_DELETE:
|
||||
delete_req_input(body, body_len, peer_addr);
|
||||
break;
|
||||
default:
|
||||
/* unsupported request */
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void
|
||||
response_input(sixp_pkt_rc_t rc,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *peer_addr)
|
||||
{
|
||||
const uint8_t *cell_list;
|
||||
uint16_t cell_list_len;
|
||||
sixp_nbr_t *nbr;
|
||||
sixp_trans_t *trans;
|
||||
|
||||
assert(body != NULL && peer_addr != NULL);
|
||||
|
||||
if((nbr = sixp_nbr_find(peer_addr)) == NULL ||
|
||||
(trans = sixp_trans_find(peer_addr)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(rc == SIXP_PKT_RC_SUCCESS) {
|
||||
switch(sixp_trans_get_cmd(trans)) {
|
||||
case SIXP_PKT_CMD_ADD:
|
||||
if(sixp_pkt_get_cell_list(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
&cell_list, &cell_list_len,
|
||||
body, body_len) != 0) {
|
||||
PRINTF("sf-simple: Parse error on add response\n");
|
||||
return;
|
||||
}
|
||||
PRINTF("sf-simple: Received a 6P Add Response with LinkList : ");
|
||||
print_cell_list(cell_list, cell_list_len);
|
||||
PRINTF("\n");
|
||||
add_links_to_schedule(peer_addr, LINK_OPTION_TX,
|
||||
cell_list, cell_list_len);
|
||||
sixp_nbr_advance_gtx(nbr);
|
||||
break;
|
||||
case SIXP_PKT_CMD_DELETE:
|
||||
if(sixp_pkt_get_cell_list(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
&cell_list, &cell_list_len,
|
||||
body, body_len) != 0) {
|
||||
PRINTF("sf-simple: Parse error on add response\n");
|
||||
return;
|
||||
}
|
||||
PRINTF("sf-simple: Received a 6P Delete Response with LinkList : ");
|
||||
print_cell_list(cell_list, cell_list_len);
|
||||
PRINTF("\n");
|
||||
remove_links_to_schedule(cell_list, cell_list_len);
|
||||
sixp_nbr_advance_gtx(nbr);
|
||||
break;
|
||||
case SIXP_PKT_CMD_STATUS:
|
||||
case SIXP_PKT_CMD_LIST:
|
||||
case SIXP_PKT_CMD_CLEAR:
|
||||
default:
|
||||
PRINTF("sf-simple: unsupported response\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Initiates a Sixtop Link addition
|
||||
*/
|
||||
int
|
||||
sf_simple_add_links(linkaddr_t *peer_addr, uint8_t num_links)
|
||||
{
|
||||
uint8_t i = 0, index = 0;
|
||||
struct tsch_slotframe *sf =
|
||||
tsch_schedule_get_slotframe_by_handle(slotframe_handle);
|
||||
|
||||
uint8_t req_len;
|
||||
sf_simple_cell_t cell_list[SF_SIMPLE_MAX_LINKS];
|
||||
|
||||
/* Flag to prevent repeated slots */
|
||||
uint8_t slot_check = 1;
|
||||
uint16_t random_slot = 0;
|
||||
|
||||
assert(peer_addr != NULL && sf != NULL);
|
||||
|
||||
do {
|
||||
/* Randomly select a slot offset within TSCH_SCHEDULE_DEFAULT_LENGTH */
|
||||
random_slot = ((random_rand() & 0xFF)) % TSCH_SCHEDULE_DEFAULT_LENGTH;
|
||||
|
||||
if(tsch_schedule_get_link_by_timeslot(sf, random_slot) == NULL) {
|
||||
|
||||
/* To prevent repeated slots */
|
||||
for(i = 0; i < index; i++) {
|
||||
if(cell_list[i].timeslot_offset != random_slot) {
|
||||
/* Random selection resulted in a free slot */
|
||||
if(i == index - 1) { /* Checked till last index of link list */
|
||||
slot_check = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Slot already present in CandidateLinkList */
|
||||
slot_check++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Random selection resulted in a free slot, add it to linklist */
|
||||
if(slot_check == 1) {
|
||||
cell_list[index].timeslot_offset = random_slot;
|
||||
cell_list[index].channel_offset = 0;
|
||||
|
||||
index++;
|
||||
slot_check++;
|
||||
} else if(slot_check > TSCH_SCHEDULE_DEFAULT_LENGTH) {
|
||||
PRINTF("sf-simple:! Number of trials for free slot exceeded...\n");
|
||||
return -1;
|
||||
break; /* exit while loop */
|
||||
}
|
||||
}
|
||||
} while(index < SF_SIMPLE_MAX_LINKS);
|
||||
|
||||
/* Create a Sixtop Add Request. Return 0 if Success */
|
||||
if(index == 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(req_storage, 0, sizeof(req_storage));
|
||||
if(sixp_pkt_set_cell_options(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
SIXP_PKT_CELL_OPTION_TX,
|
||||
req_storage,
|
||||
sizeof(req_storage)) != 0 ||
|
||||
sixp_pkt_set_num_cells(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
num_links,
|
||||
req_storage,
|
||||
sizeof(req_storage)) != 0 ||
|
||||
sixp_pkt_set_cell_list(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
(const uint8_t *)cell_list,
|
||||
index * sizeof(sf_simple_cell_t), 0,
|
||||
req_storage, sizeof(req_storage)) != 0) {
|
||||
PRINTF("sf-simple: Build error on add request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The length of fixed part is 4 bytes: Metadata, CellOptions, and NumCells */
|
||||
req_len = 4 + index * sizeof(sf_simple_cell_t);
|
||||
sixp_output(SIXP_PKT_TYPE_REQUEST, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
SF_SIMPLE_SFID,
|
||||
req_storage, req_len, peer_addr,
|
||||
NULL, NULL, 0);
|
||||
|
||||
PRINTF("sf-simple: Send a 6P Add Request for %d links to node %d with LinkList : ",
|
||||
num_links, peer_addr->u8[7]);
|
||||
print_cell_list((const uint8_t *)cell_list, index * sizeof(sf_simple_cell_t));
|
||||
PRINTF("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Initiates a Sixtop Link deletion
|
||||
*/
|
||||
int
|
||||
sf_simple_remove_links(linkaddr_t *peer_addr)
|
||||
{
|
||||
uint8_t i = 0, index = 0;
|
||||
struct tsch_slotframe *sf =
|
||||
tsch_schedule_get_slotframe_by_handle(slotframe_handle);
|
||||
struct tsch_link *l;
|
||||
|
||||
uint16_t req_len;
|
||||
sf_simple_cell_t cell;
|
||||
|
||||
assert(peer_addr != NULL && sf != NULL);
|
||||
|
||||
for(i = 0; i < TSCH_SCHEDULE_DEFAULT_LENGTH; i++) {
|
||||
l = tsch_schedule_get_link_by_timeslot(sf, i);
|
||||
|
||||
if(l) {
|
||||
/* Non-zero value indicates a scheduled link */
|
||||
if((linkaddr_cmp(&l->addr, peer_addr)) && (l->link_options == LINK_OPTION_TX)) {
|
||||
/* This link is scheduled as a TX link to the specified neighbor */
|
||||
cell.timeslot_offset = i;
|
||||
cell.channel_offset = l->channel_offset;
|
||||
index++;
|
||||
break; /* delete atmost one */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(index == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(req_storage, 0, sizeof(req_storage));
|
||||
if(sixp_pkt_set_num_cells(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_DELETE,
|
||||
1,
|
||||
req_storage,
|
||||
sizeof(req_storage)) != 0 ||
|
||||
sixp_pkt_set_cell_list(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_DELETE,
|
||||
(const uint8_t *)&cell, sizeof(cell),
|
||||
0,
|
||||
req_storage, sizeof(req_storage)) != 0) {
|
||||
PRINTF("sf-simple: Build error on add request\n");
|
||||
return -1;
|
||||
}
|
||||
/* The length of fixed part is 4 bytes: Metadata, CellOptions, and NumCells */
|
||||
req_len = 4 + sizeof(sf_simple_cell_t);
|
||||
|
||||
sixp_output(SIXP_PKT_TYPE_REQUEST, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_DELETE,
|
||||
SF_SIMPLE_SFID,
|
||||
req_storage, req_len, peer_addr,
|
||||
NULL, NULL, 0);
|
||||
|
||||
PRINTF("sf-simple: Send a 6P Delete Request for %d links to node %d with LinkList : ",
|
||||
1, peer_addr->u8[7]);
|
||||
print_cell_list((const uint8_t *)&cell, sizeof(cell));
|
||||
PRINTF("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const sixtop_sf_t sf_simple_driver = {
|
||||
SF_SIMPLE_SFID,
|
||||
CLOCK_SECOND,
|
||||
NULL,
|
||||
input,
|
||||
NULL
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Yasuyuki Tanaka
|
||||
* Copyright (c) 2016, Centre for Development of Advanced Computing (C-DAC).
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* \file
|
||||
* A 6P Simple Schedule Function
|
||||
* \author
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Lijo Thomas <lijo@cdac.in>
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef _SIXTOP_SF_SIMPLE_H_
|
||||
#define _SIXTOP_SF_SIMPLE_H_
|
||||
|
||||
#include "net/linkaddr.h"
|
||||
|
||||
int sf_simple_add_links(linkaddr_t *peer_addr, uint8_t num_links);
|
||||
int sf_simple_remove_links(linkaddr_t *peer_addr);
|
||||
|
||||
#define SF_SIMPLE_MAX_LINKS 3
|
||||
#define SF_SIMPLE_SFID 0xf0
|
||||
extern const sixtop_sf_t sf_simple_driver;
|
||||
|
||||
#endif /* !_SIXTOP_SF_SIMPLE_H_ */
|
|
@ -62,6 +62,7 @@ enum ieee802154e_header_ie_id {
|
|||
enum ieee802154e_payload_ie_id {
|
||||
PAYLOAD_IE_ESDU = 0,
|
||||
PAYLOAD_IE_MLME,
|
||||
PAYLOAD_IE_IETF = 0x5,
|
||||
PAYLOAD_IE_LIST_TERMINATION = 0xf,
|
||||
};
|
||||
|
||||
|
@ -81,6 +82,11 @@ enum ieee802154e_mlme_long_subie_id {
|
|||
MLME_LONG_IE_TSCH_CHANNEL_HOPPING_SEQUENCE = 0x9,
|
||||
};
|
||||
|
||||
#include <net/mac/tsch/sixtop/sixtop.h>
|
||||
enum ieee802154e_ietf_subie_id {
|
||||
IETF_IE_6TOP = SIXTOP_SUBIE_ID,
|
||||
};
|
||||
|
||||
#define WRITE16(buf, val) \
|
||||
do { ((uint8_t *)(buf))[0] = (val) & 0xff; \
|
||||
((uint8_t *)(buf))[1] = ((val) >> 8) & 0xff; } while(0);
|
||||
|
@ -194,6 +200,21 @@ frame80215e_create_ie_payload_list_termination(uint8_t *buf, int len,
|
|||
}
|
||||
}
|
||||
|
||||
#if TSCH_WITH_SIXTOP
|
||||
/* Payload IE. 6top. Used to nest sub-IEs */
|
||||
int
|
||||
frame80215e_create_ie_ietf(uint8_t *buf, int len, struct ieee802154_ies *ies)
|
||||
{
|
||||
if(len >= 2 && ies != NULL) {
|
||||
create_payload_ie_descriptor(buf,
|
||||
PAYLOAD_IE_IETF,
|
||||
ies->sixtop_ie_content_len);
|
||||
return 2 + ies->sixtop_ie_content_len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
|
||||
/* Payload IE. MLME. Used to nest sub-IEs */
|
||||
int
|
||||
frame80215e_create_ie_mlme(uint8_t *buf, int len,
|
||||
|
@ -531,6 +552,29 @@ frame802154e_parse_information_elements(const uint8_t *buf, uint8_t buf_size,
|
|||
len = 0; /* Reset len as we want to read subIEs and not jump over them */
|
||||
LOG_DBG("entering MLME ie with len %u\n", nested_mlme_len);
|
||||
break;
|
||||
#if TSCH_WITH_SIXTOP
|
||||
case PAYLOAD_IE_IETF:
|
||||
switch(*buf) {
|
||||
case IETF_IE_6TOP:
|
||||
/*
|
||||
* buf points to the Sub-ID field, a one-octet field, now;
|
||||
* advance it by one and use the result as the head pointer of
|
||||
* 6top IE Content.
|
||||
*/
|
||||
ies->sixtop_ie_content_ptr = buf + 1;
|
||||
/*
|
||||
* Similarly as above, subtract 1 (one octet) from len, which
|
||||
* includes the length of Sub-ID field, and use the result as
|
||||
* the length of 6top IE Content.
|
||||
*/
|
||||
ies->sixtop_ie_content_len = len - 1;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("frame802154e: unsupported IETF sub-IE %u\n", *buf);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
case PAYLOAD_IE_LIST_TERMINATION:
|
||||
LOG_DBG("payload ie list termination %u\n", len);
|
||||
return (len == 0) ? buf + len - start : -1;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "contiki.h"
|
||||
/* We need definitions from tsch-private.h for TSCH-specific information elements */
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
#include "net/mac/tsch/tsch-private.h"
|
||||
|
||||
#define FRAME802154E_IE_MAX_LINKS 4
|
||||
|
@ -80,6 +81,11 @@ struct ieee802154_ies {
|
|||
/* We include and parse only the sequence len and list and omit unused fields */
|
||||
uint16_t ie_hopping_sequence_len;
|
||||
uint8_t ie_hopping_sequence_list[TSCH_HOPPING_SEQUENCE_MAX_LEN];
|
||||
#if TSCH_WITH_SIXTOP
|
||||
/* Payload Sixtop IE */
|
||||
const uint8_t *sixtop_ie_content_ptr;
|
||||
uint16_t sixtop_ie_content_len;
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
};
|
||||
|
||||
/** Insert various Information Elements **/
|
||||
|
@ -97,6 +103,11 @@ int frame80215e_create_ie_header_list_termination_2(uint8_t *buf, int len,
|
|||
/* Payload IE. List termination */
|
||||
int frame80215e_create_ie_payload_list_termination(uint8_t *buf, int len,
|
||||
struct ieee802154_ies *ies);
|
||||
#if TSCH_WITH_SIXTOP
|
||||
/* Payload IE. 6top. Used to nest sub-IEs */
|
||||
int frame80215e_create_ie_ietf(uint8_t *buf, int len,
|
||||
struct ieee802154_ies *ies);
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
/* Payload IE. MLME. Used to nest sub-IEs */
|
||||
int frame80215e_create_ie_mlme(uint8_t *buf, int len,
|
||||
struct ieee802154_ies *ies);
|
||||
|
|
|
@ -1,64 +1,103 @@
|
|||
# [EXPERIMENTAL] 6TiSCH Operation Sublayer (6top)
|
||||
|
||||
## Overview
|
||||
|
||||
6TiSCH Operation Sublayer (6top), a logical link layer in the 6TiSCH
|
||||
architecture, provides the abstraction of an IP link over a TSCH MAC layer (IEEE
|
||||
802.15.4e). The functionality of 6top is to facilitate the dynamic cell
|
||||
negotiation with one-hop neighbors.
|
||||
|
||||
# 6TiSCH Operation Sublayer (6top)
|
||||
This is a Contiki implementation of 6top, developed by:
|
||||
|
||||
## **Overview**
|
||||
|
||||
6TiSCH Operation Sublayer (6top), a logical link layer in the 6TiSCH architecture, provides the abstraction of an IP link over a TSCH MAC layer (IEEE 802.15.4e). The functionality of 6top is to facilitate the dynamic cell negotiation with one-hop neighbors.
|
||||
|
||||
This is a Contiki implementation of 6top, which defines how to handle a 2-step 6top transaction on a basic RPL+TSCH network.
|
||||
|
||||
Developed by:
|
||||
|
||||
- Shalu R, CDAC, shalur@cdac.in, github user: [shalurajendran](https://github.com/shalurajendran)
|
||||
- Shalu R, CDAC, shalur@cdac.in, github user: [shalurajendran](https://github.com/shalurajendran)
|
||||
- Lijo Thomas, CDAC, lijo@cdac.in
|
||||
- Yasuyuki Tanaka
|
||||
|
||||
## **Features**
|
||||
It supports 6P (6top Protocol) of [draft-03](draft-ietf-6tisch-6top-protocol-03)
|
||||
except for concurrent 6P transactions described in [Section
|
||||
4.3.3](https://tools.ietf.org/html/draft-ietf-6tisch-6top-protocol-03#section-4.3.3).
|
||||
|
||||
This implementation includes:
|
||||
## Code Structure
|
||||
|
||||
- 6top protocol(6P)
|
||||
- 6P Add
|
||||
- 6P Delete
|
||||
- 2-step 6top Transaction
|
||||
| File | Contents |
|
||||
|-----------------|--------------------------------|
|
||||
| sixtop.[ch] | 6top external APIs |
|
||||
| sixp.[ch] | 6P I/O APIs |
|
||||
| sixp-nbr.[ch] | 6P Neighbor Management APIs |
|
||||
| sixp-pkt.[ch] | 6P Packet Manipulation APIs |
|
||||
| sixp-trans.[ch] | 6P Transaction Management APIs |
|
||||
| sixp-conf.h | 6P Configuration Parameters |
|
||||
|
||||
The code has been tested on Zolertia Z1 (z1, tested in cooja only) platform.
|
||||
## Configuration Paramters
|
||||
|
||||
## **Code structure**
|
||||
| Parameter | Meaning | Default Value |
|
||||
|--------------------------------------|----------------------------------------------|---------------|
|
||||
| SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS | The maximum number of SFs installed in 6top | 1 |
|
||||
| SIXTOP_CONF_MAX_TRANSACTIONS | The maximum number of transactions at a time | 1 |
|
||||
|
||||
The 6top frame format is included in:
|
||||
## Caveat
|
||||
|
||||
- core/net/mac/frame802154-ie.[ch]: Modified to include Sixtop Information Elements
|
||||
At this moment, allocated 6P neighbor states never be deleted since 6P has no
|
||||
way to decide to delete them. 6P neighbor state consists of SeqNum to be used
|
||||
for a next reqeust, GTX, and GRX (defined in sixp-nbr.c).
|
||||
|
||||
6top is implemented in:
|
||||
Once the number of 6P neighbor states reaches to the `SIXTOP_6P_MAX_NEIGHBORS`,
|
||||
a transaction with a new neighbor may fail due to failure in allocating a 6P
|
||||
neighbor state or schedule generation inconsistency.
|
||||
|
||||
- core/net/mac/tsch/sixtop/sixtop.[ch]: 6top interface and 6top protocol(6P addition and deletion), handling of 6P Requests and Response
|
||||
## Example
|
||||
|
||||
TSCH file modified:
|
||||
An example using 6top is provided under `examples/ipv6/rpl-tsch-sxitop/`.
|
||||
|
||||
- core/net/mac/tsch/tsch.[ch]: Modified to include Sixtop module
|
||||
A simple Scheduling Function (SF) is implemented in `sf-simple.[ch]`. This SF
|
||||
does not have bandwidth monitoring mechanism nor bandwidth adaptation
|
||||
mechanism. Instead, the SF provides APIs so that a user process can add or
|
||||
remove cells dynamically. A sample user process implementation using the SF is
|
||||
found in `node-sixtop.c`, which is tested with `rpl-tsch-sixtop-z1.csc`.
|
||||
|
||||
## Test
|
||||
|
||||
## **Using 6top**
|
||||
6top or 6P related tests are implemented under `regression-tests/26-6tisch`.
|
||||
|
||||
A simple 6top+TSCH+RPL example is included under examples/ipv6/rpl-tsch-sixtop. Currently this application triggers the 6P transactions, later the 6top Scheduling Function (SF) may be implemented for the purpose.
|
||||
## Using 6top
|
||||
|
||||
To use 6top, make sure your platform supports TSCH and have sufficient memory.
|
||||
In order to use 6top with your system, `sixtop` module must be built together in
|
||||
addition to [TSCH](../).
|
||||
|
||||
To add 6top to your application, first include the Sixtop module in your Makefile with:
|
||||
Enable TSCH, then set 1 to `TSCH_CONF_WITH_SIXTOP`, typically, in your
|
||||
`project-conf.h`:
|
||||
|
||||
MODULES += core/net/mac/tsch/sixtop
|
||||
```C
|
||||
#undef TSCH_CONF_WITH_SIXTOP
|
||||
#define TSCH_CONF_WITH_SIXTOP 1
|
||||
```
|
||||
|
||||
Also enable the sixtop functionalities in your project-conf.h file with
|
||||
Next, add `sixtop` into `MODULES` in your Makefile:
|
||||
|
||||
#undef TSCH_CONF_WITH_SIXTOP
|
||||
|
||||
#define TSCH_CONF_WITH_SIXTOP 1
|
||||
```Makefile
|
||||
MODULES += core/net/mac/tsch/sixtop
|
||||
```
|
||||
|
||||
## **Additional documentation**
|
||||
For now, the simple SF mentioned above is only one SF shipped in the code
|
||||
base. You may have to implement your own SF.
|
||||
|
||||
## Implementing a Scheduling Function
|
||||
|
||||
Scheduling Function (SF) is represented with `sixtop_sf_t`, which defined in
|
||||
`sixtop.h`. An SF can be added into 6top by `sixtop_add_sf()`. After the
|
||||
addition, a handler defined in `sixtop_sf_t` is invoked on a correspondent
|
||||
event, for example, reception of a 6P request or timeout of an ongoing
|
||||
transaction.
|
||||
|
||||
SF can send a 6P packet by `sixp_output()`. After every Add or Delete operation,
|
||||
SF needs to advance schedule generation counter associated with the peer by
|
||||
`sixp_advance_generation()`, counter which is maintaeind by 6P. Otherwise, SF
|
||||
will not able to perform any command request other than Clear due to schedule
|
||||
generation inconsistency.
|
||||
|
||||
## References
|
||||
|
||||
1. [IETF 6TiSCH Working Group](https://datatracker.ietf.org/wg/6tisch)
|
||||
2. [6TiSCH 6top Protocol (6P)](https://tools.ietf.org/pdf/draft-ietf-6tisch-6top-protocol-02.pdf)
|
||||
2. [6top Protocol (6P)](https://tools.ietf.org/html/draft-ietf-6tisch-6top-protocol)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/net-debug.h"
|
||||
|
||||
/**
|
||||
* \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;
|
||||
uint8_t gtx;
|
||||
uint8_t grx;
|
||||
} sixp_nbr_t;
|
||||
|
||||
static int advance_generation_counter(uint8_t *gc);
|
||||
|
||||
NBR_TABLE(sixp_nbr_t, sixp_nbrs);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
advance_generation_counter(uint8_t *gc)
|
||||
{
|
||||
assert(gc != NULL);
|
||||
if(gc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
switch(*gc) {
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
*gc = 0x01;
|
||||
break;
|
||||
case 0x01:
|
||||
*gc = 0x02;
|
||||
break;
|
||||
default:
|
||||
/* unexpected condition */
|
||||
PRINTF("6P-nbr: advance_generation_counter() has unexpected gc %02x\n",
|
||||
*gc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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) {
|
||||
PRINTF("6P-nbr: sixp_nbr_alloc() fails because of invalid argument\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(sixp_nbr_find(addr) != NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_alloc() fails because of duplication [peer_addr:");
|
||||
PRINTLLADDR((const uip_lladdr_t *)addr);
|
||||
PRINTF("]\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((nbr = (sixp_nbr_t *)nbr_table_add_lladdr(sixp_nbrs,
|
||||
addr,
|
||||
NBR_TABLE_REASON_SIXTOP,
|
||||
NULL)) == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_alloc() fails to add nbr because of no memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linkaddr_copy(&nbr->addr, addr);
|
||||
nbr->next_seqno = SIXP_INITIAL_SEQUENCE_NUMBER;
|
||||
nbr->gtx = 0;
|
||||
nbr->grx = 0;
|
||||
|
||||
return nbr;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
sixp_nbr_free(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr != NULL) {
|
||||
(void)nbr_table_remove(sixp_nbrs, nbr);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int16_t
|
||||
sixp_nbr_get_gtx(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_get_gtx() fails because of invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
return nbr->gtx;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int8_t
|
||||
sixp_nbr_get_grx(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_get_grx() fails because of invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
return nbr->grx;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_nbr_advance_gtx(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_advance_gtx() fails because of invalid arg\n");
|
||||
return -1;
|
||||
}
|
||||
return advance_generation_counter(&nbr->gtx);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_nbr_advance_grx(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_advance_grx() fails because of invalid arg\n");
|
||||
return -1;
|
||||
}
|
||||
return advance_generation_counter(&nbr->grx);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_get_next_seqno() fails because of invalid arg\n");
|
||||
return -1;
|
||||
}
|
||||
return nbr->next_seqno;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr)
|
||||
{
|
||||
assert(nbr != NULL);
|
||||
if(nbr == NULL) {
|
||||
PRINTF("6P-nbr: sixp_nbr_increment_next_seqno() fails; invalid arg\n");
|
||||
return -1;
|
||||
}
|
||||
nbr->next_seqno++;
|
||||
if(nbr->next_seqno > 0x0f) {
|
||||
/*
|
||||
* nbr->next_seqno, which represents a value of the SeqNum field, won't be
|
||||
* larger than 0x0f since he length of SeqNum field is 4 bits.
|
||||
*/
|
||||
nbr->next_seqno = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_nbr_init(void)
|
||||
{
|
||||
sixp_nbr_t *nbr, *next_nbr;
|
||||
if(nbr_table_is_register(sixp_nbrs) == 0) {
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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 APIs for 6top Protocol (6P)
|
||||
* \author
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "sixp-pkt.h"
|
||||
|
||||
typedef struct sixp_nbr sixp_nbr_t;
|
||||
|
||||
/**
|
||||
* \brief Find a neighbor
|
||||
* \param addr The MAC address of a neighbor
|
||||
* \return The pointer to a neighbor, NULL on failure
|
||||
*/
|
||||
sixp_nbr_t *sixp_nbr_find(const linkaddr_t *addr);
|
||||
|
||||
/**
|
||||
* \brief Allocate a neighbor
|
||||
* \param addr The MAC address of a neighbor
|
||||
* \return The pointer to a allocated neighbor, NULL on failure
|
||||
*/
|
||||
sixp_nbr_t *sixp_nbr_alloc(const linkaddr_t *addr);
|
||||
|
||||
/**
|
||||
* \brief Free a neighbor
|
||||
* \param nbr The pointer to a neighbor to free
|
||||
*/
|
||||
void sixp_nbr_free(sixp_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* \brief Return GTX of a neighbor
|
||||
* \param nbr The pointer to a neighbor
|
||||
* \return A value of GTX, -1 on failure
|
||||
*/
|
||||
int16_t sixp_nbr_get_gtx(sixp_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* \brief Return GRX of a neighbor
|
||||
* \param nbr The pointer to a neighbor
|
||||
* \return A value of GRX
|
||||
*/
|
||||
int16_t sixp_nbr_get_grx(sixp_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* \brief Advance GTX of a neighbor
|
||||
* \param nbr The pointer to a neighbor
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_nbr_advance_gtx(sixp_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* \brief Advance GRX of a neighbor
|
||||
* \param nbr The pointer to a neighbor
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_nbr_advance_grx(sixp_nbr_t *nbr);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the next sequence number of a neighbor
|
||||
* \param nbr The pointer to a neighbor
|
||||
* \return A sequence number to use for a next request, -1 on failure
|
||||
*/
|
||||
int16_t sixp_nbr_get_next_seqno(sixp_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* \brief Increment the next sequence number of a neighbor
|
||||
* \param nbr The pointer to a neighbor
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* \brief Initialize 6p Neighbor Table
|
||||
*/
|
||||
int sixp_nbr_init(void);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Yasuyuki Tanaka.
|
||||
* Copyright (c) 2016, Centre for Development of Advanced Computing (C-DAC).
|
||||
* 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
|
||||
* 6top Protocol (6P) Packet Manipulation
|
||||
* \author
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Lijo Thomas <lijo@cdac.in>
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "contiki-lib.h"
|
||||
#include "lib/assert.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
|
||||
#include "sixp.h"
|
||||
#include "sixp-pkt.h"
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/net-debug.h"
|
||||
|
||||
static int32_t get_metadata_offset(sixp_pkt_type_t type, sixp_pkt_code_t code);
|
||||
static int32_t get_cell_options_offset(sixp_pkt_type_t type,
|
||||
sixp_pkt_code_t code);
|
||||
static int32_t get_num_cells_offset(sixp_pkt_type_t type, sixp_pkt_code_t code);
|
||||
static int32_t get_reserved_offset(sixp_pkt_type_t type, sixp_pkt_code_t code);
|
||||
static int32_t get_offset_offset(sixp_pkt_type_t type, sixp_pkt_code_t code);
|
||||
static int32_t get_max_num_cells_offset(sixp_pkt_type_t type,
|
||||
sixp_pkt_code_t code);
|
||||
static int32_t get_cell_list_offset(sixp_pkt_type_t type, sixp_pkt_code_t code);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_metadata_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST) {
|
||||
return 0; /* offset */
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_cell_options_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST &&
|
||||
(code.cmd == SIXP_PKT_CMD_ADD ||
|
||||
code.cmd == SIXP_PKT_CMD_DELETE ||
|
||||
code.cmd == SIXP_PKT_CMD_STATUS ||
|
||||
code.cmd == SIXP_PKT_CMD_LIST)) {
|
||||
return sizeof(sixp_pkt_metadata_t);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_num_cells_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST &&
|
||||
(code.value == SIXP_PKT_CMD_ADD || code.value == SIXP_PKT_CMD_DELETE)) {
|
||||
return sizeof(sixp_pkt_metadata_t) + sizeof(sixp_pkt_cell_options_t);
|
||||
} else if(type == SIXP_PKT_TYPE_RESPONSE &&
|
||||
code.value == SIXP_PKT_RC_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_reserved_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST &&
|
||||
code.value == SIXP_PKT_CMD_LIST) {
|
||||
return sizeof(sixp_pkt_metadata_t) + sizeof(sixp_pkt_cell_options_t);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_offset_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST &&
|
||||
code.value == SIXP_PKT_CMD_LIST) {
|
||||
return (sizeof(sixp_pkt_metadata_t) +
|
||||
sizeof(sixp_pkt_cell_options_t) +
|
||||
sizeof(sixp_pkt_reserved_t));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_max_num_cells_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST &&
|
||||
code.value == SIXP_PKT_CMD_LIST) {
|
||||
return (sizeof(sixp_pkt_metadata_t) +
|
||||
sizeof(sixp_pkt_cell_options_t) +
|
||||
sizeof(sixp_pkt_reserved_t) +
|
||||
sizeof(sixp_pkt_offset_t));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int32_t
|
||||
get_cell_list_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
|
||||
{
|
||||
if(type == SIXP_PKT_TYPE_REQUEST && (code.value == SIXP_PKT_CMD_ADD ||
|
||||
code.value == SIXP_PKT_CMD_DELETE)) {
|
||||
return (sizeof(sixp_pkt_metadata_t) +
|
||||
sizeof(sixp_pkt_cell_options_t) +
|
||||
sizeof(sixp_pkt_num_cells_t));
|
||||
} else if((type == SIXP_PKT_TYPE_RESPONSE ||
|
||||
type == SIXP_PKT_TYPE_CONFIRMATION) &&
|
||||
code.value == SIXP_PKT_RC_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_metadata_t metadata,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set metadata; body is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_metadata_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set metadata [type=%u, code=%u], invalid type\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(metadata))) {
|
||||
PRINTF("6P-pkt: cannot set metadata, body is too short [body_len=%u]\n",
|
||||
body_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the content into the Metadata field as it is since 6P has no idea
|
||||
* about the internal structure of the field.
|
||||
*/
|
||||
memcpy(body + offset, &metadata, sizeof(metadata));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_metadata_t *metadata,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(metadata == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get metadata; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_metadata_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get metadata [type=%u, code=%u], invalid type\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(*metadata))) {
|
||||
PRINTF("6P-pkt: cannot get metadata [type=%u, code=%u], body is too short\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the content in the Metadata field as it is since 6P has no idea about
|
||||
* the internal structure of the field.
|
||||
*/
|
||||
memcpy(metadata + offset, body, sizeof(*metadata));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_cell_options(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_cell_options_t cell_options,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set cell_options; body is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_cell_options_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set cell_options [type=%u, code=%u], invalid type\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(cell_options))) {
|
||||
PRINTF("6P-pkt: cannot set cell_options, body is too short [body_len=%u]\n",
|
||||
body_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The CellOption field is an 8-bit bitfield */
|
||||
memcpy(body + offset, &cell_options, sizeof(uint8_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_cell_options(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_cell_options_t *cell_options,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(cell_options == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get cell_options; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_cell_options_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get cell_options [type=%u, code=%u], invalid type\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(*cell_options))) {
|
||||
PRINTF("6P-pkt: cannot get cell_options, body is too short [body_len=%u]\n",
|
||||
body_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The CellOption field is an 8-bit bitfield */
|
||||
memcpy(cell_options, body + offset, sizeof(uint8_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_num_cells_t num_cells,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set num_cells; body is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_num_cells_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set num_cells; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have NumCells\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(num_cells))) {
|
||||
PRINTF("6P-pkt: cannot set num_cells; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* NumCells is an 8-bit unsigned integer */
|
||||
memcpy(body + offset, &num_cells, sizeof(num_cells));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_num_cells_t *num_cells,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(num_cells == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get num_cells; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_num_cells_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get num_cells; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have NumCells\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(*num_cells))) {
|
||||
PRINTF("6P-pkt: cannot get num_cells; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* NumCells is an 8-bit unsigned integer */
|
||||
memcpy(num_cells, body + offset, sizeof(uint8_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_reserved(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_reserved_t reserved,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set reserved; body is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_reserved_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set reserved; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have Reserved\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(reserved))) {
|
||||
PRINTF("6P-pkt: cannot set reserved; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The Reserved field is an 8-bit field */
|
||||
memcpy(body + offset, &reserved, sizeof(uint8_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_reserved(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_reserved_t *reserved,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(reserved == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get reserved; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_reserved_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get reserved; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have Reserved\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The Reserved field is an 8-bit field */
|
||||
memcpy(reserved, body + offset, sizeof(uint8_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_offset(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_offset_t cell_offset,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set offset; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_offset_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set offset; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have Offset\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(cell_offset))) {
|
||||
PRINTF("6P-pkt: cannot set offset; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The (Cell)Offset field is 16-bit long; treat it as a little-endian value of
|
||||
* unsigned integer following IEEE 802.15.4-2015.
|
||||
*/
|
||||
(body + offset)[0] = *((uint16_t *)&cell_offset) & 0xff;
|
||||
(body + offset)[1] = (*((uint16_t *)&cell_offset) >> 8) & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_offset(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_offset_t *cell_offset,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
const uint8_t *p;
|
||||
|
||||
if(cell_offset == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get offset; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_offset_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get offset; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have Offset\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(*cell_offset))) {
|
||||
PRINTF("6P-pkt: cannot get offset; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The (Cell)Offset field is 16-bit long; treat it as a little-endian value of
|
||||
* unsigned integer following IEEE 802.15.4-2015.
|
||||
*/
|
||||
p = body + offset;
|
||||
*((uint16_t *)cell_offset) = p[0] + (p[1] << 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_max_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_max_num_cells_t max_num_cells,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set max_num_cells; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_max_num_cells_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set max_num_cells; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have MaxNumCells\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(max_num_cells))) {
|
||||
PRINTF("6P-pkt: cannot set max_num_cells; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The MaxNumCells field is 16-bit long; treat it as a little-endian value of
|
||||
* unsigned integer following IEEE 802.15.4-2015.
|
||||
*/
|
||||
(body + offset)[0] = *((uint16_t *)&max_num_cells) & 0xff;
|
||||
(body + offset)[1] = (*((uint16_t *)&max_num_cells) >> 8) & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_max_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_max_num_cells_t *max_num_cells,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
const uint8_t *p;
|
||||
|
||||
if(max_num_cells == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get max_num_cells; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_max_num_cells_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get max_num_cells; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have MaxNumCells\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < (offset + sizeof(*max_num_cells))) {
|
||||
PRINTF("6P-pkt: cannot get max_num_cells; body is too short\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The MaxNumCells field is 16-bit long; treat it as a little-endian value of
|
||||
* unsigned integer following IEEE 802.15.4-2015.
|
||||
*/
|
||||
p = body + offset;
|
||||
*((uint16_t *)max_num_cells) = p[0] + (p[1] << 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_set_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t *cell_list,
|
||||
uint16_t cell_list_len,
|
||||
uint16_t cell_offset,
|
||||
uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(cell_list == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot set cell_list; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_cell_list_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot set cell_list; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have CellList\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset += cell_offset * sizeof(sixp_pkt_cell_t);
|
||||
|
||||
if(body_len < (offset + cell_list_len)) {
|
||||
PRINTF("6P-pkt: cannot set cell_list; body is too short\n");
|
||||
return -1;
|
||||
} else if((cell_list_len % sizeof(sixp_pkt_cell_t)) != 0) {
|
||||
PRINTF("6P-pkt: cannot set cell_list; invalid {body, cell_list}_len\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(body + offset, cell_list, cell_list_len);
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_get_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t **cell_list,
|
||||
sixp_pkt_offset_t *cell_list_len,
|
||||
const uint8_t *body, uint16_t body_len)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
if(cell_list_len == NULL || body == NULL) {
|
||||
PRINTF("6P-pkt: cannot get cell_list; invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((offset = get_cell_list_offset(type, code)) < 0) {
|
||||
PRINTF("6P-pkt: cannot get cell_list; ");
|
||||
PRINTF("packet [type=%u, code=%u] won't have CellList\n",
|
||||
type, code.value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(body_len < offset) {
|
||||
PRINTF("6P-pkt: cannot set cell_list; body is too short\n");
|
||||
return -1;
|
||||
} else if(((body_len - offset) % sizeof(sixp_pkt_cell_t)) != 0) {
|
||||
PRINTF("6P-pkt: cannot set cell_list; invalid {body, cell_list}_len\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(cell_list != NULL) {
|
||||
*cell_list = body + offset;
|
||||
}
|
||||
|
||||
*cell_list_len = body_len - offset;
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_parse(const uint8_t *buf, uint16_t len,
|
||||
sixp_pkt_t *pkt)
|
||||
{
|
||||
assert(buf != NULL && pkt != NULL);
|
||||
if(buf == NULL || pkt == NULL) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read the first 4 octets */
|
||||
if(len < 4) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because it's a too short packet\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((buf[0] & 0x0f) != SIXP_PKT_VERSION) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid version [%u]\n",
|
||||
buf[0] & 0x0f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(pkt, 0, sizeof(sixp_pkt_t));
|
||||
pkt->type = (buf[0] & 0x30) >> 4;
|
||||
pkt->code.value = buf[1];
|
||||
pkt->sfid = buf[2];
|
||||
pkt->seqno = buf[3] & 0x0f;
|
||||
pkt->gab = (buf[3] & 0x30) >> 4;
|
||||
pkt->gba = (buf[3] & 0xc0) >> 6;
|
||||
|
||||
buf += 4;
|
||||
len -= 4;
|
||||
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() is processing [type:%u, code:%u, len:%u]\n",
|
||||
pkt->type, pkt->code.value, len);
|
||||
|
||||
/* the rest is message body called "Other Fields" */
|
||||
if(pkt->type == SIXP_PKT_TYPE_REQUEST) {
|
||||
switch(pkt->code.cmd) {
|
||||
case SIXP_PKT_CMD_ADD:
|
||||
case SIXP_PKT_CMD_DELETE:
|
||||
/* Add and Delete has the same request format */
|
||||
if(len < (sizeof(sixp_pkt_metadata_t) +
|
||||
sizeof(sixp_pkt_cell_options_t) +
|
||||
sizeof(sixp_pkt_num_cells_t)) ||
|
||||
(len % sizeof(uint32_t)) != 0) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SIXP_PKT_CMD_STATUS:
|
||||
if(len != (sizeof(sixp_pkt_metadata_t) +
|
||||
sizeof(sixp_pkt_cell_options_t))) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SIXP_PKT_CMD_LIST:
|
||||
if(len != (sizeof(sixp_pkt_metadata_t) +
|
||||
sizeof(sixp_pkt_cell_options_t) +
|
||||
sizeof(sixp_pkt_reserved_t) +
|
||||
sizeof(sixp_pkt_offset_t) +
|
||||
sizeof(sixp_pkt_max_num_cells_t))) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SIXP_PKT_CMD_CLEAR:
|
||||
if(len != sizeof(sixp_pkt_metadata_t)) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of unsupported cmd\n");
|
||||
return -1;
|
||||
}
|
||||
} else if(pkt->type == SIXP_PKT_TYPE_RESPONSE ||
|
||||
pkt->type == SIXP_PKT_TYPE_CONFIRMATION) {
|
||||
switch(pkt->code.rc) {
|
||||
case SIXP_PKT_RC_SUCCESS:
|
||||
/*
|
||||
* The "Other Field" contains
|
||||
* - Res to CLEAR: Empty (length 0)
|
||||
* - Res to STATUS: "Num. Cells"
|
||||
* - Res to ADD, DELETE, LIST: 0, 1, or multiple 6P cells
|
||||
*/
|
||||
if(len != 0 &&
|
||||
len != sizeof(sixp_pkt_num_cells_t) &&
|
||||
(len % sizeof(uint32_t)) != 0) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SIXP_PKT_RC_ERR_VER:
|
||||
case SIXP_PKT_RC_ERR_SFID:
|
||||
case SIXP_PKT_RC_ERR_GEN:
|
||||
case SIXP_PKT_RC_ERR_BUSY:
|
||||
case SIXP_PKT_RC_ERR_NORES:
|
||||
case SIXP_PKT_RC_ERR_RESET:
|
||||
case SIXP_PKT_RC_ERR:
|
||||
if(len != 0) {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of unsupported code\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
PRINTF("6P-pkt: sixp_pkt_parse() fails because of unsupported type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pkt->body = buf;
|
||||
pkt->body_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
uint8_t sfid, uint8_t seqno, uint8_t gab, uint8_t gba,
|
||||
const uint8_t *body, uint16_t body_len, sixp_pkt_t *pkt)
|
||||
{
|
||||
uint8_t *hdr;
|
||||
|
||||
assert((body == NULL && body_len == 0) || (body != NULL && body_len > 0));
|
||||
if((body == NULL && body_len > 0) || (body != NULL && body_len == 0)) {
|
||||
PRINTF("6P-pkt: sixp_pkt_create() fails because of invalid argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
packetbuf_clear();
|
||||
|
||||
/*
|
||||
* We're going to create a packet having 6top IE header (4 octets) and body
|
||||
* (body_len octets).
|
||||
*/
|
||||
if(PACKETBUF_SIZE < (packetbuf_totlen() + body_len)) {
|
||||
PRINTF("6P-pkt: sixp_pkt_create() fails because body is too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(packetbuf_hdralloc(4) != 1) {
|
||||
PRINTF("6P-pkt: sixp_pkt_create fails to allocate header space\n");
|
||||
return -1;
|
||||
}
|
||||
hdr = packetbuf_hdrptr();
|
||||
/* header: write the 6top IE header, 4 octets */
|
||||
hdr[0] = (type << 4) | SIXP_PKT_VERSION;
|
||||
hdr[1] = code.value;
|
||||
hdr[2] = sfid;
|
||||
hdr[3] = (gab << 4) | (gba << 6) | seqno;
|
||||
|
||||
/* data: write body */
|
||||
if(body_len > 0 && body != NULL) {
|
||||
memcpy(packetbuf_dataptr(), body, body_len);
|
||||
packetbuf_set_datalen(body_len);
|
||||
}
|
||||
|
||||
/* copy information of a sending packet into pkt if necessary */
|
||||
if(pkt != NULL) {
|
||||
pkt->type = type;
|
||||
pkt->code = code;
|
||||
pkt->sfid = sfid;
|
||||
pkt->seqno = seqno;
|
||||
pkt->gab = gab;
|
||||
pkt->gba = gba;
|
||||
pkt->body = body;
|
||||
pkt->body_len = body_len;
|
||||
}
|
||||
|
||||
/* packetbuf is ready to be sent */
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Yasuyuki Tanaka
|
||||
* Copyright (c) 2016, Centre for Development of Advanced Computing (C-DAC).
|
||||
* 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
|
||||
* 6top Protocol (6P) Packet Manipulation APIs
|
||||
* \author
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Lijo Thomas <lijo@cdac.in>
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
#ifndef _SIXTOP_6P_PACKET_H_
|
||||
#define _SIXTOP_6P_PACKET_H_
|
||||
|
||||
#define SIXP_PKT_VERSION 0x01
|
||||
|
||||
/* typedefs for code readability */
|
||||
typedef uint8_t sixp_pkt_cell_options_t;
|
||||
typedef uint8_t sixp_pkt_num_cells_t;
|
||||
typedef uint8_t sixp_pkt_reserved_t;
|
||||
typedef uint16_t sixp_pkt_metadata_t;
|
||||
typedef uint16_t sixp_pkt_max_num_cells_t;
|
||||
typedef uint16_t sixp_pkt_offset_t;
|
||||
typedef uint32_t sixp_pkt_cell_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Message Types
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_PKT_TYPE_REQUEST = 0x00, /**< 6P Request */
|
||||
SIXP_PKT_TYPE_RESPONSE = 0x01, /**< 6P Response */
|
||||
SIXP_PKT_TYPE_CONFIRMATION = 0x02, /**< 6P Confirmation */
|
||||
SIXP_PKT_TYPE_RESERVED = 0x03, /**< Reserved */
|
||||
} sixp_pkt_type_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Command Identifiers
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_PKT_CMD_ADD = 0x01, /**< CMD_ADD */
|
||||
SIXP_PKT_CMD_DELETE = 0x02, /**< CMD_DELETE */
|
||||
SIXP_PKT_CMD_STATUS = 0x03, /**< CMD_STATUS */
|
||||
SIXP_PKT_CMD_LIST = 0x04, /**< CMD_LIST */
|
||||
SIXP_PKT_CMD_CLEAR = 0x05, /**< CMD_CLEAR */
|
||||
SIXP_PKT_CMD_UNAVAILABLE /**< for internal use */
|
||||
} sixp_pkt_cmd_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Return Codes
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_PKT_RC_SUCCESS = 0x06, /**< RC_SUCCESS */
|
||||
SIXP_PKT_RC_ERR_VER = 0x07, /**< RC_ERR_VER */
|
||||
SIXP_PKT_RC_ERR_SFID = 0x08, /**< RC_ERR_SFID */
|
||||
SIXP_PKT_RC_ERR_GEN = 0x09, /**< RC_ERR_GEN */
|
||||
SIXP_PKT_RC_ERR_BUSY = 0x0a, /**< RC_ERR_BUSY */
|
||||
SIXP_PKT_RC_ERR_NORES = 0x0b, /**< RC_ERR_NORES */
|
||||
SIXP_PKT_RC_ERR_RESET = 0x0c, /**< RC_ERR_RESET */
|
||||
SIXP_PKT_RC_ERR = 0x0d, /**< RC_ERR */
|
||||
} sixp_pkt_rc_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Codes integrating Command IDs and Return Codes
|
||||
*/
|
||||
typedef union {
|
||||
sixp_pkt_cmd_t cmd; /**< 6P Command Identifier */
|
||||
sixp_pkt_rc_t rc; /**< 6P Return Code */
|
||||
uint8_t value; /**< 8-bit unsigned integer value */
|
||||
} sixp_pkt_code_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Cell Options
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_PKT_CELL_OPTION_TX = 0x01, /**< TX Cell */
|
||||
SIXP_PKT_CELL_OPTION_RX = 0x02, /**< RX Cell */
|
||||
SIXP_PKT_CELL_OPTION_SHARED = 0x04 /**< SHARED Cell */
|
||||
} sixp_pkt_cell_option_t;
|
||||
|
||||
/**
|
||||
* \brief 6top IE Structure
|
||||
*/
|
||||
typedef struct {
|
||||
sixp_pkt_type_t type; /**< Type */
|
||||
sixp_pkt_code_t code; /**< Code */
|
||||
uint8_t sfid; /**< SFID */
|
||||
uint8_t seqno; /**< SeqNum */
|
||||
uint8_t gab; /**< GAB */
|
||||
uint8_t gba; /**< GBA */
|
||||
const uint8_t *body; /**< Other Fields... */
|
||||
uint16_t body_len; /**< The length of Other Fields */
|
||||
} sixp_pkt_t;
|
||||
|
||||
/**
|
||||
* \brief Write Metadata into "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param metadata Metadata to write
|
||||
* \param body The pointer to "Other Fields" in a buffer
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_metadata_t metadata,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read Metadata stored in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param metadata The pointer to a buffer to store Metadata in
|
||||
* \param body The pointer to the buffer having "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_metadata_t *metadata,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write CellOptions in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param cell_options "CellOptions" to write
|
||||
* \param body The pointer to buffer having "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_cell_options(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_cell_options_t cell_options,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read CellOptions in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param cell_options The pointer to buffer to store CellOptions in
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_cell_options(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_cell_options_t *cell_options,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write NumCells in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param num_cells "NumCells" to write
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_num_cells_t num_cells,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read NumCells in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param num_cells The pointer to buffer to store NumCells in
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_num_cells_t *num_cells,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
/**
|
||||
* \brief Write Reserved in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param reserved "Reserved" to write
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_reserved(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_reserved_t reserved,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read Reserved in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param reserved The pointer to buffer to store Reserved in
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_reserved(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_reserved_t *reserved,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write Offset in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param offset "Offset" to write
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_offset(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_offset_t offset,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
/**
|
||||
* \brief Read Offset in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param offset The pointer to buffer to store Offset in
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_offset(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_offset_t *offset,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write MaxNumCells in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param max_num_cells "MaxNumCells" to write
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_max_num_cells(sixp_pkt_type_t type,
|
||||
sixp_pkt_code_t code,
|
||||
sixp_pkt_max_num_cells_t max_num_cells,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read MaxNumCells in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param max_num_cells The pointer to buffer to store MaxNumCells in
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_max_num_cells(sixp_pkt_type_t type,
|
||||
sixp_pkt_code_t code,
|
||||
sixp_pkt_max_num_cells_t *max_num_cells,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write CellList in "Other Fields" of 6P packet
|
||||
* \note "offset" is specified by index in CellList
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param cell_list The pointer to "CellList" to write
|
||||
* \param cell_list_len Length to write
|
||||
* \param offset Offset in the "CellList" field to start writing
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t *cell_list,
|
||||
uint16_t cell_list_len,
|
||||
uint16_t offset,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
/**
|
||||
* \brief Read CellList in "Other Fields" of 6P packet
|
||||
* \note If you want only the length of CellList, you can set null to cell_list.
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param cell_list The double pointer to store the starting address of CellList
|
||||
* \param cell_list_len Pointer to store the length of CellList
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t **cell_list,
|
||||
sixp_pkt_offset_t *cell_list_len,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write RelCellList in "Other Fields" of 6P packet
|
||||
* \note "offset" is specified by index in RelCellList
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param rel_cell_list The pointer to "RelCellList" to write
|
||||
* \param rel_cell_list_len Length to write
|
||||
* \param offset Offset in the "RelCellList" field to start writing
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_rel_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t *rel_cell_list,
|
||||
uint16_t rel_cell_list_len,
|
||||
uint16_t offset,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read RelCellList in "Other Fields" of 6P packet
|
||||
* \note If you want only the length of RelCellList, you can set null to
|
||||
* rel_cell_list.
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param rel_cell_list The double pointer to store the starting address of
|
||||
* RelCellList
|
||||
* \param rel_cell_list_len Pointer to store the length of a returned
|
||||
* RelCellList
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_rel_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t **rel_cell_list,
|
||||
sixp_pkt_offset_t *rel_cell_list_len,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write CandCellList in "Other Fields" of 6P packet
|
||||
* \note "offset" is specified by index in CandCellList
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param cand_cell_list The pointer to "CandCellList" to write
|
||||
* \param cand_cell_list_len Length to write
|
||||
* \param offset Offset in the "CandCellList" field to start writing
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_cand_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t *cand_cell_list,
|
||||
uint16_t cand_cell_list_len,
|
||||
uint16_t offset,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read CandCellList in "Other Fields" of 6P packet
|
||||
* \note If you want only the length of CandCellList, you can set null to
|
||||
* cell_list.
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param cand_cell_list The double pointer to store the starting address of
|
||||
* CandCellList
|
||||
* \param cand_cell_list_len Pointer to store the length of CandCellList
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_cand_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
const uint8_t **cand_cell_list,
|
||||
sixp_pkt_offset_t *cand_cell_list_len,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Write TotalNumCells in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param total_num_cells "TotalNumCells" to write
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_set_total_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_total_num_cells_t total_num_cells,
|
||||
uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Read TotalNumCells in "Other Fields" of 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Command Identifier or Return Code
|
||||
* \param total_num_cells The pointer to buffer to store TotalNumCells in
|
||||
* \param body The pointer to buffer pointing to "Other Fields"
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_get_total_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
sixp_pkt_total_num_cells_t *total_num_cells,
|
||||
const uint8_t *body, uint16_t body_len);
|
||||
|
||||
/**
|
||||
* \brief Parse a 6P packet
|
||||
* \param buf The pointer to a buffer pointing 6top IE Content
|
||||
* \param len The length of the buffer
|
||||
* \param pkt The pointer to a sixp_pkt_t structure to store packet info
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_parse(const uint8_t *buf, uint16_t len,
|
||||
sixp_pkt_t *pkt);
|
||||
|
||||
/**
|
||||
* \brief Create a 6P packet
|
||||
* \param type 6P Message Type
|
||||
* \param code 6P Message Code, Command Identifier or Return Code
|
||||
* \param sfid Scheduling Function Identifier
|
||||
* \param seqno Sequence Number
|
||||
* \param gab GAB
|
||||
* \param gba GBA
|
||||
* \param body The pointer to "Other Fields" in a buffer
|
||||
* \param body_len The length of body, typically "Other Fields" length
|
||||
* \param pkt The pointer to a sixp_pkt_t structure to store packet info
|
||||
* (option)
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
uint8_t sfid, uint8_t seqno, uint8_t gab, uint8_t gba,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
sixp_pkt_t *pkt);
|
||||
|
||||
#endif /* !_SIXP_PKT_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* 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
|
||||
* Transaction Management for 6top Protocol (6P)
|
||||
* \author
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "contiki-lib.h"
|
||||
#include "lib/assert.h"
|
||||
|
||||
#include "sixtop.h"
|
||||
#include "sixtop-conf.h"
|
||||
#include "sixp-trans.h"
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/net-debug.h"
|
||||
|
||||
/**
|
||||
* \brief 6P Transaction Data Structure (for internal use)
|
||||
*/
|
||||
typedef struct sixp_trans {
|
||||
struct sixp_trans *next;
|
||||
const sixtop_sf_t *sf;
|
||||
linkaddr_t peer_addr;
|
||||
uint8_t seqno;
|
||||
sixp_pkt_cmd_t cmd;
|
||||
sixp_trans_state_t state;
|
||||
sixp_trans_mode_t mode;
|
||||
struct {
|
||||
sixp_sent_callback_t func;
|
||||
void *arg;
|
||||
uint16_t arg_len;
|
||||
} callback;
|
||||
struct ctimer timer;
|
||||
} sixp_trans_t;
|
||||
|
||||
static void handle_trans_timeout(void *ptr);
|
||||
static void process_trans(void *ptr);
|
||||
static void schedule_trans_process(sixp_trans_t *trans);
|
||||
static void free_trans(sixp_trans_t *trans);
|
||||
static sixp_trans_mode_t determine_trans_mode(const sixp_pkt_t *req);
|
||||
|
||||
MEMB(trans_memb, sixp_trans_t, SIXTOP_MAX_TRANSACTIONS);
|
||||
LIST(trans_list);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
handle_trans_timeout(void *ptr)
|
||||
{
|
||||
sixp_trans_t *trans = (sixp_trans_t *)ptr;
|
||||
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(trans->sf->timeout != NULL) {
|
||||
trans->sf->timeout(trans->cmd,
|
||||
(const linkaddr_t *)&trans->peer_addr);
|
||||
}
|
||||
|
||||
(void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
process_trans(void *ptr)
|
||||
{
|
||||
sixp_trans_t *trans = (sixp_trans_t *)ptr;
|
||||
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure that the timer is stopped */
|
||||
ctimer_stop(&trans->timer);
|
||||
|
||||
/* state-specific operation */
|
||||
if(trans->state == SIXP_TRANS_STATE_TERMINATING) {
|
||||
/* handle the terminating state first */
|
||||
PRINTF("6P-trans: trans [peer_addr:");
|
||||
PRINTLLADDR((const uip_lladdr_t *)&trans->peer_addr);
|
||||
PRINTF(", seqno:%u] is going to be freed\n", trans->seqno);
|
||||
free_trans(trans);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(trans->state) {
|
||||
/* do for others */
|
||||
case SIXP_TRANS_STATE_RESPONSE_SENT:
|
||||
case SIXP_TRANS_STATE_RESPONSE_RECEIVED:
|
||||
if(trans->mode == SIXP_TRANS_MODE_2_STEP) {
|
||||
(void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
|
||||
}
|
||||
break;
|
||||
case SIXP_TRANS_STATE_CONFIRMATION_SENT:
|
||||
case SIXP_TRANS_STATE_CONFIRMATION_RECEIVED:
|
||||
(void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
|
||||
break;
|
||||
case SIXP_TRANS_STATE_TERMINATING:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(trans->state != SIXP_TRANS_STATE_TERMINATING) {
|
||||
/* set the timer with a timeout values defined by the SF */
|
||||
ctimer_set(&trans->timer, trans->sf->timeout_interval,
|
||||
handle_trans_timeout, trans);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
schedule_trans_process(sixp_trans_t *trans)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctimer_stop(&trans->timer);
|
||||
ctimer_set(&trans->timer, 0, process_trans, trans); /* expires immediately */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
free_trans(sixp_trans_t *trans)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_remove(trans_list, trans);
|
||||
memb_free(&trans_memb, trans);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static sixp_trans_mode_t
|
||||
determine_trans_mode(const sixp_pkt_t *req)
|
||||
{
|
||||
uint16_t cell_list_len;
|
||||
|
||||
assert(req != NULL);
|
||||
if(req == NULL) {
|
||||
return SIXP_TRANS_MODE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We consider a transaction as 3-step if and only if its request command is
|
||||
* either Add or Delete AND its cell_list is empty. Otherwise, 2-step.
|
||||
*/
|
||||
if(req->type == SIXP_PKT_TYPE_REQUEST &&
|
||||
(req->code.cmd == SIXP_PKT_CMD_ADD ||
|
||||
req->code.cmd == SIXP_PKT_CMD_DELETE) &&
|
||||
sixp_pkt_get_cell_list(req->type, (sixp_pkt_code_t)req->code.value,
|
||||
NULL, &cell_list_len,
|
||||
req->body, req->body_len) == 0 &&
|
||||
cell_list_len == 0) {
|
||||
return SIXP_TRANS_MODE_3_STEP;
|
||||
}
|
||||
|
||||
return SIXP_TRANS_MODE_2_STEP;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
PRINTF("6top: invalid argument, trans is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* enforce state transition rules */
|
||||
if(new_state == SIXP_TRANS_STATE_TERMINATING ||
|
||||
(new_state == SIXP_TRANS_STATE_REQUEST_SENT &&
|
||||
trans->state == SIXP_TRANS_STATE_INIT) ||
|
||||
(new_state == SIXP_TRANS_STATE_REQUEST_RECEIVED &&
|
||||
trans->state == SIXP_TRANS_STATE_INIT) ||
|
||||
(new_state == SIXP_TRANS_STATE_RESPONSE_SENT &&
|
||||
trans->state == SIXP_TRANS_STATE_REQUEST_RECEIVED) ||
|
||||
(new_state == SIXP_TRANS_STATE_RESPONSE_RECEIVED &&
|
||||
trans->state == SIXP_TRANS_STATE_REQUEST_SENT) ||
|
||||
(new_state == SIXP_TRANS_STATE_CONFIRMATION_RECEIVED &&
|
||||
trans->state == SIXP_TRANS_STATE_RESPONSE_SENT &&
|
||||
trans->mode == SIXP_TRANS_MODE_3_STEP) ||
|
||||
(new_state == SIXP_TRANS_STATE_CONFIRMATION_SENT &&
|
||||
trans->state == SIXP_TRANS_STATE_RESPONSE_RECEIVED &&
|
||||
trans->mode == SIXP_TRANS_MODE_3_STEP)) {
|
||||
PRINTF("6P-trans: trans %p state changes from %u to %u\n",
|
||||
trans, trans->state, new_state);
|
||||
trans->state = new_state;
|
||||
schedule_trans_process(trans);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* invalid transition */
|
||||
PRINTF("6P-trans: invalid transaction, from %u to %u, detected on trans %p\n",
|
||||
trans->state, new_state, trans);
|
||||
return -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
sixp_pkt_cmd_t
|
||||
sixp_trans_get_cmd(sixp_trans_t *trans)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return SIXP_PKT_CMD_UNAVAILABLE;
|
||||
}
|
||||
return trans->cmd;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
sixp_trans_state_t
|
||||
sixp_trans_get_state(sixp_trans_t *trans)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return SIXP_TRANS_STATE_UNAVAILABLE;
|
||||
}
|
||||
return trans->state;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int16_t
|
||||
sixp_trans_get_seqno(sixp_trans_t *trans)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
PRINTF("6P-trans: sixp_trans_get_seqno() fails because trans is NULL\n");
|
||||
return -1;
|
||||
}
|
||||
return trans->seqno;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
sixp_trans_mode_t
|
||||
sixp_trans_get_mode(sixp_trans_t *trans)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
PRINTF("6P-trans: sixp_trans_get_mode() fails because trans is NULL\n");
|
||||
return SIXP_TRANS_STATE_UNAVAILABLE;
|
||||
}
|
||||
return trans->mode;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
sixp_trans_invoke_callback(sixp_trans_t *trans, sixp_output_status_t status)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
|
||||
if(trans == NULL || trans->callback.func == NULL) {
|
||||
return;
|
||||
}
|
||||
trans->callback.func(trans->callback.arg, trans->callback.arg_len,
|
||||
&trans->peer_addr, status);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
sixp_trans_set_callback(sixp_trans_t *trans,
|
||||
sixp_sent_callback_t func, void *arg, uint16_t arg_len)
|
||||
{
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
return;
|
||||
}
|
||||
trans->callback.func = func;
|
||||
trans->callback.arg = arg;
|
||||
trans->callback.arg_len = arg_len;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
sixp_trans_t *
|
||||
sixp_trans_alloc(const sixp_pkt_t *pkt, const linkaddr_t *peer_addr)
|
||||
{
|
||||
const sixtop_sf_t *sf;
|
||||
sixp_trans_t *trans;
|
||||
|
||||
assert(pkt != NULL && peer_addr != NULL);
|
||||
if(pkt == NULL || peer_addr == NULL) {
|
||||
PRINTF("6P-trans: sixp_trans_alloc() fails because of invalid argument\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((sf = sixtop_find_sf(pkt->sfid)) == NULL) {
|
||||
PRINTF("6P-trans: sixp_trans_alloc() fails; no suitable SF [sfid:%u]\n",
|
||||
pkt->sfid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(sixp_trans_find(peer_addr) != NULL) {
|
||||
PRINTF("6P-trans: sixp_trans_alloc() fails because another trans with ");
|
||||
PRINTLLADDR((const uip_lladdr_t *)peer_addr);
|
||||
PRINTF("is in process\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((trans = memb_alloc(&trans_memb)) == NULL) {
|
||||
PRINTF("6P-trans: sixp_trans_alloc() fails because of lack of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(trans, 0, sizeof(sixp_trans_t));
|
||||
trans->sf = sf;
|
||||
trans->peer_addr = *peer_addr;
|
||||
trans->seqno = pkt->seqno;
|
||||
trans->cmd = pkt->code.value;
|
||||
trans->state = SIXP_TRANS_STATE_INIT;
|
||||
trans->mode = determine_trans_mode(pkt);
|
||||
list_add(trans_list, trans);
|
||||
|
||||
return trans;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
sixp_trans_t *
|
||||
sixp_trans_find(const linkaddr_t *peer_addr)
|
||||
{
|
||||
sixp_trans_t *trans;
|
||||
|
||||
assert(peer_addr != NULL);
|
||||
if(peer_addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: we don't support concurrent 6P transactions which is mentioned in
|
||||
* Section 4.3.3, draft-ietf-6tisch-6top-protocol-03.
|
||||
*
|
||||
* The assumption here is that there is one transactions for a single peer at
|
||||
* most.
|
||||
*/
|
||||
for(trans = list_head(trans_list);
|
||||
trans != NULL; trans = trans->next) {
|
||||
if(memcmp(peer_addr, &trans->peer_addr, sizeof(linkaddr_t)) == 0) {
|
||||
return trans;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_trans_init(void)
|
||||
{
|
||||
sixp_trans_t *trans, *next_trans;
|
||||
|
||||
/* make sure there's no timer task left before the initialization */
|
||||
for(trans = list_head(trans_list);
|
||||
trans != NULL; trans = next_trans) {
|
||||
next_trans = trans->next;
|
||||
ctimer_stop(&trans->timer);
|
||||
free_trans(trans);
|
||||
}
|
||||
|
||||
list_init(trans_list);
|
||||
memb_init(&trans_memb);
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* 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
|
||||
* Transaction Management APIs for 6top Protocol (6P)
|
||||
* \author
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "sixp.h"
|
||||
#include "sixp-pkt.h"
|
||||
|
||||
/**
|
||||
* \brief 6P Transaction States (for internal use)
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_TRANS_STATE_UNAVAILABLE = 0,
|
||||
SIXP_TRANS_STATE_INIT,
|
||||
SIXP_TRANS_STATE_REQUEST_SENT,
|
||||
SIXP_TRANS_STATE_REQUEST_RECEIVED,
|
||||
SIXP_TRANS_STATE_RESPONSE_SENT,
|
||||
SIXP_TRANS_STATE_RESPONSE_RECEIVED,
|
||||
SIXP_TRANS_STATE_CONFIRMATION_SENT,
|
||||
SIXP_TRANS_STATE_CONFIRMATION_RECEIVED,
|
||||
SIXP_TRANS_STATE_TERMINATING,
|
||||
} sixp_trans_state_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Transaction Modes (for internal use)
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_TRANS_MODE_UNAVAILABLE = 0,
|
||||
SIXP_TRANS_MODE_2_STEP,
|
||||
SIXP_TRANS_MODE_3_STEP
|
||||
} sixp_trans_mode_t;
|
||||
|
||||
typedef struct sixp_trans sixp_trans_t;
|
||||
|
||||
/**
|
||||
* \brief Change the state of a specified transaction
|
||||
* \param trans The pointer to a transaction
|
||||
* \param new_state New state to move the transaction to
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_trans_transit_state(sixp_trans_t *trans,
|
||||
sixp_trans_state_t new_state);
|
||||
|
||||
/**
|
||||
* \brief Return the command associated with a specified transaction
|
||||
* \param trans The pointer to a transaction
|
||||
* \return Command identifier; SIXP_PKT_CMD_UNAVAILABLE on failure
|
||||
*/
|
||||
sixp_pkt_cmd_t sixp_trans_get_cmd(sixp_trans_t *trans);
|
||||
|
||||
/**
|
||||
* \brief Return the state of a specified transaction
|
||||
* \param trans The pointer to a transaction
|
||||
* \return a state of the transaction; SIXP_TRANS_STATE_UNAVAILABLE if the
|
||||
* transaction is not found in the system.
|
||||
*/
|
||||
sixp_trans_state_t sixp_trans_get_state(sixp_trans_t *trans);
|
||||
|
||||
/**
|
||||
* \brief Return the sequence number associated with a specified transaction
|
||||
* \param trans The pointer of a transaction
|
||||
* \return 0 or larger than 0 on success, -1 on failure
|
||||
*/
|
||||
int16_t sixp_trans_get_seqno(sixp_trans_t *trans);
|
||||
|
||||
/**
|
||||
* \brief Return the mode, 2-step or 3-step, of a specified transaction
|
||||
* \param trans The pointer to a transaction
|
||||
* \return The mode of the transaction, SIXP_TRANS_MODE_UNAVAILABLE on failure
|
||||
*/
|
||||
sixp_trans_mode_t sixp_trans_get_mode(sixp_trans_t *trans);
|
||||
|
||||
/**
|
||||
* \brief Invoke the output callback of a specified transaction
|
||||
* \param trans The pointer to a transaction
|
||||
* \param status An output result value
|
||||
*/
|
||||
void sixp_trans_invoke_callback(sixp_trans_t *trans,
|
||||
sixp_output_status_t status);
|
||||
|
||||
/**
|
||||
* \brief Set an output callback to a specified transaction
|
||||
* \param trans The pointer to a transaction
|
||||
* \param func The pointer to a callback function
|
||||
* \param arg The pointer to an argument which will be passed to func
|
||||
* \param arg_len The length of the argument
|
||||
*/
|
||||
void sixp_trans_set_callback(sixp_trans_t *trans,
|
||||
sixp_sent_callback_t func,
|
||||
void *arg,
|
||||
uint16_t arg_len);
|
||||
|
||||
/**
|
||||
* \brief Allocate a transaction
|
||||
* \param pkt The pointer to a packet which triggers the allocation
|
||||
* \param peer_addr The peer address which will be associated
|
||||
* \return A pointer to an newly allocated transaction, NULL on failure
|
||||
*/
|
||||
sixp_trans_t *sixp_trans_alloc(const sixp_pkt_t *pkt,
|
||||
const linkaddr_t *peer_addr);
|
||||
|
||||
/**
|
||||
* \brief Find a transaction
|
||||
* \param peer_addr The peer address
|
||||
* \return The pointer to a transaction; NULL on failure
|
||||
*/
|
||||
sixp_trans_t *sixp_trans_find(const linkaddr_t *peer_addr);
|
||||
|
||||
/**
|
||||
* \brief Initialize Memory and List for 6P transactions
|
||||
* This function removes and frees existing transactions.
|
||||
*/
|
||||
int sixp_trans_init(void);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* 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
|
||||
* 6top Protocol (6P)
|
||||
* \author
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#include "contiki-lib.h"
|
||||
#include "lib/assert.h"
|
||||
|
||||
#include "sixtop.h"
|
||||
#include "sixp-nbr.h"
|
||||
#include "sixp-pkt.h"
|
||||
#include "sixp-trans.h"
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/net-debug.h"
|
||||
|
||||
static void mac_callback(void *ptr, int status, int transmissions);
|
||||
static int send_back_error(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
uint8_t sfid, uint8_t seqno,
|
||||
const linkaddr_t *dest_addr);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mac_callback(void *ptr, int status, int transmissions)
|
||||
{
|
||||
sixp_trans_t *trans = (sixp_trans_t *)ptr;
|
||||
sixp_trans_state_t new_state, current_state;
|
||||
|
||||
assert(trans != NULL);
|
||||
if(trans == NULL) {
|
||||
PRINTF("6P: mac_callback() fails because trans is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
current_state = sixp_trans_get_state(trans);
|
||||
if(status == MAC_TX_OK) {
|
||||
switch(current_state) {
|
||||
case SIXP_TRANS_STATE_INIT:
|
||||
new_state = SIXP_TRANS_STATE_REQUEST_SENT;
|
||||
break;
|
||||
case SIXP_TRANS_STATE_REQUEST_RECEIVED:
|
||||
new_state = SIXP_TRANS_STATE_RESPONSE_SENT;
|
||||
break;
|
||||
case SIXP_TRANS_STATE_RESPONSE_RECEIVED:
|
||||
new_state = SIXP_TRANS_STATE_CONFIRMATION_SENT;
|
||||
break;
|
||||
default:
|
||||
PRINTF("6P: mac_callback() fails because of an unexpected state (%u)\n",
|
||||
current_state);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* In a case of transmission failure of a request, a corresponding SF would
|
||||
* retransmit the request with a new transaction. For a response or a
|
||||
* confirmation, the same transaction will be used for retransmission as
|
||||
* long as it doesn't have timeout.
|
||||
*/
|
||||
if(current_state == SIXP_TRANS_STATE_INIT) {
|
||||
/* request case */
|
||||
new_state = SIXP_TRANS_STATE_TERMINATING;
|
||||
} else {
|
||||
/* response or confirmation case: stay the same state */
|
||||
new_state = current_state;
|
||||
}
|
||||
}
|
||||
|
||||
if(new_state != current_state &&
|
||||
sixp_trans_transit_state(trans, new_state) != 0) {
|
||||
PRINTF("6P: mac_callback() fails because of state transition failure\n");
|
||||
PRINTF("6P: something wrong; we're terminating the trans %p\n", trans);
|
||||
(void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
sixp_trans_invoke_callback(trans,
|
||||
status == MAC_TX_OK ?
|
||||
SIXP_OUTPUT_STATUS_SUCCESS :
|
||||
SIXP_OUTPUT_STATUS_FAILURE);
|
||||
sixp_trans_set_callback(trans, NULL, NULL, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
send_back_error(sixp_pkt_type_t type, sixp_pkt_code_t code,
|
||||
uint8_t sfid, uint8_t seqno,
|
||||
const linkaddr_t *dest_addr)
|
||||
{
|
||||
/* create a 6P packet within packetbuf */
|
||||
/* XXX: set 0 as GAB and GBA for a error response */
|
||||
/* XXX: how can we make a confirmation having an error return value? */
|
||||
if(sixp_pkt_create(type, code, sfid, seqno, 0, 0, NULL, 0, NULL) < 0) {
|
||||
PRINTF("6P: failed to create a 6P packet to return an error [rc:%u]\n",
|
||||
code.value);
|
||||
return -1;
|
||||
}
|
||||
/* we don't care about how the transmission goes; no need to set callback */
|
||||
sixtop_output(dest_addr, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_nbr_t *nbr;
|
||||
uint8_t invalid_schedule_generation;
|
||||
sixp_trans_t *trans;
|
||||
const sixtop_sf_t *sf;
|
||||
int16_t seqno;
|
||||
int ret;
|
||||
|
||||
assert(buf != NULL && src_addr != NULL);
|
||||
if(buf == NULL || src_addr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(sixp_pkt_parse(buf, len, &pkt) < 0) {
|
||||
PRINTF("6P: sixp_input() fails because off a malformed 6P packet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(pkt.type != SIXP_PKT_TYPE_REQUEST &&
|
||||
pkt.type != SIXP_PKT_TYPE_RESPONSE &&
|
||||
pkt.type != SIXP_PKT_TYPE_CONFIRMATION) {
|
||||
PRINTF("6P: sixp_input() fails because of unsupported type [type:%u]\n",
|
||||
pkt.type);
|
||||
return;
|
||||
}
|
||||
|
||||
if((sf = sixtop_find_sf(pkt.sfid)) == NULL) {
|
||||
PRINTF("6P: sixp_input() fails because SF [sfid:%u] is unavailable\n",
|
||||
pkt.sfid);
|
||||
/*
|
||||
* XXX: what if the incoming packet is a response? confirmation should be
|
||||
* sent back?
|
||||
*/
|
||||
if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_SFID,
|
||||
pkt.sfid, pkt.seqno, src_addr) < 0) {
|
||||
PRINTF("6P: sixp_input() fails to return an error response\n");
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
nbr = sixp_nbr_find(src_addr);
|
||||
/* Generation Management */
|
||||
if(pkt.code.value == SIXP_PKT_CMD_CLEAR) {
|
||||
/* Not need to validate generation counters in a case of CMD_CLEAR */
|
||||
invalid_schedule_generation = 0;
|
||||
} else if(nbr == NULL) {
|
||||
if(pkt.gab == 0 && pkt.gba == 0) {
|
||||
invalid_schedule_generation = 0; /* valid combination */
|
||||
} else {
|
||||
PRINTF("6P: GAB/GBA should be 0 because of no corresponding nbr\n");
|
||||
invalid_schedule_generation = 1;
|
||||
}
|
||||
} else {
|
||||
PRINTF("6P: GAB: %u, GBA: %u, GTX: %u, GRX: %u\n",
|
||||
pkt.gab, pkt.gba, sixp_nbr_get_grx(nbr), sixp_nbr_get_gtx(nbr));
|
||||
if(((pkt.type == SIXP_PKT_TYPE_REQUEST ||
|
||||
pkt.type == SIXP_PKT_TYPE_CONFIRMATION) &&
|
||||
pkt.gab == sixp_nbr_get_grx(nbr) &&
|
||||
pkt.gba == sixp_nbr_get_gtx(nbr)) ||
|
||||
(pkt.type == SIXP_PKT_TYPE_RESPONSE &&
|
||||
pkt.gab == sixp_nbr_get_gtx(nbr) &&
|
||||
pkt.gba == sixp_nbr_get_grx(nbr))) {
|
||||
invalid_schedule_generation = 0; /* valid combination */
|
||||
} else {
|
||||
invalid_schedule_generation = 1;
|
||||
}
|
||||
}
|
||||
if(invalid_schedule_generation) {
|
||||
PRINTF("6P: sixp_input() fails because of schedule generation mismatch\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Transaction Management */
|
||||
trans = sixp_trans_find(src_addr);
|
||||
|
||||
if(pkt.type == SIXP_PKT_TYPE_REQUEST) {
|
||||
if(trans != NULL) {
|
||||
/* Error: not supposed to have another transaction with the peer. */
|
||||
PRINTF("6P: sixp_input() fails because another request [peer_addr:");
|
||||
PRINTLLADDR((const uip_lladdr_t *)src_addr);
|
||||
PRINTF(" seqno:%u] is in process\n", sixp_trans_get_seqno(trans));
|
||||
if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_BUSY,
|
||||
pkt.sfid, pkt.seqno, src_addr) < 0) {
|
||||
PRINTF("6P: sixp_input() fails to return an error response");
|
||||
}
|
||||
return;
|
||||
} else if((trans = sixp_trans_alloc(&pkt, src_addr)) == NULL) {
|
||||
PRINTF("6P: sixp_input() fails because of lack of memory\n");
|
||||
if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_NORES,
|
||||
pkt.sfid, pkt.seqno, src_addr) < 0) {
|
||||
PRINTF("6P: sixp_input() fails to return an error response\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if(pkt.type == SIXP_PKT_TYPE_RESPONSE ||
|
||||
pkt.type == SIXP_PKT_TYPE_CONFIRMATION) {
|
||||
if(trans == NULL) {
|
||||
/* Error: should have a transaction for incoming packet */
|
||||
PRINTF("6P: sixp_input() fails because of no trans [peer_addr:");
|
||||
PRINTLLADDR((const uip_lladdr_t *)src_addr);
|
||||
PRINTF("]\n");
|
||||
return;
|
||||
} else if((seqno = sixp_trans_get_seqno(trans)) < 0 ||
|
||||
seqno != pkt.seqno) {
|
||||
PRINTF("6P: sixp_input() fails because of invalid seqno [seqno:%u, %u]\n",
|
||||
seqno, pkt.seqno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* state transition */
|
||||
assert(trans != NULL);
|
||||
switch(pkt.type) {
|
||||
case SIXP_PKT_TYPE_REQUEST:
|
||||
ret = sixp_trans_transit_state(trans,
|
||||
SIXP_TRANS_STATE_REQUEST_RECEIVED);
|
||||
break;
|
||||
case SIXP_PKT_TYPE_RESPONSE:
|
||||
ret = sixp_trans_transit_state(trans,
|
||||
SIXP_TRANS_STATE_RESPONSE_RECEIVED);
|
||||
break;
|
||||
case SIXP_PKT_TYPE_CONFIRMATION:
|
||||
ret = sixp_trans_transit_state(trans,
|
||||
SIXP_TRANS_STATE_CONFIRMATION_RECEIVED);
|
||||
break;
|
||||
default:
|
||||
PRINTF("6P: sixp_input() fails because of unsupported type [type:%u]\n",
|
||||
pkt.type);
|
||||
return;
|
||||
}
|
||||
if(ret < 0) {
|
||||
PRINTF("6P: sixp_input() fails because of state transition failure\n");
|
||||
PRINTF("6P: something wrong; we're terminating the trans %p\n", trans);
|
||||
(void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
if(sf->input != NULL) {
|
||||
sf->input(pkt.type, pkt.code, pkt.body, pkt.body_len, src_addr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
sixp_output(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_sent_callback_t func, void *arg, uint16_t arg_len)
|
||||
{
|
||||
sixp_trans_t *trans;
|
||||
sixp_nbr_t *nbr;
|
||||
sixp_pkt_cmd_t cmd;
|
||||
int16_t seqno, gab, gba;
|
||||
sixp_pkt_t pkt;
|
||||
|
||||
assert(dest_addr != NULL);
|
||||
|
||||
/* validate the state of a transaction with a specified peer */
|
||||
trans = sixp_trans_find(dest_addr);
|
||||
if(type == SIXP_PKT_TYPE_REQUEST) {
|
||||
if(trans != NULL) {
|
||||
PRINTF("6P: sixp_output() fails because another trans for [peer_addr:");
|
||||
PRINTLLADDR((const uip_lladdr_t *)dest_addr);
|
||||
PRINTF("] is in process\n");
|
||||
return -1;
|
||||
} else {
|
||||
/* ready to send a request */
|
||||
/* we're going to allocate a new transaction later */
|
||||
}
|
||||
} else if(type == SIXP_PKT_TYPE_RESPONSE) {
|
||||
if(trans == NULL) {
|
||||
PRINTF("6P: sixp_output() fails because of no transaction [peer_addr:");
|
||||
PRINTLLADDR((const uip_lladdr_t *)dest_addr);
|
||||
PRINTF("]\n");
|
||||
return -1;
|
||||
} else if(sixp_trans_get_state(trans) !=
|
||||
SIXP_TRANS_STATE_REQUEST_RECEIVED) {
|
||||
PRINTF("6P: sixp_output() fails because of invalid transaction state\n");
|
||||
return -1;
|
||||
} else {
|
||||
/* ready to send a response */
|
||||
}
|
||||
} else if(type == SIXP_PKT_TYPE_CONFIRMATION) {
|
||||
if(trans == NULL) {
|
||||
PRINTF("6P: sixp_output() fails because of no transaction [peer_addr:\n");
|
||||
PRINTLLADDR((const uip_lladdr_t *)dest_addr);
|
||||
PRINTF("\n");
|
||||
return -1;
|
||||
} else if(sixp_trans_get_state(trans) !=
|
||||
SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
|
||||
PRINTF("6P: sixp_output() fails because of invalid transaction state\n");
|
||||
return -1;
|
||||
} else {
|
||||
/* ready to send a confirmation */
|
||||
}
|
||||
} else {
|
||||
PRINTF("6P: sixp_output() fails because of unsupported type [type:%u]\n",
|
||||
type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nbr = sixp_nbr_find(dest_addr);
|
||||
|
||||
/*
|
||||
* Make sure we have a nbr for the peer if the packet is a response with
|
||||
* success so that we can manage the schedule generation.
|
||||
*/
|
||||
if(nbr == NULL &&
|
||||
type == SIXP_PKT_TYPE_RESPONSE && code.value == SIXP_PKT_RC_SUCCESS &&
|
||||
((cmd = sixp_trans_get_cmd(trans)) == SIXP_PKT_CMD_ADD ||
|
||||
cmd == SIXP_PKT_CMD_DELETE) &&
|
||||
(nbr = sixp_nbr_alloc(dest_addr)) == NULL) {
|
||||
PRINTF("6P: sixp_output() fails because of no memory for another nbr\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set SeqNum */
|
||||
if(type == SIXP_PKT_TYPE_REQUEST) {
|
||||
if(nbr == NULL &&
|
||||
(nbr = sixp_nbr_alloc(dest_addr)) == NULL) {
|
||||
PRINTF("6P: sixp_output() fails because it fails to allocate a nbr\n");
|
||||
return -1;
|
||||
}
|
||||
if((seqno = sixp_nbr_get_next_seqno(nbr)) < 0){
|
||||
PRINTF("6P: sixp_output() fails to get the next sequence number\n");
|
||||
return -1;
|
||||
}
|
||||
if(sixp_nbr_increment_next_seqno(nbr) < 0) {
|
||||
PRINTF("6P: sixp_output() fails to increment the next sequence number\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
assert(trans != NULL);
|
||||
if((seqno = sixp_trans_get_seqno(trans)) < 0) {
|
||||
PRINTF("6P: sixp_output() fails because it fails to get seqno\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* set GAB and GBA */
|
||||
if(nbr == NULL) {
|
||||
gab = gba = 0;
|
||||
} else {
|
||||
if(type == SIXP_PKT_TYPE_REQUEST ||
|
||||
type == SIXP_PKT_TYPE_CONFIRMATION) {
|
||||
gab = sixp_nbr_get_gtx(nbr);
|
||||
gba = sixp_nbr_get_grx(nbr);
|
||||
} else if(type == SIXP_PKT_TYPE_RESPONSE) {
|
||||
gba = sixp_nbr_get_gtx(nbr);
|
||||
gab = sixp_nbr_get_grx(nbr);
|
||||
} else {
|
||||
/* never come here */
|
||||
PRINTF("6P: sixp_output() fails because of an unexpected condition\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(gab < 0 || gba < 0) {
|
||||
PRINTF("6P: sixp_output() fails to get GAB or GBA\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create a 6P packet within packetbuf */
|
||||
if(sixp_pkt_create(type, code, sfid,
|
||||
(uint8_t)seqno, (uint8_t)gab, (uint8_t)gba,
|
||||
body, body_len,
|
||||
type == SIXP_PKT_TYPE_REQUEST ? &pkt : NULL) < 0) {
|
||||
PRINTF("6P: sixp_output() fails to create a 6P packet\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate a transaction for a sending request */
|
||||
if(type == SIXP_PKT_TYPE_REQUEST) {
|
||||
assert(trans == NULL);
|
||||
if((trans = sixp_trans_alloc(&pkt, dest_addr)) == NULL) {
|
||||
PRINTF("6P: sixp_output() is aborted because of no memory\n");
|
||||
return -1;
|
||||
} else {
|
||||
/* ready for proceed */
|
||||
}
|
||||
}
|
||||
|
||||
assert(trans != NULL);
|
||||
sixp_trans_set_callback(trans, func, arg, arg_len);
|
||||
sixtop_output(dest_addr, mac_callback, trans);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
sixp_init(void)
|
||||
{
|
||||
sixp_nbr_init();
|
||||
sixp_trans_init();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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
|
||||
* 6top Protocol (6P) APIs
|
||||
* \author
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef _SIXP_H_
|
||||
#define _SIXP_H_
|
||||
|
||||
#include "net/linkaddr.h"
|
||||
#include "sys/clock.h"
|
||||
|
||||
#include "sixp-pkt.h"
|
||||
|
||||
#define SIXP_SUBIE_ID 0x00
|
||||
|
||||
#ifdef SIXP_CONF_WITH_PAYLOAD_TERMINATION_IE
|
||||
#define SIXP_WITH_PAYLOAD_TERMINATION_IE SIXP_CONF_WITH_PAYLOAD_TERMINATION_IE
|
||||
#else
|
||||
#define SIXP_WITH_PAYLOAD_TERMINATION_IE 0
|
||||
#endif /* SIXP_CONF_WITH_PAYLOAD_TERMINATION_IE */
|
||||
|
||||
/**
|
||||
* \brief The initial sequence number used for 6P request
|
||||
*/
|
||||
#define SIXP_INITIAL_SEQUENCE_NUMBER 0
|
||||
|
||||
/**
|
||||
* \brief 6P Send Status, which represents sixp_output() result.
|
||||
*/
|
||||
typedef enum {
|
||||
SIXP_OUTPUT_STATUS_SUCCESS, /**< SUCCESS */
|
||||
SIXP_OUTPUT_STATUS_FAILURE /**< FAILURE */
|
||||
} sixp_output_status_t;
|
||||
|
||||
/**
|
||||
* \brief 6P Packet Sent Handler
|
||||
*/
|
||||
typedef void (*sixp_sent_callback_t)(void *arg, uint16_t arg_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_output_status_t status);
|
||||
|
||||
/**
|
||||
* \brief Input a 6P packet
|
||||
* \param buf The pointer to a buffer pointing the head of 6top IE Content
|
||||
* \param len The lengh of 6top IE Content
|
||||
* \param src_addr The Source address of an incoming packet
|
||||
* \return 0 if , -1 on failure
|
||||
*/
|
||||
void sixp_input(const uint8_t *buf, uint16_t len,
|
||||
const linkaddr_t *src_addr);
|
||||
|
||||
/**
|
||||
* \brief Output a 6P packet
|
||||
* \param type Message Type
|
||||
* \param code Message Code; Command ID or Return Code
|
||||
* \param sfid Scheduling Function Identifier
|
||||
* \param body 6top IE Content
|
||||
* \param body_len The length of 6top IE Content
|
||||
* \param dest_addr The destination Address
|
||||
* \param func callback function invoked after the transmission process
|
||||
* \param arg The pointer to an argument to be passed with the callback
|
||||
* \param arg_len The length of the argument
|
||||
* \return 0 on success, -1 on failure
|
||||
*/
|
||||
int sixp_output(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid,
|
||||
const uint8_t *body, uint16_t body_len,
|
||||
const linkaddr_t *dest_addr,
|
||||
sixp_sent_callback_t func, void *arg, uint16_t arg_len);
|
||||
|
||||
/**
|
||||
* \brief Initialize 6P Module
|
||||
* It invokes sixp_nbr_init() and sixp_trans_init().
|
||||
*/
|
||||
void sixp_init(void);
|
||||
#endif /* ! _SIXP_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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
|
||||
* 6top Configuration
|
||||
* \author
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef __SIXTOP_CONF_H__
|
||||
#define __SIXTOP_CONF_H__
|
||||
|
||||
/**
|
||||
* \brief The maximum number of Scheduling Functions in the system.
|
||||
*/
|
||||
#ifdef SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS
|
||||
#define SIXTOP_MAX_SCHEDULING_FUNCTIONS SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS
|
||||
#else
|
||||
#define SIXTOP_MAX_SCHEDULING_FUNCTIONS 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief The maximum number of transactions which the sixtop module can handle
|
||||
* at the same time.
|
||||
*/
|
||||
#ifdef SIXTOP_CONF_MAX_TRANSACTIONS
|
||||
#define SIXTOP_MAX_TRANSACTIONS SIXTOP_CONF_MAX_TRANSACTIONS
|
||||
#else
|
||||
#define SIXTOP_MAX_TRANSACTIONS 1
|
||||
#endif
|
||||
|
||||
#endif /* !__SIXTOP_CONF_H__ */
|
||||
/** @} */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* Copyright (c) 2016, Yasuyuki Tanaka
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -10,96 +10,132 @@
|
|||
* 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.
|
||||
* 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 net
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* \defgroup sixtop 6TiSCH Operation Sublayer (6top)
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A sixtop protocol that performs link addition/deletion
|
||||
* 6TiSCH Operation Sublayer (6top) APIs
|
||||
* \author
|
||||
* Shalu R <shalur@cdac.in>
|
||||
* Lijo Thomas <lijo@cdac.in>
|
||||
* Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef __SIXTOP_H__
|
||||
#define __SIXTOP_H__
|
||||
#ifndef _SIXTOP_H_
|
||||
#define _SIXTOP_H_
|
||||
|
||||
#include "contiki.h"
|
||||
#include "stdbool.h"
|
||||
#include "net/ip/uip-debug.h"
|
||||
#include "net/mac/mac.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/mac/tsch/tsch-schedule.h"
|
||||
#include "net/mac/tsch/tsch-asn.h"
|
||||
|
||||
#define SIXTOP_SUBIE_ID 0x00
|
||||
#define SIXTOP_VERSION 0x01
|
||||
#include "sixp-pkt.h"
|
||||
|
||||
/* Link Option OFF */
|
||||
#define LINK_OPTION_OFF 0
|
||||
/**
|
||||
* \brief Input Handler of Scheduling Function
|
||||
* \param type 6P Message Type of an input packet
|
||||
* \param code Code, 6P Command Identifier or Return Code, of an input packet
|
||||
* \param body Body, "Other Fields", of an input packet
|
||||
* \param body_len The length of body
|
||||
* \param body src_addr Source address of an input packet
|
||||
*/
|
||||
typedef void (* sixtop_sf_input)(sixp_pkt_type_t type,
|
||||
sixp_pkt_code_t code,
|
||||
const uint8_t *body,
|
||||
uint16_t body_len,
|
||||
const linkaddr_t *src_addr);
|
||||
|
||||
/* Maximum number of retransmissions permissible at MAC layer */
|
||||
#define SIXTOP_CONF_MAX_MAC_TRANSMISSIONS 3
|
||||
/**
|
||||
* \brief Timeout Handler of Scheduling Function
|
||||
* \param cmd 6P Command (Identifier) in process under the transaction
|
||||
* \param peer_addr The peer address of the transaction
|
||||
*/
|
||||
typedef void (* sixtop_sf_timeout)(sixp_pkt_cmd_t cmd,
|
||||
const linkaddr_t *peer_addr);
|
||||
/**
|
||||
* /brief Scheduling Function Driver
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t sfid; /**< SFID */
|
||||
clock_time_t timeout_interval; /**< Timeout Value */
|
||||
void (*init)(void); /**< Init Function */
|
||||
sixtop_sf_input input; /**< Input Handler */
|
||||
sixtop_sf_timeout timeout; /**< Transaction Timeout Handler */
|
||||
} sixtop_sf_t;
|
||||
/**
|
||||
* \var sixtop_sf_t::sfid
|
||||
* managed: 0x00-0xfe
|
||||
* unmanaged: 0xf0-0xfe
|
||||
* reserved: 0xff
|
||||
*/
|
||||
|
||||
/* 6P Command ID */
|
||||
enum sixtop_command_id {
|
||||
CMD_ADD = 0x01,
|
||||
CMD_DELETE = 0x02,
|
||||
CMD_COUNT = 0x03,
|
||||
CMD_LIST = 0x04,
|
||||
CMD_CLEAR = 0x05,
|
||||
};
|
||||
|
||||
/* 6P Return Code */
|
||||
enum sixtop_return_code {
|
||||
RC_SUCCESS = 0x06, /* Operation succeeded */
|
||||
RC_VER_ERR = 0x07, /* Unsupported 6P version */
|
||||
RC_SFID_ERR = 0x08, /* Unsupported SFID */
|
||||
RC_BUSY = 0x09, /* Handling previous request */
|
||||
RC_RESET = 0x0a, /* Abort 6P transaction */
|
||||
RC_ERR = 0x0b, /* Operation failed */
|
||||
};
|
||||
/**
|
||||
* \brief Add a Scheduling Function (SF) to 6top Sublayer
|
||||
* \param sf The pointer to a Scheduling Function Driver
|
||||
* \return 0 on success, -1 on failure
|
||||
*
|
||||
* If there is a SF whose SF is identical to one of a SF specified to this API,
|
||||
* the addition will fail and -1 will be returned. If there is no room to
|
||||
* another SF, -1 will be returned as well. You can specify how many SFs can be
|
||||
* added with SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS.
|
||||
*/
|
||||
int sixtop_add_sf(const sixtop_sf_t *sf);
|
||||
|
||||
/* Sixtop State Machine */
|
||||
enum {
|
||||
SIXTOP_IDLE = 0x00,
|
||||
SIXTOP_ADD_REQUEST_WAIT_SENDDONE = 0x01, /* Waiting for SendDone confirmation of Add Request */
|
||||
SIXTOP_ADD_RESPONSE_WAIT = 0x02, /* Waiting for Add Response */
|
||||
SIXTOP_ADD_RESPONSE_WAIT_SENDDONE = 0x03, /* Waiting for SendDone confirmation of Add Response */
|
||||
SIXTOP_ADD_RESPONSE_RECEIVED = 0x04, /* Received Add Response */
|
||||
SIXTOP_DELETE_REQUEST_WAIT_SENDDONE = 0x05, /* Waiting for SendDone confirmation of Delete Request */
|
||||
SIXTOP_DELETE_RESPONSE_WAIT = 0x06, /* waiting for Delete Response */
|
||||
SIXTOP_DELETE_RESPONSE_WAIT_SENDDONE = 0x07, /* Waiting for SendDone confirmation of Add Response */
|
||||
SIXTOP_DELETE_RESPONSE_RECEIVED = 0x08, /* Received Delete Response */
|
||||
} sixtop_state;
|
||||
/**
|
||||
* \brief Find a SF which has been added by SFID
|
||||
* \param sfid Scheduling Function Identifier of a SF
|
||||
* \return The pointer to a SF driver having the specified SFID on success, NULL
|
||||
* on failure (not found)
|
||||
*/
|
||||
const sixtop_sf_t *sixtop_find_sf(uint8_t sfid);
|
||||
|
||||
/********** Functions *********/
|
||||
/* Initiates a Sixtop Link addition */
|
||||
int sixtop_add_links(linkaddr_t *dest_addr, uint8_t num_Links);
|
||||
/* Initiates a Sixtop Link deletion */
|
||||
int sixtop_remove_link(linkaddr_t *dest_addr);
|
||||
/* Is it a Sixtop IE? Returns 0 if success */
|
||||
int sixtop_is_sixtop_ie(const uint8_t *buf, int buf_size, frame802154_t *frame, struct ieee802154_ies *ies);
|
||||
/* Set the Sequence Number of Link Response as in Link Request */
|
||||
void sixtop_set_seqno(uint8_t seq_num);
|
||||
/* Parse a Sixtop IE. Returns length of IE */
|
||||
int sixtop_parse_ie(const uint8_t *buf, linkaddr_t *dest_addr);
|
||||
/**
|
||||
* \brief Output a 6P packet which is supposestored in packetbuf
|
||||
* \param dest_addr Destination address of the outgoing packet
|
||||
* \param callback MAC callback function to get a TX result
|
||||
* \param arg The pointer to an argument which is returned with the MAC callback
|
||||
*/
|
||||
void sixtop_output(const linkaddr_t *dest_addr,
|
||||
mac_callback_t callback, void *arg);
|
||||
|
||||
#endif /* __SIXTOP_H__ */
|
||||
/**
|
||||
* \brief Input a packet stored in packetbuf
|
||||
*/
|
||||
void sixtop_input(void);
|
||||
|
||||
/**
|
||||
* \brief Initialize 6top module
|
||||
* This initialization function removes all the SFs which has been installed
|
||||
* into the 6top sub-layer. In addition, it invokes sixp_init().
|
||||
*/
|
||||
void sixtop_init(void);
|
||||
|
||||
/**
|
||||
* \brief Initialize installed SFs which has been added in the system
|
||||
* This function is supposed to be invoked every time the node gets associated.
|
||||
*/
|
||||
void sixtop_init_sf(void);
|
||||
|
||||
#endif /* !_SIXTOP_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "net/mac/tsch/tsch-log.h"
|
||||
#include "net/mac/tsch/tsch-packet.h"
|
||||
#include "net/mac/tsch/tsch-security.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
#include "net/mac/mac-sequence.h"
|
||||
#include "lib/random.h"
|
||||
|
||||
|
@ -63,6 +62,10 @@
|
|||
#include "net/mac/tsch/tsch-rpl.h"
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
||||
#if TSCH_WITH_SIXTOP
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
#endif
|
||||
|
||||
#if FRAME802154_VERSION < FRAME802154_IEEE802154_2015
|
||||
#error TSCH: FRAME802154_VERSION must be at least FRAME802154_IEEE802154_2015
|
||||
#endif
|
||||
|
@ -423,28 +426,6 @@ tsch_rx_process_pending()
|
|||
&& frame.fcf.frame_version == FRAME802154_IEEE802154_2015
|
||||
&& frame.fcf.frame_type == FRAME802154_BEACONFRAME;
|
||||
|
||||
#if TSCH_WITH_SIXTOP
|
||||
int is_ie = ret
|
||||
&& frame.fcf.frame_version == FRAME802154_IEEE802154E_2012
|
||||
&& frame.fcf.frame_type == FRAME802154_DATAFRAME
|
||||
&& frame.fcf.ie_list_present == 1;
|
||||
|
||||
if(is_ie) {
|
||||
/* IE received (Data may/ maynot be present) */
|
||||
|
||||
/* Save sequence number of Link Request */
|
||||
sixtop_set_seqno(frame.seq);
|
||||
|
||||
/* Check and parse, if it is a Sixtop IE. Returns length of data */
|
||||
uint8_t data_len = ie_input(current_input);
|
||||
|
||||
if(data_len <= 0) {
|
||||
/* Only Sixtop IE present , no data */
|
||||
is_data = 0;
|
||||
}
|
||||
}
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
|
||||
if(is_data) {
|
||||
/* Skip EBs and other control messages */
|
||||
/* Copy to packetbuf for processing */
|
||||
|
@ -546,7 +527,6 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
|
|||
return 0;
|
||||
}
|
||||
#endif /* TSCH_JOIN_SECURED_ONLY */
|
||||
|
||||
#if LLSEC802154_ENABLED
|
||||
if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
|
||||
input_eb->len - hdrlen - tsch_security_mic_len(&frame),
|
||||
|
@ -633,9 +613,9 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
|
|||
ies.ie_tsch_slotframe_and_link.slotframe_size);
|
||||
for(i = 0; i < num_links; i++) {
|
||||
tsch_schedule_add_link(sf,
|
||||
ies.ie_tsch_slotframe_and_link.links[i].link_options,
|
||||
LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
|
||||
ies.ie_tsch_slotframe_and_link.links[i].timeslot, ies.ie_tsch_slotframe_and_link.links[i].channel_offset);
|
||||
ies.ie_tsch_slotframe_and_link.links[i].link_options,
|
||||
LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
|
||||
ies.ie_tsch_slotframe_and_link.links[i].timeslot, ies.ie_tsch_slotframe_and_link.links[i].channel_offset);
|
||||
}
|
||||
} else {
|
||||
LOG_ERR("! parse_eb: too many links in schedule (%u)\n", num_links);
|
||||
|
@ -952,6 +932,10 @@ tsch_init(void)
|
|||
* If TSCH_AUTOSTART is not set, one needs to call NETSTACK_MAC.on() to start TSCH. */
|
||||
NETSTACK_MAC.on();
|
||||
#endif /* TSCH_AUTOSTART */
|
||||
|
||||
#if TSCH_WITH_SIXTOP
|
||||
sixtop_init();
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Function send for TSCH-MAC, puts the packet in packetbuf in the MAC queue */
|
||||
|
@ -1067,6 +1051,9 @@ packet_input(void)
|
|||
LOG_INFO("received from ");
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
LOG_INFO_(" with seqno %u\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
|
||||
#if TSCH_WITH_SIXTOP
|
||||
sixtop_input();
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
NETSTACK_NETWORK.input();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -301,6 +301,16 @@ nbr_table_register(nbr_table_t *table, nbr_table_callback *callback)
|
|||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Test whether a specified table has been registered or not */
|
||||
int
|
||||
nbr_table_is_register(nbr_table_t *table)
|
||||
{
|
||||
if(table != NULL && all_tables[table->index] == table) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Returns the first item of the current table */
|
||||
nbr_table_item_t *
|
||||
nbr_table_head(nbr_table_t *table)
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef struct nbr_table {
|
|||
#define NBR_TABLE_DECLARE(name) extern nbr_table_t *name
|
||||
|
||||
typedef enum {
|
||||
NBR_TABLE_REASON_UNDEFINED,
|
||||
NBR_TABLE_REASON_UNDEFINED,
|
||||
NBR_TABLE_REASON_RPL_DIO,
|
||||
NBR_TABLE_REASON_RPL_DAO,
|
||||
NBR_TABLE_REASON_RPL_DIS,
|
||||
|
@ -86,11 +86,13 @@ typedef enum {
|
|||
NBR_TABLE_REASON_MAC,
|
||||
NBR_TABLE_REASON_LLSEC,
|
||||
NBR_TABLE_REASON_LINK_STATS,
|
||||
NBR_TABLE_REASON_SIXTOP,
|
||||
} nbr_table_reason_t;
|
||||
|
||||
/** \name Neighbor tables: register and loop through table elements */
|
||||
/** @{ */
|
||||
int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback);
|
||||
int nbr_table_is_register(nbr_table_t *table);
|
||||
nbr_table_item_t *nbr_table_head(nbr_table_t *table);
|
||||
nbr_table_item_t *nbr_table_next(nbr_table_t *table, nbr_table_item_t *item);
|
||||
/** @} */
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
#undef NETSTACK_CONF_MAC
|
||||
#define NETSTACK_CONF_MAC tschmac_driver
|
||||
|
||||
#undef TSCH_CONF_WITH_SIXTOP
|
||||
#define TSCH_CONF_WITH_SIXTOP 1
|
||||
|
||||
#if CONTIKI_TARGET_COOJA
|
||||
#define COOJA_CONF_SIMULATE_TURNAROUND 0
|
||||
#endif /* CONTIKI_TARGET_COOJA */
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype382</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/16-6tisch/code/test-sixtop.c</source>
|
||||
<commands>make clean TARGET=cooja
|
||||
make test-sixtop.cooja TARGET=cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>47.60131881808453</x>
|
||||
<y>20.028921031789082</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype382</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>5</z>
|
||||
<height>160</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<moterelations>true</moterelations>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 150.72607380174134 154.79188997110083</viewport>
|
||||
</plugin_config>
|
||||
<width>400</width>
|
||||
<z>4</z>
|
||||
<height>400</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>1320</width>
|
||||
<z>3</z>
|
||||
<height>240</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>160</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<zoomfactor>500.0</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1720</width>
|
||||
<z>2</z>
|
||||
<height>166</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>957</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Notes
|
||||
<plugin_config>
|
||||
<notes>Enter notes here</notes>
|
||||
<decorations>true</decorations>
|
||||
</plugin_config>
|
||||
<width>1040</width>
|
||||
<z>1</z>
|
||||
<height>160</height>
|
||||
<location_x>680</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan-pcap" />
|
||||
</plugin_config>
|
||||
<width>500</width>
|
||||
<z>0</z>
|
||||
<height>300</height>
|
||||
<location_x>290</location_x>
|
||||
<location_y>422</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/16-6tisch/js/unit-test.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>663</location_x>
|
||||
<location_y>105</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype382</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/16-6tisch/code/test-sixp-pkt.c</source>
|
||||
<commands>make clean TARGET=cooja
|
||||
make test-sixp-pkt.cooja TARGET=cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>47.60131881808453</x>
|
||||
<y>20.028921031789082</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype382</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>5</z>
|
||||
<height>160</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<moterelations>true</moterelations>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 150.72607380174134 154.79188997110083</viewport>
|
||||
</plugin_config>
|
||||
<width>400</width>
|
||||
<z>4</z>
|
||||
<height>400</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>1320</width>
|
||||
<z>3</z>
|
||||
<height>240</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>160</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<zoomfactor>500.0</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1720</width>
|
||||
<z>2</z>
|
||||
<height>166</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>957</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Notes
|
||||
<plugin_config>
|
||||
<notes>Enter notes here</notes>
|
||||
<decorations>true</decorations>
|
||||
</plugin_config>
|
||||
<width>1040</width>
|
||||
<z>1</z>
|
||||
<height>160</height>
|
||||
<location_x>680</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan-pcap" />
|
||||
</plugin_config>
|
||||
<width>500</width>
|
||||
<z>0</z>
|
||||
<height>300</height>
|
||||
<location_x>290</location_x>
|
||||
<location_y>422</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/16-6tisch/js/unit-test.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>663</location_x>
|
||||
<location_y>105</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype382</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/16-6tisch/code/test-sixp-trans.c</source>
|
||||
<commands>make clean TARGET=cooja
|
||||
make test-sixp-trans.cooja TARGET=cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>47.60131881808453</x>
|
||||
<y>20.028921031789082</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype382</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>5</z>
|
||||
<height>160</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<moterelations>true</moterelations>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 150.72607380174134 154.79188997110083</viewport>
|
||||
</plugin_config>
|
||||
<width>400</width>
|
||||
<z>4</z>
|
||||
<height>400</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>1320</width>
|
||||
<z>3</z>
|
||||
<height>240</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>160</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<zoomfactor>500.0</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1720</width>
|
||||
<z>2</z>
|
||||
<height>166</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>957</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Notes
|
||||
<plugin_config>
|
||||
<notes>Enter notes here</notes>
|
||||
<decorations>true</decorations>
|
||||
</plugin_config>
|
||||
<width>1040</width>
|
||||
<z>1</z>
|
||||
<height>160</height>
|
||||
<location_x>680</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan-pcap" />
|
||||
</plugin_config>
|
||||
<width>500</width>
|
||||
<z>0</z>
|
||||
<height>300</height>
|
||||
<location_x>290</location_x>
|
||||
<location_y>422</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/16-6tisch/js/unit-test.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>663</location_x>
|
||||
<location_y>105</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype382</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/16-6tisch/code/test-sixp-nbr.c</source>
|
||||
<commands>make clean TARGET=cooja
|
||||
make test-sixp-nbr.cooja TARGET=cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>47.60131881808453</x>
|
||||
<y>20.028921031789082</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype382</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>5</z>
|
||||
<height>160</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<moterelations>true</moterelations>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 150.72607380174134 154.79188997110083</viewport>
|
||||
</plugin_config>
|
||||
<width>400</width>
|
||||
<z>4</z>
|
||||
<height>400</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>1320</width>
|
||||
<z>3</z>
|
||||
<height>240</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>160</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<zoomfactor>500.0</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1720</width>
|
||||
<z>2</z>
|
||||
<height>166</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>957</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Notes
|
||||
<plugin_config>
|
||||
<notes>Enter notes here</notes>
|
||||
<decorations>true</decorations>
|
||||
</plugin_config>
|
||||
<width>1040</width>
|
||||
<z>1</z>
|
||||
<height>160</height>
|
||||
<location_x>680</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan-pcap" />
|
||||
</plugin_config>
|
||||
<width>500</width>
|
||||
<z>0</z>
|
||||
<height>300</height>
|
||||
<location_x>290</location_x>
|
||||
<location_y>422</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/16-6tisch/js/unit-test.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>663</location_x>
|
||||
<location_y>105</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype382</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/16-6tisch/code/test-sixp.c</source>
|
||||
<commands>make clean TARGET=cooja
|
||||
make test-sixp.cooja TARGET=cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>47.60131881808453</x>
|
||||
<y>20.028921031789082</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype382</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.SimControl
|
||||
<width>280</width>
|
||||
<z>5</z>
|
||||
<height>160</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Visualizer
|
||||
<plugin_config>
|
||||
<moterelations>true</moterelations>
|
||||
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
|
||||
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 150.72607380174134 154.79188997110083</viewport>
|
||||
</plugin_config>
|
||||
<width>400</width>
|
||||
<z>4</z>
|
||||
<height>400</height>
|
||||
<location_x>1</location_x>
|
||||
<location_y>1</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.LogListener
|
||||
<plugin_config>
|
||||
<filter />
|
||||
<formatted_time />
|
||||
<coloring />
|
||||
</plugin_config>
|
||||
<width>1320</width>
|
||||
<z>3</z>
|
||||
<height>240</height>
|
||||
<location_x>400</location_x>
|
||||
<location_y>160</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.TimeLine
|
||||
<plugin_config>
|
||||
<mote>0</mote>
|
||||
<showRadioRXTX />
|
||||
<showRadioHW />
|
||||
<showLEDs />
|
||||
<zoomfactor>500.0</zoomfactor>
|
||||
</plugin_config>
|
||||
<width>1720</width>
|
||||
<z>2</z>
|
||||
<height>166</height>
|
||||
<location_x>0</location_x>
|
||||
<location_y>957</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.Notes
|
||||
<plugin_config>
|
||||
<notes>Enter notes here</notes>
|
||||
<decorations>true</decorations>
|
||||
</plugin_config>
|
||||
<width>1040</width>
|
||||
<z>1</z>
|
||||
<height>160</height>
|
||||
<location_x>680</location_x>
|
||||
<location_y>0</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.RadioLogger
|
||||
<plugin_config>
|
||||
<split>150</split>
|
||||
<formatted_time />
|
||||
<showdups>false</showdups>
|
||||
<hidenodests>false</hidenodests>
|
||||
<analyzers name="6lowpan-pcap" />
|
||||
</plugin_config>
|
||||
<width>500</width>
|
||||
<z>0</z>
|
||||
<height>300</height>
|
||||
<location_x>290</location_x>
|
||||
<location_y>422</location_y>
|
||||
</plugin>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/16-6tisch/js/unit-test.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>663</location_x>
|
||||
<location_y>105</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
||||
|
|
@ -0,0 +1 @@
|
|||
include ../Makefile.simulation-test
|
|
@ -0,0 +1,15 @@
|
|||
all:
|
||||
|
||||
CFLAGS += -D PROJECT_CONF_H=\"project-conf.h\"
|
||||
APPS += unit-test
|
||||
MODULES += os/net/mac/tsch os/net/mac/tsch/sixtop
|
||||
|
||||
PROJECT_SOURCEFILES += common.c
|
||||
|
||||
ifeq ($(TEST_04),1)
|
||||
CFLAGS += -DSIXP_MSG_API_TEST=1
|
||||
endif
|
||||
|
||||
CONTIKI = ../../..
|
||||
CONTIKI_WITH_IPV6 = 1
|
||||
include $(CONTIKI)/Makefile.include
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
|
||||
#include "unit-test/unit-test.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "lib/simEnvChange.h"
|
||||
#include "sys/cooja_mt.h"
|
||||
|
||||
static uint8_t send_is_called;
|
||||
|
||||
void
|
||||
test_print_report(const unit_test_t *utp)
|
||||
{
|
||||
printf("=check-me= ");
|
||||
if(utp->result == unit_test_failure) {
|
||||
printf("FAILED - %s: exit at L%u\n", utp->descr, utp->exit_line);
|
||||
} else {
|
||||
printf("SUCCEEDED - %s\n", utp->descr);
|
||||
}
|
||||
|
||||
/* give up the CPU so that the mote can output messages in the serial buffer */
|
||||
simProcessRunValue = 1;
|
||||
cooja_mt_yield();
|
||||
}
|
||||
|
||||
uint8_t
|
||||
test_mac_send_function_is_called(void)
|
||||
{
|
||||
return send_is_called;
|
||||
}
|
||||
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
send_is_called = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
send(mac_callback_t sent_callback, void *ptr)
|
||||
{
|
||||
send_is_called = 1;
|
||||
}
|
||||
|
||||
const struct mac_driver test_mac_driver = {
|
||||
"Test MAC",
|
||||
init,
|
||||
send,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#include "unit-test/unit-test.h"
|
||||
|
||||
void test_print_report(const unit_test_t *utp);
|
||||
uint8_t test_mac_send_function_is_called(void);
|
||||
extern const struct mac_driver test_mac_driver;
|
||||
|
||||
#endif /* !_COMMON_H */
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#ifndef _PROJECT_CONF_H_
|
||||
#define _PROJECT_CONF_H_
|
||||
|
||||
#if CONTIKI_TARGET_COOJA
|
||||
#define COOJA_CONF_SIMULATE_TURNAROUND 0
|
||||
#else
|
||||
//#error "This file is intended to be used for Cooja mote."
|
||||
#endif /* CONTIKI_TARGET_COOJA */
|
||||
|
||||
#undef SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS
|
||||
#define SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS 2
|
||||
|
||||
#undef SIXTOP_CONF_MAX_TRANSACTIONS
|
||||
#define SIXTOP_CONF_MAX_TRANSACTIONS 2
|
||||
|
||||
#undef SIXP_CONF_WITH_PAYLOAD_TERMINATION_IE
|
||||
#define SIXP_CONF_WITH_PAYLOAD_TERMINATION_IE 1
|
||||
|
||||
#undef NBR_TABLE_CONF_MAX_NEIGHBORS
|
||||
#define NBR_TABLE_CONF_MAX_NEIGHBORS 2
|
||||
|
||||
#define UNIT_TEST_PRINT_FUNCTION test_print_report
|
||||
|
||||
#undef TSCH_CONF_WITH_SIXTOP
|
||||
#define TSCH_CONF_WITH_SIXTOP 1
|
||||
|
||||
#undef TSCH_LOG_CONF_PER_SLOT
|
||||
#define TSCH_LOG_CONF_PER_SLOT 1
|
||||
|
||||
#undef TSCH_CONF_AUTOSTART
|
||||
#define TSCH_CONF_AUTOSTART 0
|
||||
|
||||
#undef IEEE802154_CONF_PANID
|
||||
#define IEEE802154_CONF_PANID 0xabcd
|
||||
|
||||
#undef NETSTACK_CONF_MAC
|
||||
#define NETSTACK_CONF_MAC test_mac_driver
|
||||
|
||||
#undef NETSTACK_CONF_RDC
|
||||
#define NETSTACK_CONF_RDC nordc_driver
|
||||
|
||||
#undef NETSTACK_CONF_FRAMER
|
||||
#define NETSTACK_CONF_FRAMER framer_802154
|
||||
|
||||
#undef FRAME802154_CONF_VERSION
|
||||
#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154_2015
|
||||
|
||||
#endif /* __PROJECT_CONF_H__ */
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 STEP OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "contiki-lib.h"
|
||||
#include "lib/assert.h"
|
||||
|
||||
#include "net/mac/tsch/sixtop/sixp-nbr.h"
|
||||
|
||||
#include "unit-test/unit-test.h"
|
||||
#include "common.h"
|
||||
|
||||
static linkaddr_t peer_addr_1;
|
||||
static linkaddr_t peer_addr_2;
|
||||
static linkaddr_t peer_addr_3;
|
||||
|
||||
PROCESS(test_process, "6P neighbor APIs test");
|
||||
AUTOSTART_PROCESSES(&test_process);
|
||||
|
||||
static void
|
||||
test_setup(void)
|
||||
{
|
||||
sixp_nbr_init();
|
||||
|
||||
memset(&peer_addr_1, 0, sizeof(peer_addr_1));
|
||||
peer_addr_1.u8[0] = 1;
|
||||
|
||||
memset(&peer_addr_2, 0, sizeof(peer_addr_2));
|
||||
peer_addr_2.u8[0] = 2;
|
||||
|
||||
memset(&peer_addr_3, 0, sizeof(peer_addr_3));
|
||||
peer_addr_3.u8[0] = 3;
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_alloc_and_free,
|
||||
"test sixp_nbr_{alloc,free}");
|
||||
UNIT_TEST(test_alloc_and_free)
|
||||
{
|
||||
sixp_nbr_t *nbr;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_1) == NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_2) == NULL);
|
||||
|
||||
/* a valid allocation */
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_1)) != NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_1) == nbr);
|
||||
|
||||
/* another allocation */
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_2)) != NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_2) == nbr);
|
||||
|
||||
/* no available memory because NBR_TABLE_CONF_MAX_NEIGHBORS == 2 */
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_3) == NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_alloc(&peer_addr_3) == NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_3) == NULL);
|
||||
|
||||
/* cannot allocate a duplicate nbr */
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_1)) == NULL);
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_2)) == NULL);
|
||||
|
||||
/* remove allocated nbrs */
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_1) != NULL);
|
||||
sixp_nbr_free(sixp_nbr_find(&peer_addr_1));
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_1) == NULL);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_2) != NULL);
|
||||
sixp_nbr_free(sixp_nbr_find(&peer_addr_2));
|
||||
UNIT_TEST_ASSERT(sixp_nbr_find(&peer_addr_2) == NULL);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_gtx_management,
|
||||
"test GTX Management");
|
||||
UNIT_TEST(test_gtx_management)
|
||||
{
|
||||
sixp_nbr_t *nbr;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_1)) != NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_gtx(nbr) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_gtx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_gtx(nbr) == 0x01);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_gtx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_gtx(nbr) == 0x02);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_gtx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_gtx(nbr) == 0x01);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_gtx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_gtx(nbr) == 0x02);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_grx_management,
|
||||
"test GRX Management");
|
||||
UNIT_TEST(test_grx_management)
|
||||
{
|
||||
sixp_nbr_t *nbr;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_1)) != NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_grx(nbr) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_grx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_grx(nbr) == 0x01);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_grx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_grx(nbr) == 0x02);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_grx(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_grx(nbr) == 0x01);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_next_seqno,
|
||||
"test next_seqno operation");
|
||||
UNIT_TEST(test_next_seqno)
|
||||
{
|
||||
sixp_nbr_t *nbr;
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
test_setup();
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr_1)) != NULL);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 1);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 2);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 3);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 4);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 5);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 6);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 7);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 8);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 9);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 10);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 11);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 12);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 13);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 14);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 15);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
|
||||
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
|
||||
PROCESS_THREAD(test_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
printf("Run unit-test\n");
|
||||
printf("---\n");
|
||||
|
||||
/* alloc / free */
|
||||
UNIT_TEST_RUN(test_alloc_and_free);
|
||||
|
||||
/* GTX */
|
||||
UNIT_TEST_RUN(test_gtx_management);
|
||||
/* GRX */
|
||||
UNIT_TEST_RUN(test_grx_management);
|
||||
|
||||
/* next sequence number */
|
||||
UNIT_TEST_RUN(test_next_seqno);
|
||||
|
||||
printf("=check-me= DONE\n");
|
||||
PROCESS_END();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "contiki-lib.h"
|
||||
#include "lib/assert.h"
|
||||
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
#include "net/mac/tsch/sixtop/sixp.h"
|
||||
#include "net/mac/tsch/sixtop/sixp-nbr.h"
|
||||
#include "net/mac/tsch/sixtop/sixp-trans.h"
|
||||
|
||||
#include "unit-test/unit-test.h"
|
||||
#include "common.h"
|
||||
|
||||
#define UNKNOWN_SF_SFID 0
|
||||
#define TEST_SF_SFID 0xf1
|
||||
|
||||
static linkaddr_t peer_addr;
|
||||
static uint8_t test_sf_input_is_called = 0;
|
||||
|
||||
static void
|
||||
input(sixp_pkt_type_t type,sixp_pkt_code_t code, const uint8_t *body,
|
||||
uint16_t body_len, const linkaddr_t *peer_addr)
|
||||
{
|
||||
test_sf_input_is_called = 1;
|
||||
}
|
||||
|
||||
static const sixtop_sf_t test_sf = {
|
||||
TEST_SF_SFID,
|
||||
0,
|
||||
NULL,
|
||||
input,
|
||||
NULL
|
||||
};
|
||||
|
||||
PROCESS(test_process, "6top protocol APIs test");
|
||||
AUTOSTART_PROCESSES(&test_process);
|
||||
|
||||
static void
|
||||
test_setup(void)
|
||||
{
|
||||
test_mac_driver.init();
|
||||
sixtop_init();
|
||||
packetbuf_clear();
|
||||
memset(&peer_addr, 0, sizeof(peer_addr));
|
||||
sixtop_add_sf(&test_sf);
|
||||
test_sf_input_is_called = 0;
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_input_no_sf,
|
||||
"sixp_input(no_sf)");
|
||||
UNIT_TEST(test_input_no_sf)
|
||||
{
|
||||
uint32_t body;
|
||||
uint8_t *p;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
memset(&body, 0, sizeof(body));
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
UNKNOWN_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
NULL) == 0);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
|
||||
|
||||
p = packetbuf_hdrptr();
|
||||
|
||||
/* length */
|
||||
UNIT_TEST_ASSERT(packetbuf_totlen() == 11);
|
||||
|
||||
/* Termination 1 IE */
|
||||
UNIT_TEST_ASSERT(p[0] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[1] == 0x3f);
|
||||
|
||||
/* IETF IE */
|
||||
UNIT_TEST_ASSERT(p[2] == 0x05);
|
||||
UNIT_TEST_ASSERT(p[3] == 0xa8);
|
||||
|
||||
/* 6top IE */
|
||||
UNIT_TEST_ASSERT(p[4] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[5] == 0x11);
|
||||
UNIT_TEST_ASSERT(p[6] == 0x08);
|
||||
UNIT_TEST_ASSERT(p[7] == UNKNOWN_SF_SFID);
|
||||
UNIT_TEST_ASSERT(p[8] == 0x0a);
|
||||
|
||||
/* Payload Termination IE */
|
||||
UNIT_TEST_ASSERT(p[9] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[10] == 0xf8);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_input_busy,
|
||||
"sixp_input(busy)");
|
||||
UNIT_TEST(test_input_busy)
|
||||
{
|
||||
uint8_t *p;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
/* send a request to the peer first */
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_trans_find(&peer_addr) == NULL);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_CLEAR,
|
||||
TEST_SF_SFID, NULL, 0, &peer_addr,
|
||||
NULL, NULL, 0) == 0);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
UNIT_TEST_ASSERT(sixp_trans_find(&peer_addr) != NULL);
|
||||
|
||||
test_mac_driver.init(); /* clear test_mac_send_is_called status */
|
||||
|
||||
memset(&body, 0, sizeof(body));
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
NULL) == 0);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
|
||||
|
||||
p = packetbuf_hdrptr();
|
||||
|
||||
/* length */
|
||||
UNIT_TEST_ASSERT(packetbuf_totlen() == 11);
|
||||
|
||||
/* Termination 1 IE */
|
||||
UNIT_TEST_ASSERT(p[0] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[1] == 0x3f);
|
||||
|
||||
/* IETF IE */
|
||||
UNIT_TEST_ASSERT(p[2] == 0x05);
|
||||
UNIT_TEST_ASSERT(p[3] == 0xa8);
|
||||
|
||||
/* 6top IE */
|
||||
UNIT_TEST_ASSERT(p[4] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[5] == 0x11);
|
||||
UNIT_TEST_ASSERT(p[6] == 0x0a);
|
||||
UNIT_TEST_ASSERT(p[7] == TEST_SF_SFID);
|
||||
UNIT_TEST_ASSERT(p[8] == 0x0a);
|
||||
|
||||
/* Payload Termination IE */
|
||||
UNIT_TEST_ASSERT(p[9] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[10] == 0xf8);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_input_no_memory,
|
||||
"sixp_input(no_memory)");
|
||||
UNIT_TEST(test_input_no_memory)
|
||||
{
|
||||
uint32_t body;
|
||||
sixp_pkt_t pkt;
|
||||
uint8_t *p;
|
||||
linkaddr_t addr;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
memset(&body, 0, sizeof(body));
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.u8[0] = 1;
|
||||
UNIT_TEST_ASSERT(sixp_trans_alloc(&pkt, &addr) != NULL);
|
||||
addr.u8[0] = 2;
|
||||
UNIT_TEST_ASSERT(sixp_trans_alloc(&pkt, &addr) != NULL);
|
||||
addr.u8[0] = 3;
|
||||
/* no memory left for another transaction */
|
||||
UNIT_TEST_ASSERT(sixp_trans_alloc(&pkt, &addr) == NULL);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
|
||||
|
||||
p = packetbuf_hdrptr();
|
||||
|
||||
/* length */
|
||||
UNIT_TEST_ASSERT(packetbuf_totlen() == 11);
|
||||
|
||||
/* Termination 1 IE */
|
||||
UNIT_TEST_ASSERT(p[0] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[1] == 0x3f);
|
||||
|
||||
/* IETF IE */
|
||||
UNIT_TEST_ASSERT(p[2] == 0x05);
|
||||
UNIT_TEST_ASSERT(p[3] == 0xa8);
|
||||
|
||||
/* 6top IE */
|
||||
UNIT_TEST_ASSERT(p[4] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[5] == 0x11);
|
||||
UNIT_TEST_ASSERT(p[6] == 0x0b);
|
||||
UNIT_TEST_ASSERT(p[7] == TEST_SF_SFID);
|
||||
UNIT_TEST_ASSERT(p[8] == 0x0a);
|
||||
|
||||
/* Payload Termination IE */
|
||||
UNIT_TEST_ASSERT(p[9] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[10] == 0xf8);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_input_schedule_generation,
|
||||
"sixp_input(schedule_generation)");
|
||||
UNIT_TEST(test_input_schedule_generation)
|
||||
{
|
||||
sixp_nbr_t *nbr;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
memset(&body, 0, sizeof(body));
|
||||
|
||||
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr)) != NULL);
|
||||
/* nbr has GTX 0 and GRX 0 now */
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 1, 1,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
NULL) == 0);
|
||||
|
||||
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
|
||||
UNIT_TEST_ASSERT(test_sf_input_is_called == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_gtx(nbr) == 0);
|
||||
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
|
||||
UNIT_TEST_ASSERT(test_sf_input_is_called == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_nbr_advance_grx(nbr) == 0);
|
||||
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
|
||||
UNIT_TEST_ASSERT(test_sf_input_is_called == 1);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_find(&peer_addr)) != NULL);
|
||||
UNIT_TEST_ASSERT(sixp_trans_get_state(trans) ==
|
||||
SIXP_TRANS_STATE_REQUEST_RECEIVED);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_request_1,
|
||||
"sixp_output(request_1)");
|
||||
UNIT_TEST(test_output_request_1)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
test_setup();
|
||||
memset(&body, 0, sizeof(body));
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
memset(&body, 0, sizeof(body));
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, (uint8_t *)&body, sizeof(body),
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_request_2,
|
||||
"sixp_output(request_2)");
|
||||
UNIT_TEST(test_output_request_2)
|
||||
{
|
||||
uint32_t body;
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
test_setup();
|
||||
memset(&body, 0, sizeof(body));
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, (uint8_t *)&body, sizeof(body),
|
||||
&peer_addr, NULL, NULL, 0) == 0);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_response_1,
|
||||
"sixp_output(response_1)");
|
||||
UNIT_TEST(test_output_response_1)
|
||||
{
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_response_2,
|
||||
"sixp_output(response_2)");
|
||||
UNIT_TEST(test_output_response_2)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_response_3,
|
||||
"sixp_output(response_3)");
|
||||
UNIT_TEST(test_output_response_3)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_RECEIVED) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == 0);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_response_4,
|
||||
"sixp_output(response_4)");
|
||||
UNIT_TEST(test_output_response_4)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_SENT) == 0);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_RESPONSE_RECEIVED) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_RESPONSE,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_confirmation_1,
|
||||
"sixp_output(confirmation_1)");
|
||||
UNIT_TEST(test_output_confirmation_1)
|
||||
{
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_CONFIRMATION,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_confirmation_2,
|
||||
"sixp_output(confirmation_2)");
|
||||
UNIT_TEST(test_output_confirmation_2)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_CONFIRMATION,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_confirmation_3,
|
||||
"sixp_output(confirmation_3)");
|
||||
UNIT_TEST(test_output_confirmation_3)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_SENT) == 0);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_RESPONSE_RECEIVED) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_CONFIRMATION,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == 0);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 1);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output_confirmation_4,
|
||||
"sixp_output(confirmation_4)");
|
||||
UNIT_TEST(test_output_confirmation_4)
|
||||
{
|
||||
sixp_pkt_t pkt;
|
||||
sixp_trans_t *trans;
|
||||
uint32_t body;
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
test_setup();
|
||||
|
||||
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
|
||||
TEST_SF_SFID, 10, 0, 0,
|
||||
(const uint8_t *)&body, sizeof(body),
|
||||
&pkt) == 0);
|
||||
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_SENT) == 0);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_RESPONSE_RECEIVED) == 0);
|
||||
UNIT_TEST_ASSERT(
|
||||
sixp_trans_transit_state(trans,
|
||||
SIXP_TRANS_STATE_CONFIRMATION_SENT) == 0);
|
||||
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_CONFIRMATION,
|
||||
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
|
||||
TEST_SF_SFID, NULL, 0,
|
||||
&peer_addr, NULL, NULL, 0) == -1);
|
||||
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
PROCESS_THREAD(test_process, ev, data)
|
||||
{
|
||||
static struct etimer et;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
/* wait until the sixtop module gets ready */
|
||||
etimer_set(&et, CLOCK_SECOND);
|
||||
tschmac_driver.init();
|
||||
tschmac_driver.on();
|
||||
tsch_set_coordinator(1);
|
||||
while(tsch_is_associated == 0) {
|
||||
PROCESS_YIELD_UNTIL(etimer_expired(&et));
|
||||
etimer_reset(&et);
|
||||
}
|
||||
|
||||
printf("Run unit-test\n");
|
||||
printf("---\n");
|
||||
|
||||
UNIT_TEST_RUN(test_input_no_sf);
|
||||
UNIT_TEST_RUN(test_input_busy);
|
||||
UNIT_TEST_RUN(test_input_no_memory);
|
||||
UNIT_TEST_RUN(test_input_schedule_generation);
|
||||
|
||||
UNIT_TEST_RUN(test_output_request_1);
|
||||
UNIT_TEST_RUN(test_output_request_2);
|
||||
UNIT_TEST_RUN(test_output_response_1);
|
||||
UNIT_TEST_RUN(test_output_response_2);
|
||||
UNIT_TEST_RUN(test_output_response_3);
|
||||
UNIT_TEST_RUN(test_output_response_4);
|
||||
UNIT_TEST_RUN(test_output_confirmation_1);
|
||||
UNIT_TEST_RUN(test_output_confirmation_2);
|
||||
UNIT_TEST_RUN(test_output_confirmation_3);
|
||||
UNIT_TEST_RUN(test_output_confirmation_4);
|
||||
|
||||
printf("=check-me= DONE\n");
|
||||
PROCESS_END();
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "contiki-net.h"
|
||||
#include "contiki-lib.h"
|
||||
#include "lib/assert.h"
|
||||
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop.h"
|
||||
#include "net/mac/tsch/sixtop/sixtop-conf.h"
|
||||
|
||||
#include "unit-test/unit-test.h"
|
||||
#include "common.h"
|
||||
|
||||
#if SIXTOP_MAX_SCHEDULING_FUNCTIONS != 2
|
||||
#error SIXTOP_CONF_MAX_SCHEDULING_FUNCTIONS must be set with 2 for this test
|
||||
#endif
|
||||
|
||||
#define TEST_SF1_SFID 0xf1
|
||||
#define TEST_SF2_SFID 0xf2
|
||||
#define TEST_SF3_SFID 0xf3
|
||||
|
||||
static uint8_t sf_init_vector;
|
||||
static void test_sf1_init(void);
|
||||
static void test_sf2_init(void);
|
||||
static void test_sf3_init(void);
|
||||
static void reset_sf_init_vector(void);
|
||||
|
||||
static const sixtop_sf_t test_sf1 = {
|
||||
TEST_SF1_SFID,
|
||||
0,
|
||||
test_sf1_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const sixtop_sf_t test_sf2 = {
|
||||
TEST_SF2_SFID,
|
||||
0,
|
||||
test_sf2_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const sixtop_sf_t test_sf3 = {
|
||||
TEST_SF3_SFID,
|
||||
0,
|
||||
test_sf3_init,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
test_sf1_init(void)
|
||||
{
|
||||
sf_init_vector |= TEST_SF1_SFID;
|
||||
}
|
||||
|
||||
static void
|
||||
test_sf2_init(void)
|
||||
{
|
||||
sf_init_vector |= TEST_SF2_SFID;
|
||||
}
|
||||
|
||||
static void
|
||||
test_sf3_init(void)
|
||||
{
|
||||
sf_init_vector |= TEST_SF3_SFID;
|
||||
}
|
||||
|
||||
void
|
||||
reset_sf_init_vector(void)
|
||||
{
|
||||
sf_init_vector = 0;
|
||||
}
|
||||
|
||||
PROCESS(test_process, "6top module APIs test");
|
||||
AUTOSTART_PROCESSES(&test_process);
|
||||
|
||||
UNIT_TEST_REGISTER(test_add_sf,
|
||||
"sixtop_add_sf() should add a SF");
|
||||
UNIT_TEST(test_add_sf)
|
||||
{
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/* confirm any of test_sf{1,2,3} is not added yet. */
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF1_SFID) == NULL);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF2_SFID) == NULL);
|
||||
|
||||
/* add test_sf1 */
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf1) == 0);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF1_SFID) == &test_sf1);
|
||||
|
||||
/* add test_sf2 */
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf2) == 0);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF2_SFID) == &test_sf2);
|
||||
|
||||
/*
|
||||
* add test_sf3; should fail because of lack of memory.
|
||||
* SIXTOP_MAX_SCHEDULING_FUNCTIONS is set with two.
|
||||
*/
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf3) == -1);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF3_SFID) == NULL);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_find_sf,
|
||||
"sixtop_find_sf() should find a SF which has been added");
|
||||
UNIT_TEST(test_find_sf)
|
||||
{
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/*
|
||||
* See test_add_sf(); sixtop_find_sf() is tested together with sixtop_add_sf()
|
||||
* in it.
|
||||
*/
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_init,
|
||||
"sixtop_init() should remove all SFs in the 6top module");
|
||||
UNIT_TEST(test_init)
|
||||
{
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/* set up a precondition where some SFs has been added */
|
||||
if(sixtop_find_sf(TEST_SF1_SFID) == NULL) {
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf1) == 0);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF1_SFID) != NULL);
|
||||
}
|
||||
|
||||
if(sixtop_find_sf(TEST_SF2_SFID) == NULL) {
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf2) == 0);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF2_SFID) != NULL);
|
||||
}
|
||||
|
||||
/* call sixtop_init() which removes all the SFs in the module */
|
||||
sixtop_init();
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF1_SFID) == NULL);
|
||||
UNIT_TEST_ASSERT(sixtop_find_sf(TEST_SF2_SFID) == NULL);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_output,
|
||||
"test sixtop_output()");
|
||||
UNIT_TEST(test_output)
|
||||
{
|
||||
linkaddr_t peer_addr;
|
||||
uint8_t *p;
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
packetbuf_clear();
|
||||
UNIT_TEST_ASSERT(packetbuf_hdralloc(1) > 0);
|
||||
p = packetbuf_hdrptr();
|
||||
p[0] = 0xca; // header
|
||||
p = packetbuf_dataptr();
|
||||
p[0] = 0xfe; // data
|
||||
packetbuf_set_datalen(1);
|
||||
|
||||
sixtop_output(&peer_addr, NULL, NULL);
|
||||
|
||||
p = packetbuf_hdrptr();
|
||||
|
||||
/* Length */
|
||||
UNIT_TEST_ASSERT(packetbuf_totlen() == 9);
|
||||
|
||||
/* Termination 1 IE */
|
||||
UNIT_TEST_ASSERT(p[0] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[1] == 0x3f);
|
||||
|
||||
/* IETF IE */
|
||||
UNIT_TEST_ASSERT(p[2] == 0x03);
|
||||
UNIT_TEST_ASSERT(p[3] == 0xa8);
|
||||
|
||||
/* 6top IE Sub-ID */
|
||||
UNIT_TEST_ASSERT(p[4] == 0x00);
|
||||
/* test data set above */
|
||||
UNIT_TEST_ASSERT(p[5] == 0xca);
|
||||
UNIT_TEST_ASSERT(p[6] == 0xfe);
|
||||
|
||||
/* Payload Termination IE */
|
||||
UNIT_TEST_ASSERT(p[7] == 0x00);
|
||||
UNIT_TEST_ASSERT(p[8] == 0xf8);
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(test_init_sf,
|
||||
"sixtop_init_sf() should invoke every SF->init()");
|
||||
UNIT_TEST(test_init_sf)
|
||||
{
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/* remove all the SFs in the 6top module */
|
||||
sixtop_init();
|
||||
|
||||
/* add test_sf1 */
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf1) == 0);
|
||||
reset_sf_init_vector();
|
||||
sixtop_init_sf();
|
||||
UNIT_TEST_ASSERT(sf_init_vector == TEST_SF1_SFID);
|
||||
|
||||
/* add test_sf2 */
|
||||
UNIT_TEST_ASSERT(sixtop_add_sf(&test_sf2) == 0);
|
||||
reset_sf_init_vector();
|
||||
sixtop_init_sf();
|
||||
UNIT_TEST_ASSERT(sf_init_vector == (TEST_SF1_SFID | TEST_SF2_SFID));
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
PROCESS_THREAD(test_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("Run unit-test\n");
|
||||
printf("---\n");
|
||||
|
||||
UNIT_TEST_RUN(test_add_sf);
|
||||
UNIT_TEST_RUN(test_find_sf);
|
||||
UNIT_TEST_RUN(test_init);
|
||||
UNIT_TEST_RUN(test_init_sf);
|
||||
UNIT_TEST_RUN(test_output);
|
||||
|
||||
printf("=check-me= DONE\n");
|
||||
PROCESS_END();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
TIMEOUT(10000, log.testFailed());
|
||||
|
||||
var failed = false;
|
||||
var done = 0;
|
||||
|
||||
while(done < sim.getMotes().length) {
|
||||
YIELD();
|
||||
|
||||
log.log(time + " " + "node-" + id + " "+ msg + "\n");
|
||||
|
||||
if(msg.contains("=check-me=") == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(msg.contains("FAILED")) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if(msg.contains("DONE")) {
|
||||
done++;
|
||||
}
|
||||
}
|
||||
if(failed) {
|
||||
log.testFailed();
|
||||
}
|
||||
log.testOK();
|
||||
|
Loading…
Reference in New Issue