Merge pull request #357 from yatch/pr/6top-protocol-draft-10

Update 6top Protocol (6P) to draft-10
This commit is contained in:
George Oikonomou 2018-03-29 16:30:14 +01:00 committed by GitHub
commit 941d8457b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1490 additions and 379 deletions

View File

@ -37,4 +37,6 @@
#define TSCH_CONF_AUTOSTART 1 #define TSCH_CONF_AUTOSTART 1
#define TSCH_CONF_DEFAULT_HOPPING_SEQUENCE TSCH_HOPPING_SEQUENCE_1_1 #define TSCH_CONF_DEFAULT_HOPPING_SEQUENCE TSCH_HOPPING_SEQUENCE_1_1
#define LOG_CONF_LEVEL_6TOP LOG_LEVEL_DBG
#endif /* _PROJECT_CONF_H_ */ #endif /* _PROJECT_CONF_H_ */

View File

@ -35,7 +35,8 @@
#include <net/mac/tsch/sixtop/sixtop.h> #include <net/mac/tsch/sixtop/sixtop.h>
/* Hard-coded MAC address of the TSCH coordinator */ /* Hard-coded MAC address of the TSCH coordinator */
static linkaddr_t coordinator_addr = {{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}; static linkaddr_t coordinator_addr = {{ 0x00, 0x01, 0x00, 0x01,
0x00, 0x01, 0x00, 0x01 }};
extern const sixtop_sf_t test_sf; extern const sixtop_sf_t test_sf;
extern int test_sf_start(const linkaddr_t *addr); extern int test_sf_start(const linkaddr_t *addr);
@ -43,8 +44,6 @@ extern int test_sf_start(const linkaddr_t *addr);
PROCESS(sixp_node_process, "6P node"); PROCESS(sixp_node_process, "6P node");
AUTOSTART_PROCESSES(&sixp_node_process); AUTOSTART_PROCESSES(&sixp_node_process);
#define COORDINATOR_NODE_ID 1
PROCESS_THREAD(sixp_node_process, ev, data) PROCESS_THREAD(sixp_node_process, ev, data)
{ {
PROCESS_BEGIN(); PROCESS_BEGIN();

View File

@ -67,16 +67,17 @@ static void test_relocate_2_step(const linkaddr_t *peer_addr);
static void test_count_2_step(const linkaddr_t *peer_addr); static void test_count_2_step(const linkaddr_t *peer_addr);
static void test_list_2_step(const linkaddr_t *peer_addr); static void test_list_2_step(const linkaddr_t *peer_addr);
static void test_list_2_step_eol(const linkaddr_t *peer_addr); static void test_list_2_step_eol(const linkaddr_t *peer_addr);
static void test_signal_2_step(const linkaddr_t *peer_addr);
static void test_clear_2_step_success(const linkaddr_t *peer_addr); static void test_clear_2_step_success(const linkaddr_t *peer_addr);
static void test_clear_2_step_error(const linkaddr_t *peer_addr);
static void test_clear_2_step_eol(const linkaddr_t *peer_addr); static void test_clear_2_step_eol(const linkaddr_t *peer_addr);
static void test_clear_2_step_err(const linkaddr_t *peer_addr);
static void test_clear_2_step_reset(const linkaddr_t *peer_addr); static void test_clear_2_step_reset(const linkaddr_t *peer_addr);
static void test_clear_2_step_version(const linkaddr_t *peer_addr); static void test_clear_2_step_version(const linkaddr_t *peer_addr);
static void test_clear_2_step_sfid(const linkaddr_t *peer_addr); static void test_clear_2_step_sfid(const linkaddr_t *peer_addr);
static void test_clear_2_step_gen(const linkaddr_t *peer_addr); static void test_clear_2_step_seqnum(const linkaddr_t *peer_addr);
static void test_clear_2_step_busy(const linkaddr_t *peer_addr);
static void test_clear_2_step_nores(const linkaddr_t *peer_addr);
static void test_clear_2_step_celllist(const linkaddr_t *peer_addr); static void test_clear_2_step_celllist(const linkaddr_t *peer_addr);
static void test_clear_2_step_busy(const linkaddr_t *peer_addr);
static void test_clear_2_step_locked(const linkaddr_t *peer_addr);
typedef void (*test_func)(const linkaddr_t *peer_addr); typedef void (*test_func)(const linkaddr_t *peer_addr);
static const test_func test_case[] = { static const test_func test_case[] = {
@ -88,27 +89,19 @@ static const test_func test_case[] = {
test_count_2_step, test_count_2_step,
test_list_2_step, test_list_2_step,
test_list_2_step_eol, test_list_2_step_eol,
test_signal_2_step,
test_clear_2_step_success, test_clear_2_step_success,
test_clear_2_step_error,
test_clear_2_step_eol, test_clear_2_step_eol,
test_clear_2_step_err,
test_clear_2_step_reset, test_clear_2_step_reset,
test_clear_2_step_version, test_clear_2_step_version,
test_clear_2_step_sfid, test_clear_2_step_sfid,
test_clear_2_step_gen, test_clear_2_step_seqnum,
test_clear_2_step_busy,
test_clear_2_step_nores,
test_clear_2_step_celllist, test_clear_2_step_celllist,
test_clear_2_step_busy,
test_clear_2_step_locked,
}; };
static void
advance_gen(const linkaddr_t *peer_addr)
{
sixp_nbr_t *nbr;
nbr = sixp_nbr_find(peer_addr);
assert(nbr != NULL);
assert(sixp_nbr_advance_gen(nbr) == 0);
}
static void static void
set_peer_addr(const linkaddr_t *addr) set_peer_addr(const linkaddr_t *addr)
{ {
@ -202,10 +195,8 @@ test_add_2_step(const linkaddr_t *peer_addr)
peer_addr, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
test_index++; test_index++;
advance_gen(peer_addr);
} else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) { } else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
process_post(&test_sf_process, test_sf_trans_done, NULL); process_post(&test_sf_process, test_sf_trans_done, NULL);
advance_gen(peer_addr);
} }
} }
} }
@ -266,10 +257,8 @@ test_add_3_step(const linkaddr_t *peer_addr)
peer_addr, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
process_post(&test_sf_process, test_sf_trans_done, NULL); process_post(&test_sf_process, test_sf_trans_done, NULL);
advance_gen(peer_addr);
} else if (state == SIXP_TRANS_STATE_CONFIRMATION_RECEIVED){ } else if (state == SIXP_TRANS_STATE_CONFIRMATION_RECEIVED){
test_index++; test_index++;
advance_gen(peer_addr);
} }
} }
} }
@ -325,10 +314,8 @@ test_delete_2_step(const linkaddr_t *peer_addr)
peer_addr, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
test_index++; test_index++;
advance_gen(peer_addr);
} else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) { } else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
process_post(&test_sf_process, test_sf_trans_done, NULL); process_post(&test_sf_process, test_sf_trans_done, NULL);
advance_gen(peer_addr);
} }
} }
} }
@ -390,10 +377,8 @@ test_delete_3_step(const linkaddr_t *peer_addr)
peer_addr, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
process_post(&test_sf_process, test_sf_trans_done, NULL); process_post(&test_sf_process, test_sf_trans_done, NULL);
advance_gen(peer_addr);
} else if (state == SIXP_TRANS_STATE_CONFIRMATION_RECEIVED) { } else if (state == SIXP_TRANS_STATE_CONFIRMATION_RECEIVED) {
test_index++; test_index++;
advance_gen(peer_addr);
} }
} }
} }
@ -459,10 +444,8 @@ test_relocate_2_step(const linkaddr_t *peer_addr)
peer_addr, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
test_index++; test_index++;
advance_gen(peer_addr);
} else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) { } else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
process_post(&test_sf_process, test_sf_trans_done, NULL); process_post(&test_sf_process, test_sf_trans_done, NULL);
advance_gen(peer_addr);
} }
} }
} }
@ -658,6 +641,70 @@ test_list_2_step_eol(const linkaddr_t *peer_addr)
} }
} }
static void
test_signal_2_step(const linkaddr_t *peer_addr)
{
sixp_trans_t *trans = sixp_trans_find(peer_addr);
uint8_t payload[10];
size_t payload_len;
if(trans == NULL) {
memset(sixp_pkt_buf, 0, sizeof(sixp_pkt_buf));
assert(
sixp_pkt_set_metadata(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_LIST,
sample_metadata,
sixp_pkt_buf, sizeof(sixp_pkt_buf)) == 0);
payload[0] = 0xbe;
payload[1] = 0xef;
payload[2] = 0xca;
payload[3] = 0xfe;
payload_len = 4;
assert(
sixp_pkt_set_payload(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_SIGNAL,
(const uint8_t *)payload, payload_len,
sixp_pkt_buf, sizeof(sixp_pkt_buf)) == 0);
assert(sixp_output(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_SIGNAL,
TEST_SF_SFID, sixp_pkt_buf,
sizeof(sixp_pkt_metadata_t) + payload_len,
peer_addr,
NULL, NULL, 0) == 0);
} else {
sixp_trans_state_t state;
printf("hoge\n");
state = sixp_trans_get_state(trans);
if(state == SIXP_TRANS_STATE_REQUEST_RECEIVED) {
payload[0] = 0x01;
payload[1] = 0x02;
payload[2] = 0x03;
payload[3] = 0x04;
payload[4] = 0x05;
payload_len = 5;
assert(
sixp_pkt_set_payload(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
(const uint8_t *)payload, payload_len,
sixp_pkt_buf, sizeof(sixp_pkt_buf)) == 0);
sixp_output(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SUCCESS,
TEST_SF_SFID, sixp_pkt_buf,
payload_len,
peer_addr,
NULL, NULL, 0);
test_index++;
} else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
process_post(&test_sf_process, test_sf_trans_done, NULL);
}
}
}
static void static void
test_clear_2_step(const linkaddr_t *peer_addr, sixp_pkt_rc_t rc) test_clear_2_step(const linkaddr_t *peer_addr, sixp_pkt_rc_t rc)
{ {
@ -699,9 +746,9 @@ test_clear_2_step_success(const linkaddr_t *peer_addr)
} }
static void static void
test_clear_2_step_error(const linkaddr_t *peer_addr) test_clear_2_step_err(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_ERROR); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR);
} }
static void static void
@ -719,37 +766,37 @@ test_clear_2_step_reset(const linkaddr_t *peer_addr)
static void static void
test_clear_2_step_version(const linkaddr_t *peer_addr) test_clear_2_step_version(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_VERSION); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR_VERSION);
} }
static void static void
test_clear_2_step_sfid(const linkaddr_t *peer_addr) test_clear_2_step_sfid(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_SFID); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR_SFID);
} }
static void static void
test_clear_2_step_gen(const linkaddr_t *peer_addr) test_clear_2_step_seqnum(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_GEN); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR_SEQNUM);
} }
static void static void
test_clear_2_step_busy(const linkaddr_t *peer_addr) test_clear_2_step_busy(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_BUSY); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR_BUSY);
} }
static void static void
test_clear_2_step_nores(const linkaddr_t *peer_addr) test_clear_2_step_locked(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_NORES); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR_LOCKED);
} }
static void static void
test_clear_2_step_celllist(const linkaddr_t *peer_addr) test_clear_2_step_celllist(const linkaddr_t *peer_addr)
{ {
test_clear_2_step(peer_addr, SIXP_PKT_RC_CELLLIST); test_clear_2_step(peer_addr, SIXP_PKT_RC_ERR_CELLLIST);
} }
PROCESS_THREAD(test_sf_process, ev, data) PROCESS_THREAD(test_sf_process, ev, data)

View File

@ -75,7 +75,6 @@ typedef void (req_handler_t)(const linkaddr_t *peer_addr,
typedef void (res_handler_t)(const linkaddr_t *peer_addr, sixp_pkt_rc_t rc, typedef void (res_handler_t)(const linkaddr_t *peer_addr, sixp_pkt_rc_t rc,
const uint8_t *body, size_t body_len); const uint8_t *body, size_t body_len);
static void advance_gen(const linkaddr_t *peer_addr);
static void add_res_sent_callback(void *arg, uint16_t arg_len, static void add_res_sent_callback(void *arg, uint16_t arg_len,
const linkaddr_t *dest_addr, const linkaddr_t *dest_addr,
sixp_output_status_t status); sixp_output_status_t status);
@ -145,17 +144,6 @@ static const struct {
{ SIXP_PKT_CMD_UNAVAILABLE, NULL, NULL } { SIXP_PKT_CMD_UNAVAILABLE, NULL, NULL }
}; };
static void
advance_gen(const linkaddr_t *peer_addr)
{
sixp_nbr_t *nbr;
assert((nbr = sixp_nbr_find(peer_addr)) != NULL);
if(nbr == NULL) {
return;
}
assert(sixp_nbr_advance_gen(nbr) == 0);
}
static void static void
add_res_sent_callback(void *arg, uint16_t arg_len, add_res_sent_callback(void *arg, uint16_t arg_len,
const linkaddr_t *dest_addr, const linkaddr_t *dest_addr,
@ -168,7 +156,6 @@ add_res_sent_callback(void *arg, uint16_t arg_len,
} else { } else {
add_cell(dest_addr, (sf_plugtest_cell_t *)arg, LINK_OPTION_RX); add_cell(dest_addr, (sf_plugtest_cell_t *)arg, LINK_OPTION_RX);
} }
advance_gen(dest_addr);
} }
static void static void
@ -182,7 +169,6 @@ delete_res_sent_callback(void *arg, uint16_t arg_len,
LOG_ERR("error in sending a response\n"); LOG_ERR("error in sending a response\n");
} else { } else {
delete_cell(dest_addr, (sf_plugtest_cell_t *)arg); delete_cell(dest_addr, (sf_plugtest_cell_t *)arg);
advance_gen(dest_addr);
} }
} }
@ -338,7 +324,7 @@ add_req_handler(const linkaddr_t *peer_addr,
reserve_cell(peer_addr, &pending_cell) < 0) { reserve_cell(peer_addr, &pending_cell) < 0) {
LOG_ERR("Failed to add a cell [slot:%u]\n", timeslot); LOG_ERR("Failed to add a cell [slot:%u]\n", timeslot);
sixp_output(SIXP_PKT_TYPE_RESPONSE, sixp_output(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_NORES, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_BUSY,
SF_PLUGTEST_SFID, NULL, 0, peer_addr, SF_PLUGTEST_SFID, NULL, 0, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
} else { } else {
@ -378,7 +364,6 @@ add_res_handler(const linkaddr_t *peer_addr, sixp_pkt_rc_t rc,
add_cell(peer_addr, (sf_plugtest_cell_t *)cell, LINK_OPTION_TX) < 0) { add_cell(peer_addr, (sf_plugtest_cell_t *)cell, LINK_OPTION_TX) < 0) {
LOG_ERR("Failed to add a cell [slot:%u]\n", timeslot); LOG_ERR("Failed to add a cell [slot:%u]\n", timeslot);
} }
advance_gen(peer_addr);
} }
static void static void
@ -423,7 +408,7 @@ delete_req_handler(const linkaddr_t *peer_addr,
memcmp(peer_addr, &link->addr, sizeof(linkaddr_t)) != 0) { memcmp(peer_addr, &link->addr, sizeof(linkaddr_t)) != 0) {
LOG_ERR("Failed to delete a cell [slot:%u]\n", timeslot); LOG_ERR("Failed to delete a cell [slot:%u]\n", timeslot);
sixp_output(SIXP_PKT_TYPE_RESPONSE, sixp_output(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_NORES, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_BUSY,
SF_PLUGTEST_SFID, NULL, 0, peer_addr, SF_PLUGTEST_SFID, NULL, 0, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
} else { } else {
@ -473,7 +458,6 @@ delete_res_handler(const linkaddr_t *peer_addr, sixp_pkt_rc_t rc,
delete_cell(peer_addr, cell) < 0) { delete_cell(peer_addr, cell) < 0) {
LOG_ERR("Failed to delete a cell [slot:%u]\n", timeslot); LOG_ERR("Failed to delete a cell [slot:%u]\n", timeslot);
} }
advance_gen(peer_addr);
} }
static void static void
@ -503,7 +487,7 @@ count_req_handler(const linkaddr_t *peer_addr,
if((slotframe = tsch_schedule_get_slotframe_by_handle(0)) == NULL) { if((slotframe = tsch_schedule_get_slotframe_by_handle(0)) == NULL) {
sixp_output(SIXP_PKT_TYPE_RESPONSE, sixp_output(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERROR, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR,
SF_PLUGTEST_SFID, NULL, 0, peer_addr, SF_PLUGTEST_SFID, NULL, 0, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
return; return;
@ -602,7 +586,7 @@ list_req_handler(const linkaddr_t *peer_addr,
if((slotframe = tsch_schedule_get_slotframe_by_handle(0)) == NULL) { if((slotframe = tsch_schedule_get_slotframe_by_handle(0)) == NULL) {
sixp_output(SIXP_PKT_TYPE_RESPONSE, sixp_output(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERROR, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR,
SF_PLUGTEST_SFID, NULL, 0, peer_addr, SF_PLUGTEST_SFID, NULL, 0, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
return; return;
@ -684,7 +668,7 @@ clear_req_handler(const linkaddr_t *peer_addr,
if((slotframe = tsch_schedule_get_slotframe_by_handle(0)) == NULL) { if((slotframe = tsch_schedule_get_slotframe_by_handle(0)) == NULL) {
sixp_output(SIXP_PKT_TYPE_RESPONSE, sixp_output(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERROR, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR,
SF_PLUGTEST_SFID, NULL, 0, peer_addr, SF_PLUGTEST_SFID, NULL, 0, peer_addr,
NULL, NULL, 0); NULL, NULL, 0);
return; return;

View File

@ -198,7 +198,6 @@ add_response_sent_callback(void *arg, uint16_t arg_len,
(nbr = sixp_nbr_find(dest_addr)) != NULL) { (nbr = sixp_nbr_find(dest_addr)) != NULL) {
add_links_to_schedule(dest_addr, LINK_OPTION_RX, add_links_to_schedule(dest_addr, LINK_OPTION_RX,
cell_list, cell_list_len); cell_list, cell_list_len);
sixp_nbr_advance_gen(nbr);
} }
} }
@ -222,7 +221,6 @@ delete_response_sent_callback(void *arg, uint16_t arg_len,
body, body_len) == 0 && body, body_len) == 0 &&
(nbr = sixp_nbr_find(dest_addr)) != NULL) { (nbr = sixp_nbr_find(dest_addr)) != NULL) {
remove_links_to_schedule(cell_list, cell_list_len); remove_links_to_schedule(cell_list, cell_list_len);
sixp_nbr_advance_gen(nbr);
} }
} }
@ -429,7 +427,6 @@ response_input(sixp_pkt_rc_t rc,
PRINTF("\n"); PRINTF("\n");
add_links_to_schedule(peer_addr, LINK_OPTION_TX, add_links_to_schedule(peer_addr, LINK_OPTION_TX,
cell_list, cell_list_len); cell_list, cell_list_len);
sixp_nbr_advance_gen(nbr);
break; break;
case SIXP_PKT_CMD_DELETE: case SIXP_PKT_CMD_DELETE:
if(sixp_pkt_get_cell_list(SIXP_PKT_TYPE_RESPONSE, if(sixp_pkt_get_cell_list(SIXP_PKT_TYPE_RESPONSE,
@ -443,7 +440,6 @@ response_input(sixp_pkt_rc_t rc,
print_cell_list(cell_list, cell_list_len); print_cell_list(cell_list, cell_list_len);
PRINTF("\n"); PRINTF("\n");
remove_links_to_schedule(cell_list, cell_list_len); remove_links_to_schedule(cell_list, cell_list_len);
sixp_nbr_advance_gen(nbr);
break; break;
case SIXP_PKT_CMD_COUNT: case SIXP_PKT_CMD_COUNT:
case SIXP_PKT_CMD_LIST: case SIXP_PKT_CMD_LIST:

View File

@ -61,7 +61,6 @@ typedef struct sixp_nbr {
struct sixp_nbr *next; struct sixp_nbr *next;
linkaddr_t addr; linkaddr_t addr;
uint8_t next_seqno; uint8_t next_seqno;
uint8_t gen;
} sixp_nbr_t; } sixp_nbr_t;
NBR_TABLE(sixp_nbr_t, sixp_nbrs); NBR_TABLE(sixp_nbr_t, sixp_nbrs);
@ -105,7 +104,6 @@ sixp_nbr_alloc(const linkaddr_t *addr)
linkaddr_copy(&nbr->addr, addr); linkaddr_copy(&nbr->addr, addr);
nbr->next_seqno = SIXP_INITIAL_SEQUENCE_NUMBER; nbr->next_seqno = SIXP_INITIAL_SEQUENCE_NUMBER;
nbr->gen = 0;
return nbr; return nbr;
} }
@ -119,39 +117,6 @@ sixp_nbr_free(sixp_nbr_t *nbr)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int16_t
sixp_nbr_get_gen(sixp_nbr_t *nbr)
{
assert(nbr != NULL);
if(nbr == NULL) {
LOG_ERR("6P-nbr: sixp_nbr_get_gtx() fails because of invalid argument\n");
return -1;
}
return nbr->gen;
}
/*---------------------------------------------------------------------------*/
int
sixp_nbr_advance_gen(sixp_nbr_t *nbr)
{
assert(nbr != NULL);
if(nbr == NULL) {
LOG_ERR("6P-nbr: sixp_nbr_advance_gen() fails because of invalid arg\n");
return -1;
}
if(nbr->gen == 0x00 || nbr->gen == 0x09) {
nbr->gen = 0x01;
} else if(nbr->gen < 0x09) {
nbr->gen++;
} else {
/* unexpected condition */
LOG_ERR("6P-nbr: nbr %p has an invalid generation number %02x\n",
nbr, nbr->gen);
return -1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int int
sixp_nbr_get_next_seqno(sixp_nbr_t *nbr) sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
{ {
@ -164,6 +129,30 @@ sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
sixp_nbr_set_next_seqno(sixp_nbr_t *nbr, uint16_t seqno)
{
assert(nbr != NULL);
if(nbr == NULL) {
LOG_ERR("6P-nbr: sixp_nbr_set_next_seqno() fails because of invalid arg\n");
return -1;
}
nbr->next_seqno = seqno;
return 0;
}
/*---------------------------------------------------------------------------*/
int
sixp_nbr_reset_next_seqno(sixp_nbr_t *nbr)
{
assert(nbr != NULL);
if(nbr == NULL) {
LOG_ERR("6P-nbr: sixp_nbr_clear_next_seqno() fails; invalid arg\n");
return -1;
}
nbr->next_seqno = 0;
return 0;
}
/*---------------------------------------------------------------------------*/
int
sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr) sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr)
{ {
assert(nbr != NULL); assert(nbr != NULL);
@ -172,12 +161,12 @@ sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr)
return -1; return -1;
} }
nbr->next_seqno++; nbr->next_seqno++;
if(nbr->next_seqno > 0x0f) { if(nbr->next_seqno == 0) {
/* /*
* nbr->next_seqno, which represents a value of the SeqNum field, won't be * next_seqno can be 0 only by initialization of nbr or by a CLEAR
* larger than 0x0f since he length of SeqNum field is 4 bits. * transaction.
*/ */
nbr->next_seqno = 0; nbr->next_seqno = 1;
} }
return 0; return 0;
} }

View File

@ -62,20 +62,6 @@ sixp_nbr_t *sixp_nbr_alloc(const linkaddr_t *addr);
*/ */
void sixp_nbr_free(sixp_nbr_t *nbr); void sixp_nbr_free(sixp_nbr_t *nbr);
/**
* \brief Return GEN (Generation Number) of a neighbor
* \param nbr The pointer to a neighbor
* \return A value of GEN, -1 on failure
*/
int16_t sixp_nbr_get_gen(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_gen(sixp_nbr_t *nbr);
/** /**
* \brief Get the next sequence number of a neighbor * \brief Get the next sequence number of a neighbor
* \param nbr The pointer to a neighbor * \param nbr The pointer to a neighbor
@ -83,6 +69,21 @@ int sixp_nbr_advance_gen(sixp_nbr_t *nbr);
*/ */
int16_t sixp_nbr_get_next_seqno(sixp_nbr_t *nbr); int16_t sixp_nbr_get_next_seqno(sixp_nbr_t *nbr);
/**
* \brief Set the specified value to the next sequence number of a neighbor
* \param nbr The pointer to a neighbor
* \param seqno Value to be set
* \return 0 on success, -1 on failure
*/
int sixp_nbr_set_next_seqno(sixp_nbr_t *nbr, uint16_t seqno);
/**
* \brief Reset the next sequence number of a neighbor to zero
* \param nbr The pointer to a neighbor
* \return 0 on success, -1 on failure
*/
int sixp_nbr_reset_next_seqno(sixp_nbr_t *nbr);
/** /**
* \brief Increment the next sequence number of a neighbor * \brief Increment the next sequence number of a neighbor
* \param nbr The pointer to a neighbor * \param nbr The pointer to a neighbor

View File

@ -67,6 +67,8 @@ static int32_t get_rel_cell_list_offset(sixp_pkt_type_t type,
sixp_pkt_code_t code); sixp_pkt_code_t code);
static int32_t get_total_num_cells_offset(sixp_pkt_type_t type, static int32_t get_total_num_cells_offset(sixp_pkt_type_t type,
sixp_pkt_code_t code); sixp_pkt_code_t code);
static int32_t get_payload_offset(sixp_pkt_type_t type,
sixp_pkt_code_t code);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int32_t static int32_t
@ -176,7 +178,21 @@ get_total_num_cells_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
} }
return -1; return -1;
} }
/*---------------------------------------------------------------------------*/int /*---------------------------------------------------------------------------*/
static int32_t
get_payload_offset(sixp_pkt_type_t type, sixp_pkt_code_t code)
{
if(type == SIXP_PKT_TYPE_REQUEST && code.value == SIXP_PKT_CMD_SIGNAL) {
return sizeof(sixp_pkt_metadata_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_set_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
sixp_pkt_metadata_t metadata, sixp_pkt_metadata_t metadata,
uint8_t *body, uint16_t body_len) uint8_t *body, uint16_t body_len)
@ -227,7 +243,7 @@ sixp_pkt_get_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
return -1; return -1;
} }
if(body_len < (offset + sizeof(*metadata))) { if(body_len < offset + sizeof(*metadata)) {
LOG_ERR("6P-pkt: cannot get metadata [type=%u, code=%u], ", LOG_ERR("6P-pkt: cannot get metadata [type=%u, code=%u], ",
type, code.value); type, code.value);
LOG_ERR_("body is too short\n"); LOG_ERR_("body is too short\n");
@ -238,7 +254,7 @@ sixp_pkt_get_metadata(sixp_pkt_type_t type, sixp_pkt_code_t code,
* Copy the content in the Metadata field as it is since 6P has no idea about * Copy the content in the Metadata field as it is since 6P has no idea about
* the internal structure of the field. * the internal structure of the field.
*/ */
memcpy(metadata + offset, body, sizeof(*metadata)); memcpy(metadata, body + offset, sizeof(*metadata));
return 0; return 0;
} }
@ -861,6 +877,73 @@ sixp_pkt_get_total_num_cells(sixp_pkt_type_t type, sixp_pkt_code_t code,
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
sixp_pkt_set_payload(sixp_pkt_type_t type, sixp_pkt_code_t code,
const uint8_t *payload, uint16_t payload_len,
uint8_t *body, uint16_t body_len)
{
int32_t offset;
if(body == NULL) {
LOG_ERR("6P-pkt: cannot set metadata; body is null\n");
return -1;
}
if((offset = get_payload_offset(type, code)) < 0) {
LOG_ERR("6P-pkt: cannot set payload [type=%u, code=%u], invalid type\n",
type, code.value);
return -1;
}
if(body_len < (offset + payload_len)) {
LOG_ERR("6P-pkt: cannot set payload, body is too short [body_len=%u]\n",
body_len);
return -1;
}
/*
* Copy the content into the Payload field as it is since 6P has no idea
* about the internal structure of the field.
*/
memcpy(body + offset, payload, payload_len);
return 0;
}
/*---------------------------------------------------------------------------*/
int
sixp_pkt_get_payload(sixp_pkt_type_t type, sixp_pkt_code_t code,
uint8_t *buf, uint16_t buf_len,
const uint8_t *body, uint16_t body_len)
{
int32_t offset;
if(buf == NULL || body == NULL) {
LOG_ERR("6P-pkt: cannot get payload; invalid argument\n");
return -1;
}
if((offset = get_payload_offset(type, code)) < 0) {
LOG_ERR("6P-pkt: cannot get payload [type=%u, code=%u], invalid type\n",
type, code.value);
return -1;
}
if((body_len - offset) > buf_len) {
LOG_ERR("6P-pkt: cannot get payload [type=%u, code=%u], ",
type, code.value);
LOG_ERR_("buf_len is too short\n");
return -1;
}
/*
* Copy the content in the Payload field as it is since 6P has no idea about
* the internal structure of the field.
*/
memcpy(buf, body + offset, buf_len);
return 0;
}
/*---------------------------------------------------------------------------*/
int
sixp_pkt_parse(const uint8_t *buf, uint16_t len, sixp_pkt_parse(const uint8_t *buf, uint16_t len,
sixp_pkt_t *pkt) sixp_pkt_t *pkt)
{ {
@ -870,24 +953,20 @@ sixp_pkt_parse(const uint8_t *buf, uint16_t len,
return -1; return -1;
} }
memset(pkt, 0, sizeof(sixp_pkt_t));
/* read the first 4 octets */ /* read the first 4 octets */
if(len < 4) { if(len < 4) {
LOG_ERR("6P-pkt: sixp_pkt_parse() fails because it's a too short packet\n"); LOG_ERR("6P-pkt: sixp_pkt_parse() fails because it's a too short packet\n");
return -1; return -1;
} }
if((buf[0] & 0x0f) != SIXP_PKT_VERSION) { /* parse the header as it's version 0 6P packet */
LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid version [%u]\n", pkt->version = buf[0] & 0x0f;
buf[0] & 0x0f);
return -1;
}
memset(pkt, 0, sizeof(sixp_pkt_t));
pkt->type = (buf[0] & 0x30) >> 4; pkt->type = (buf[0] & 0x30) >> 4;
pkt->code.value = buf[1]; pkt->code.value = buf[1];
pkt->sfid = buf[2]; pkt->sfid = buf[2];
pkt->seqno = buf[3] & 0x0f; pkt->seqno = buf[3];
pkt->gen = (buf[3] & 0xf0) >> 4;
buf += 4; buf += 4;
len -= 4; len -= 4;
@ -935,6 +1014,12 @@ sixp_pkt_parse(const uint8_t *buf, uint16_t len,
return -1; return -1;
} }
break; break;
case SIXP_PKT_CMD_SIGNAL:
if(len < sizeof(sixp_pkt_metadata_t)) {
LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
return -1;
}
break;
case SIXP_PKT_CMD_CLEAR: case SIXP_PKT_CMD_CLEAR:
if(len != sizeof(sixp_pkt_metadata_t)) { if(len != sizeof(sixp_pkt_metadata_t)) {
LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid length\n"); LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
@ -954,13 +1039,9 @@ sixp_pkt_parse(const uint8_t *buf, uint16_t len,
* - Res to CLEAR: Empty (length 0) * - Res to CLEAR: Empty (length 0)
* - Res to STATUS: "Num. Cells" (total_num_cells) * - Res to STATUS: "Num. Cells" (total_num_cells)
* - Res to ADD, DELETE, LIST: 0, 1, or multiple 6P cells * - Res to ADD, DELETE, LIST: 0, 1, or multiple 6P cells
* - Res to SIGNAL: Payload (arbitrary length)
*/ */
if(len != 0 && /* we accept any length because of SIGNAL */
len != sizeof(sixp_pkt_total_num_cells_t) &&
(len % sizeof(uint32_t)) != 0) {
LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
return -1;
}
break; break;
case SIXP_PKT_RC_EOL: case SIXP_PKT_RC_EOL:
if((len % sizeof(uint32_t)) != 0) { if((len % sizeof(uint32_t)) != 0) {
@ -968,14 +1049,14 @@ sixp_pkt_parse(const uint8_t *buf, uint16_t len,
return -1; return -1;
} }
break; break;
case SIXP_PKT_RC_ERROR: case SIXP_PKT_RC_ERR:
case SIXP_PKT_RC_RESET: case SIXP_PKT_RC_RESET:
case SIXP_PKT_RC_VERSION: case SIXP_PKT_RC_ERR_VERSION:
case SIXP_PKT_RC_SFID: case SIXP_PKT_RC_ERR_SFID:
case SIXP_PKT_RC_GEN: case SIXP_PKT_RC_ERR_SEQNUM:
case SIXP_PKT_RC_BUSY: case SIXP_PKT_RC_ERR_CELLLIST:
case SIXP_PKT_RC_NORES: case SIXP_PKT_RC_ERR_BUSY:
case SIXP_PKT_RC_CELLLIST: case SIXP_PKT_RC_ERR_LOCKED:
if(len != 0) { if(len != 0) {
LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid length\n"); LOG_ERR("6P-pkt: sixp_pkt_parse() fails because of invalid length\n");
return -1; return -1;
@ -998,7 +1079,7 @@ sixp_pkt_parse(const uint8_t *buf, uint16_t len,
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int int
sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code, sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code,
uint8_t sfid, uint8_t seqno, uint8_t gen, uint8_t sfid, uint8_t seqno,
const uint8_t *body, uint16_t body_len, sixp_pkt_t *pkt) const uint8_t *body, uint16_t body_len, sixp_pkt_t *pkt)
{ {
uint8_t *hdr; uint8_t *hdr;
@ -1029,7 +1110,7 @@ sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code,
hdr[0] = (type << 4) | SIXP_PKT_VERSION; hdr[0] = (type << 4) | SIXP_PKT_VERSION;
hdr[1] = code.value; hdr[1] = code.value;
hdr[2] = sfid; hdr[2] = sfid;
hdr[3] = (gen << 4) | seqno; hdr[3] = seqno;
/* data: write body */ /* data: write body */
if(body_len > 0 && body != NULL) { if(body_len > 0 && body != NULL) {
@ -1043,7 +1124,6 @@ sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code,
pkt->code = code; pkt->code = code;
pkt->sfid = sfid; pkt->sfid = sfid;
pkt->seqno = seqno; pkt->seqno = seqno;
pkt->gen = gen;
pkt->body = body; pkt->body = body;
pkt->body_len = body_len; pkt->body_len = body_len;
} }

View File

@ -46,6 +46,7 @@
#define SIXP_PKT_VERSION 0x00 #define SIXP_PKT_VERSION 0x00
/* typedefs for code readability */ /* typedefs for code readability */
typedef uint8_t sixp_pkt_version_t;
typedef uint8_t sixp_pkt_cell_options_t; typedef uint8_t sixp_pkt_cell_options_t;
typedef uint8_t sixp_pkt_num_cells_t; typedef uint8_t sixp_pkt_num_cells_t;
typedef uint8_t sixp_pkt_reserved_t; typedef uint8_t sixp_pkt_reserved_t;
@ -74,7 +75,8 @@ typedef enum {
SIXP_PKT_CMD_RELOCATE = 0x03, /**< CMD_STATUS */ SIXP_PKT_CMD_RELOCATE = 0x03, /**< CMD_STATUS */
SIXP_PKT_CMD_COUNT = 0x04, /**< CMD_STATUS */ SIXP_PKT_CMD_COUNT = 0x04, /**< CMD_STATUS */
SIXP_PKT_CMD_LIST = 0x05, /**< CMD_LIST */ SIXP_PKT_CMD_LIST = 0x05, /**< CMD_LIST */
SIXP_PKT_CMD_CLEAR = 0x06, /**< CMD_CLEAR */ SIXP_PKT_CMD_SIGNAL = 0x06, /**< CMD_SIGNAL */
SIXP_PKT_CMD_CLEAR = 0x07, /**< CMD_CLEAR */
SIXP_PKT_CMD_UNAVAILABLE = 0xff, /**< for internal use */ SIXP_PKT_CMD_UNAVAILABLE = 0xff, /**< for internal use */
} sixp_pkt_cmd_t; } sixp_pkt_cmd_t;
@ -82,16 +84,17 @@ typedef enum {
* \brief 6P Return Codes * \brief 6P Return Codes
*/ */
typedef enum { typedef enum {
SIXP_PKT_RC_SUCCESS = 0x00, /**< RC_SUCCESS */ SIXP_PKT_RC_SUCCESS = 0x00, /**< RC_SUCCESS */
SIXP_PKT_RC_ERROR = 0x01, /**< RC_ERROR */ SIXP_PKT_RC_EOL = 0x01, /**< RC_EOL */
SIXP_PKT_RC_EOL = 0x02, /**< RC_EOL */ SIXP_PKT_RC_ERR = 0x02, /**< RC_ERR */
SIXP_PKT_RC_RESET = 0x03, /**< RC_RESET */ SIXP_PKT_RC_RESET = 0x03, /**< RC_RESET */
SIXP_PKT_RC_VERSION = 0x04, /**< RC_ERR_VER */ SIXP_PKT_RC_ERR_VERSION = 0x04, /**< RC_ERR_VERSION */
SIXP_PKT_RC_SFID = 0x05, /**< RC_ERR_SFID */ SIXP_PKT_RC_ERR_SFID = 0x05, /**< RC_ERR_SFID */
SIXP_PKT_RC_GEN = 0x06, /**< RC_ERR_GEN */ SIXP_PKT_RC_ERR_SEQNUM = 0x06, /**< RC_ERR_SEQNUM */
SIXP_PKT_RC_BUSY = 0x07, /**< RC_ERR_BUSY */ SIXP_PKT_RC_ERR_CELLLIST = 0x07, /**< RC_ERR_CELLLIST */
SIXP_PKT_RC_NORES = 0x08, /**< RC_ERR_NORES */ SIXP_PKT_RC_ERR_BUSY = 0x08, /**< RC_ERR_BUSY */
SIXP_PKT_RC_CELLLIST = 0x09, /**< RC_ERR_CELLLIST */ SIXP_PKT_RC_ERR_LOCKED = 0x09, /**< RC_ERR_LOCKED */
} sixp_pkt_rc_t; } sixp_pkt_rc_t;
/** /**
@ -116,13 +119,13 @@ typedef enum {
* \brief 6top IE Structure * \brief 6top IE Structure
*/ */
typedef struct { typedef struct {
sixp_pkt_type_t type; /**< Type */ sixp_pkt_version_t version; /**< Version */
sixp_pkt_code_t code; /**< Code */ sixp_pkt_type_t type; /**< Type */
uint8_t sfid; /**< SFID */ sixp_pkt_code_t code; /**< Code */
uint8_t seqno; /**< SeqNum */ uint8_t sfid; /**< SFID */
uint8_t gen; /**< GEN */ uint8_t seqno; /**< SeqNum */
const uint8_t *body; /**< Other Fields... */ const uint8_t *body; /**< Other Fields... */
uint16_t body_len; /**< The length of Other Fields */ uint16_t body_len; /**< The length of Other Fields */
} sixp_pkt_t; } sixp_pkt_t;
/** /**
@ -413,6 +416,34 @@ 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, sixp_pkt_total_num_cells_t *total_num_cells,
const uint8_t *body, uint16_t body_len); const uint8_t *body, uint16_t body_len);
/**
* \brief Write Payload in "Other Fields" of 6P packet
* \param type 6P Message Type
* \param code 6P Command Identifier or Return Code
* \param payload "Payload" to write
* \param payload_len The length of "Payload" 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_payload(sixp_pkt_type_t type, sixp_pkt_code_t code,
const uint8_t *payload, uint16_t payload_len,
uint8_t *body, uint16_t body_len);
/**
* \brief Read Payload in "Other Fields" of 6P packet
* \param type 6P Message Type
* \param code 6P Command Identifier or Return Code
* \param buf The pointer to buffer to store "Payload" in
* \param buf_len The length of buf
* \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_payload(sixp_pkt_type_t type, sixp_pkt_code_t code,
uint8_t *buf, uint16_t buf_len,
const uint8_t *body, uint16_t body_len);
/** /**
* \brief Parse a 6P packet * \brief Parse a 6P packet
* \param buf The pointer to a buffer pointing 6top IE Content * \param buf The pointer to a buffer pointing 6top IE Content
@ -429,7 +460,6 @@ int sixp_pkt_parse(const uint8_t *buf, uint16_t len,
* \param code 6P Message Code, Command Identifier or Return Code * \param code 6P Message Code, Command Identifier or Return Code
* \param sfid Scheduling Function Identifier * \param sfid Scheduling Function Identifier
* \param seqno Sequence Number * \param seqno Sequence Number
* \param gen GEN
* \param body The pointer to "Other Fields" in a buffer * \param body The pointer to "Other Fields" in a buffer
* \param body_len The length of body, typically "Other Fields" length * \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 * \param pkt The pointer to a sixp_pkt_t structure to store packet info
@ -437,7 +467,7 @@ int sixp_pkt_parse(const uint8_t *buf, uint16_t len,
* \return 0 on success, -1 on failure * \return 0 on success, -1 on failure
*/ */
int sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code, int sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code,
uint8_t sfid, uint8_t seqno, uint8_t gen, uint8_t sfid, uint8_t seqno,
const uint8_t *body, uint16_t body_len, const uint8_t *body, uint16_t body_len,
sixp_pkt_t *pkt); sixp_pkt_t *pkt);

View File

@ -43,6 +43,7 @@
#include "sixtop.h" #include "sixtop.h"
#include "sixtop-conf.h" #include "sixtop-conf.h"
#include "sixp-nbr.h"
#include "sixp-trans.h" #include "sixp-trans.h"
/* Log configuration */ /* Log configuration */
@ -204,6 +205,8 @@ determine_trans_mode(const sixp_pkt_t *req)
int int
sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state) sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state)
{ {
sixp_nbr_t *nbr;
assert(trans != NULL); assert(trans != NULL);
if(trans == NULL) { if(trans == NULL) {
LOG_ERR("6top: invalid argument, trans is NULL\n"); LOG_ERR("6top: invalid argument, trans is NULL\n");
@ -228,6 +231,34 @@ sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state)
trans->mode == SIXP_TRANS_MODE_3_STEP)) { trans->mode == SIXP_TRANS_MODE_3_STEP)) {
LOG_INFO("6P-trans: trans %p state changes from %u to %u\n", LOG_INFO("6P-trans: trans %p state changes from %u to %u\n",
trans, trans->state, new_state); trans, trans->state, new_state);
if(new_state == SIXP_TRANS_STATE_REQUEST_SENT) {
/*
* that is, the request is acknowledged by the peer; increment
* next_seqno
*/
if((nbr = sixp_nbr_find(&trans->peer_addr)) == NULL) {
LOG_ERR("6top: cannot increment next_seqno\n");
} else {
if(trans->cmd == SIXP_PKT_CMD_CLEAR) {
/* next_seqno must have been reset to 0 already. */
assert(sixp_nbr_get_next_seqno(nbr) == 0);
} else {
sixp_nbr_increment_next_seqno(nbr);
}
}
} else if(new_state == SIXP_TRANS_STATE_RESPONSE_SENT) {
if((nbr = sixp_nbr_find(&trans->peer_addr)) == NULL) {
LOG_ERR("6top: cannot update next_seqno\n");
} else {
/* override next_seqno with the received one unless it's zero */
if(trans->seqno != 0) {
sixp_nbr_set_next_seqno(nbr, trans->seqno);
}
sixp_nbr_increment_next_seqno(nbr);
}
}
trans->state = new_state; trans->state = new_state;
schedule_trans_process(trans); schedule_trans_process(trans);
return 0; return 0;

View File

@ -122,7 +122,7 @@ send_back_error(sixp_pkt_type_t type, sixp_pkt_code_t code,
const linkaddr_t *dest_addr) const linkaddr_t *dest_addr)
{ {
/* create a 6P packet within packetbuf */ /* create a 6P packet within packetbuf */
if(sixp_pkt_create(type, code, sfid, seqno, 0, NULL, 0, NULL) < 0) { if(sixp_pkt_create(type, code, sfid, seqno, NULL, 0, NULL) < 0) {
LOG_ERR("6P: failed to create a 6P packet to return an error [rc:%u]\n", LOG_ERR("6P: failed to create a 6P packet to return an error [rc:%u]\n",
code.value); code.value);
return -1; return -1;
@ -136,12 +136,10 @@ void
sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr) sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
{ {
sixp_pkt_t pkt; sixp_pkt_t pkt;
sixp_nbr_t *nbr;
uint8_t invalid_schedule_generation;
sixp_trans_t *trans; sixp_trans_t *trans;
sixp_nbr_t *nbr;
const sixtop_sf_t *sf; const sixtop_sf_t *sf;
int16_t seqno; int16_t seqno;
int16_t gen;
int ret; int ret;
assert(buf != NULL && src_addr != NULL); assert(buf != NULL && src_addr != NULL);
@ -150,7 +148,17 @@ sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
} }
if(sixp_pkt_parse(buf, len, &pkt) < 0) { if(sixp_pkt_parse(buf, len, &pkt) < 0) {
LOG_ERR("6P: sixp_input() fails because off a malformed 6P packet\n"); if(pkt.version != SIXP_PKT_VERSION) {
LOG_ERR("6P: sixp_input() unsupported version %u\n", pkt.version);
if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_VERSION,
pkt.sfid, pkt.seqno,
src_addr) < 0) {
LOG_ERR("6P: sixp_input() fails to send RC_ERR_VERSION\n");
return;
}
}
LOG_ERR("6P: sixp_input() fails because of a malformed 6P packet\n");
return; return;
} }
@ -170,43 +178,13 @@ sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
* sent back? * sent back?
*/ */
if(send_back_error(SIXP_PKT_TYPE_RESPONSE, if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_SFID, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_SFID,
pkt.sfid, pkt.seqno, src_addr) < 0) { pkt.sfid, pkt.seqno, src_addr) < 0) {
LOG_ERR("6P: sixp_input() fails to return an error response\n"); LOG_ERR("6P: sixp_input() fails to return an error response\n");
}; };
return; 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.gen == 0) {
invalid_schedule_generation = 0; /* valid combination */
} else {
LOG_ERR("6P: GEN should be 0 because of no corresponding nbr\n");
invalid_schedule_generation = 1;
}
} else {
if((gen = sixp_nbr_get_gen(nbr)) < 0) {
LOG_ERR("6P: unexpected error; cannot get our GEN\n");
return;
}
LOG_INFO("6P: received GEN %u, our GEN: %u\n",
pkt.gen, sixp_nbr_get_gen(nbr));
if(pkt.gen == gen) {
invalid_schedule_generation = 0; /* valid combination */
} else {
invalid_schedule_generation = 1;
}
}
if(invalid_schedule_generation) {
LOG_ERR("6P: sixp_input() fails because of schedule generation mismatch\n");
return;
}
/* Transaction Management */ /* Transaction Management */
trans = sixp_trans_find(src_addr); trans = sixp_trans_find(src_addr);
@ -217,20 +195,51 @@ sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
LOG_ERR_LLADDR((const linkaddr_t *)src_addr); LOG_ERR_LLADDR((const linkaddr_t *)src_addr);
LOG_ERR_(" seqno:%u] is in process\n", sixp_trans_get_seqno(trans)); LOG_ERR_(" seqno:%u] is in process\n", sixp_trans_get_seqno(trans));
if(send_back_error(SIXP_PKT_TYPE_RESPONSE, if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_BUSY, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_BUSY,
pkt.sfid, pkt.seqno, src_addr) < 0) { pkt.sfid, pkt.seqno, src_addr) < 0) {
LOG_ERR("6P: sixp_input() fails to return an error response"); LOG_ERR("6P: sixp_input() fails to return an error response");
} }
return; return;
} else if((trans = sixp_trans_alloc(&pkt, src_addr)) == NULL) { }
if((pkt.code.cmd == SIXP_PKT_CMD_CLEAR) &&
(nbr = sixp_nbr_find(src_addr)) != NULL) {
LOG_INFO("6P: sixp_input() reset nbr's next_seqno by CLEAR Request\n");
sixp_nbr_reset_next_seqno(nbr);
}
if((trans = sixp_trans_alloc(&pkt, src_addr)) == NULL) {
LOG_ERR("6P: sixp_input() fails because of lack of memory\n"); LOG_ERR("6P: sixp_input() fails because of lack of memory\n");
if(send_back_error(SIXP_PKT_TYPE_RESPONSE, if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_NORES, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_BUSY,
pkt.sfid, pkt.seqno, src_addr) < 0) { pkt.sfid, pkt.seqno, src_addr) < 0) {
LOG_ERR("6P: sixp_input() fails to return an error response\n"); LOG_ERR("6P: sixp_input() fails to return an error response\n");
} }
return; return;
} }
/* Inconsistency Management */
if(pkt.code.cmd != SIXP_PKT_CMD_CLEAR &&
(((nbr = sixp_nbr_find(src_addr)) == NULL &&
(pkt.seqno != 0)) ||
((nbr != NULL) &&
(sixp_nbr_get_next_seqno(nbr) != 0) &&
pkt.seqno == 0))) {
if(trans != NULL) {
sixp_trans_transit_state(trans,
SIXP_TRANS_STATE_REQUEST_RECEIVED);
}
if(send_back_error(SIXP_PKT_TYPE_RESPONSE,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_RC_ERR_SEQNUM,
pkt.sfid,
nbr == NULL ? 0 : sixp_nbr_get_next_seqno(nbr),
src_addr) < 0) {
LOG_ERR("6P: sixp_input() fails to return an error response\n");
}
return;
}
} else if(pkt.type == SIXP_PKT_TYPE_RESPONSE || } else if(pkt.type == SIXP_PKT_TYPE_RESPONSE ||
pkt.type == SIXP_PKT_TYPE_CONFIRMATION) { pkt.type == SIXP_PKT_TYPE_CONFIRMATION) {
if(trans == NULL) { if(trans == NULL) {
@ -290,7 +299,7 @@ sixp_output(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid,
sixp_trans_t *trans; sixp_trans_t *trans;
sixp_nbr_t *nbr; sixp_nbr_t *nbr;
sixp_pkt_cmd_t cmd; sixp_pkt_cmd_t cmd;
int16_t seqno, gen; int16_t seqno;
sixp_pkt_t pkt; sixp_pkt_t pkt;
assert(dest_addr != NULL); assert(dest_addr != NULL);
@ -324,7 +333,7 @@ sixp_output(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid,
if(trans == NULL) { if(trans == NULL) {
LOG_ERR("6P: sixp_output() fails because of no transaction [peer_addr:"); LOG_ERR("6P: sixp_output() fails because of no transaction [peer_addr:");
LOG_ERR_LLADDR((const linkaddr_t *)dest_addr); LOG_ERR_LLADDR((const linkaddr_t *)dest_addr);
LOG_ERR_("\n"); LOG_ERR_("]\n");
return -1; return -1;
} else if(sixp_trans_get_state(trans) != } else if(sixp_trans_get_state(trans) !=
SIXP_TRANS_STATE_RESPONSE_RECEIVED) { SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
@ -365,9 +374,9 @@ sixp_output(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid,
LOG_ERR("6P: sixp_output() fails to get the next sequence number\n"); LOG_ERR("6P: sixp_output() fails to get the next sequence number\n");
return -1; return -1;
} }
if(sixp_nbr_increment_next_seqno(nbr) < 0) { if(code.cmd == SIXP_PKT_CMD_CLEAR) {
LOG_ERR("6P: sixp_output() fails to increment the next sequence number\n"); LOG_INFO("6P: sixp_output() reset nbr's next_seqno by CLEAR Request\n");
return -1; sixp_nbr_reset_next_seqno(nbr);
} }
} else { } else {
assert(trans != NULL); assert(trans != NULL);
@ -377,17 +386,9 @@ sixp_output(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid,
} }
} }
/* set GEN */
if(nbr == NULL) {
gen = 0;
} else if((gen = sixp_nbr_get_gen(nbr)) < 0) {
LOG_ERR("6P: sixp_output() fails to get GEN\n");
return -1;
}
/* create a 6P packet within packetbuf */ /* create a 6P packet within packetbuf */
if(sixp_pkt_create(type, code, sfid, if(sixp_pkt_create(type, code, sfid,
(uint8_t)seqno, (uint8_t)gen, (uint8_t)seqno,
body, body_len, body, body_len,
type == SIXP_PKT_TYPE_REQUEST ? &pkt : NULL) < 0) { type == SIXP_PKT_TYPE_REQUEST ? &pkt : NULL) < 0) {
LOG_ERR("6P: sixp_output() fails to create a 6P packet\n"); LOG_ERR("6P: sixp_output() fails to create a 6P packet\n");

View File

@ -103,51 +103,6 @@ UNIT_TEST(test_alloc_and_free)
UNIT_TEST_END(); UNIT_TEST_END();
} }
UNIT_TEST_REGISTER(test_gen_management,
"test GEN Management");
UNIT_TEST(test_gen_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_gen(nbr) == 0x00);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x01);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x02);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x03);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x04);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x05);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x06);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x07);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x08);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x09);
UNIT_TEST_ASSERT(sixp_nbr_advance_gen(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_gen(nbr) == 0x01);
UNIT_TEST_END();
}
UNIT_TEST_REGISTER(test_next_seqno, UNIT_TEST_REGISTER(test_next_seqno,
"test next_seqno operation"); "test next_seqno operation");
UNIT_TEST(test_next_seqno) UNIT_TEST(test_next_seqno)
@ -189,7 +144,16 @@ UNIT_TEST(test_next_seqno)
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 14); 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_increment_next_seqno(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 15); UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 15);
UNIT_TEST_ASSERT(sixp_nbr_set_next_seqno(nbr, 255) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 255);
/* next_seqno must be 1 after 255. */
UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0); UNIT_TEST_ASSERT(sixp_nbr_increment_next_seqno(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 1);
/* next_seqno is reset to 0 by sixp_nbr_reset_next_seqno() */
UNIT_TEST_ASSERT(sixp_nbr_reset_next_seqno(nbr) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0); UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0);
UNIT_TEST_END(); UNIT_TEST_END();
@ -205,9 +169,6 @@ PROCESS_THREAD(test_process, ev, data)
/* alloc / free */ /* alloc / free */
UNIT_TEST_RUN(test_alloc_and_free); UNIT_TEST_RUN(test_alloc_and_free);
/* GEN */
UNIT_TEST_RUN(test_gen_management);
/* next sequence number */ /* next sequence number */
UNIT_TEST_RUN(test_next_seqno); UNIT_TEST_RUN(test_next_seqno);

File diff suppressed because it is too large Load Diff

View File

@ -35,8 +35,10 @@
#include "contiki-lib.h" #include "contiki-lib.h"
#include "lib/assert.h" #include "lib/assert.h"
#include "net/packetbuf.h"
#include "net/mac/tsch/tsch.h" #include "net/mac/tsch/tsch.h"
#include "net/mac/tsch/sixtop/sixtop.h" #include "net/mac/tsch/sixtop/sixtop.h"
#include "net/mac/tsch/sixtop/sixp-nbr.h"
#include "net/mac/tsch/sixtop/sixp-trans.h" #include "net/mac/tsch/sixtop/sixp-trans.h"
#include "unit-test/unit-test.h" #include "unit-test/unit-test.h"
@ -1075,6 +1077,84 @@ UNIT_TEST(test_state_transition_invalid_transition_responder)
UNIT_TEST_END(); UNIT_TEST_END();
} }
UNIT_TEST_REGISTER(test_next_seqno_increment_on_request_sent,
"test next_seqno is incremented on request_sent");
UNIT_TEST(test_next_seqno_increment_on_request_sent)
{
linkaddr_t peer_addr;
sixp_nbr_t *nbr;
sixp_trans_t *trans;
UNIT_TEST_BEGIN();
test_setup();
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_nbr_set_next_seqno(nbr, 10) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 10);
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, NULL, 0, &peer_addr,
NULL, NULL, 0) == 0);
/* next_seqno must not be changed by sixp_output() */
UNIT_TEST_ASSERT((trans = sixp_trans_find(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 10);
UNIT_TEST_ASSERT(sixp_trans_transit_state(trans,
SIXP_TRANS_STATE_REQUEST_SENT)
== 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 11);
UNIT_TEST_END();
}
UNIT_TEST_REGISTER(test_next_seqno_increment_on_response_sent,
"test next_seqno is incremented on response_sent");
UNIT_TEST(test_next_seqno_increment_on_response_sent)
{
linkaddr_t peer_addr;
sixp_nbr_t *nbr;
sixp_trans_t *trans;
uint32_t body;
UNIT_TEST_BEGIN();
test_setup();
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_nbr_set_next_seqno(nbr, 100) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 100);
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), NULL)
== 0);
UNIT_TEST_ASSERT((trans = sixp_trans_find(&peer_addr)) == NULL);
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
UNIT_TEST_ASSERT((trans = sixp_trans_find(&peer_addr)) != NULL);
/* next_seqno must not be changed yet */
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 100);
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(sixp_trans_transit_state(trans,
SIXP_TRANS_STATE_RESPONSE_SENT)
== 0);
/*
* next_seqno is overridden by the seqno of the request and
* incremented by 1
*/
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 11);
UNIT_TEST_END();
}
PROCESS_THREAD(test_process, ev, data) PROCESS_THREAD(test_process, ev, data)
{ {
static struct etimer et; static struct etimer et;
@ -1116,6 +1196,10 @@ PROCESS_THREAD(test_process, ev, data)
UNIT_TEST_RUN(test_state_transition_invalid_transition_initiator); UNIT_TEST_RUN(test_state_transition_invalid_transition_initiator);
UNIT_TEST_RUN(test_state_transition_invalid_transition_responder); UNIT_TEST_RUN(test_state_transition_invalid_transition_responder);
/* seqno management*/
UNIT_TEST_RUN(test_next_seqno_increment_on_request_sent);
UNIT_TEST_RUN(test_next_seqno_increment_on_response_sent);
printf("=check-me= DONE\n"); printf("=check-me= DONE\n");
PROCESS_END(); PROCESS_END();
} }

View File

@ -93,7 +93,7 @@ UNIT_TEST(test_input_no_sf)
memset(&body, 0, sizeof(body)); memset(&body, 0, sizeof(body));
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
UNKNOWN_SF_SFID, 10, 0, UNKNOWN_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
NULL) == 0); NULL) == 0);
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0); UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
@ -152,7 +152,7 @@ UNIT_TEST(test_input_busy)
memset(&body, 0, sizeof(body)); memset(&body, 0, sizeof(body));
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
NULL) == 0); NULL) == 0);
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0); UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
@ -174,7 +174,7 @@ UNIT_TEST(test_input_busy)
/* 6top IE */ /* 6top IE */
UNIT_TEST_ASSERT(p[4] == 0xc9); UNIT_TEST_ASSERT(p[4] == 0xc9);
UNIT_TEST_ASSERT(p[5] == 0x10); UNIT_TEST_ASSERT(p[5] == 0x10);
UNIT_TEST_ASSERT(p[6] == 0x07); UNIT_TEST_ASSERT(p[6] == 0x08);
UNIT_TEST_ASSERT(p[7] == TEST_SF_SFID); UNIT_TEST_ASSERT(p[7] == TEST_SF_SFID);
UNIT_TEST_ASSERT(p[8] == 0x0a); UNIT_TEST_ASSERT(p[8] == 0x0a);
@ -201,9 +201,9 @@ UNIT_TEST(test_input_no_memory)
memset(&body, 0, sizeof(body)); memset(&body, 0, sizeof(body));
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.u8[0] = 1; addr.u8[0] = 1;
UNIT_TEST_ASSERT(sixp_trans_alloc(&pkt, &addr) != NULL); UNIT_TEST_ASSERT(sixp_trans_alloc(&pkt, &addr) != NULL);
@ -244,41 +244,6 @@ UNIT_TEST(test_input_no_memory)
UNIT_TEST_END(); 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 GEN 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,
(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_gen(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, UNIT_TEST_REGISTER(test_output_request_1,
"sixp_output(request_1)"); "sixp_output(request_1)");
UNIT_TEST(test_output_request_1) UNIT_TEST(test_output_request_1)
@ -294,7 +259,7 @@ UNIT_TEST(test_output_request_1)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
@ -360,7 +325,7 @@ UNIT_TEST(test_output_response_2)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
@ -388,12 +353,12 @@ UNIT_TEST(test_output_response_3)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
UNIT_TEST_ASSERT( UNIT_TEST_ASSERT(
sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_RECEIVED) == 0); sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_RECEIVED) == 0);
UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0); UNIT_TEST_ASSERT(test_mac_send_function_is_called() == 0);
UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_RESPONSE, UNIT_TEST_ASSERT(sixp_output(SIXP_PKT_TYPE_RESPONSE,
@ -418,7 +383,7 @@ UNIT_TEST(test_output_response_4)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
@ -467,7 +432,7 @@ UNIT_TEST(test_output_confirmation_2)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
@ -495,7 +460,7 @@ UNIT_TEST(test_output_confirmation_3)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
@ -527,7 +492,7 @@ UNIT_TEST(test_output_confirmation_4)
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST, UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD, (sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10, 0, TEST_SF_SFID, 10,
(const uint8_t *)&body, sizeof(body), (const uint8_t *)&body, sizeof(body),
&pkt) == 0); &pkt) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL); UNIT_TEST_ASSERT((trans = sixp_trans_alloc(&pkt, &peer_addr)) != NULL);
@ -549,6 +514,206 @@ UNIT_TEST(test_output_confirmation_4)
UNIT_TEST_END(); UNIT_TEST_END();
} }
UNIT_TEST_REGISTER(test_next_seqno_reset_by_clear_request_1,
"test if next_seqno is reset by sending CLEAR");
UNIT_TEST(test_next_seqno_reset_by_clear_request_1)
{
linkaddr_t peer_addr;
sixp_nbr_t *nbr;
sixp_trans_t *trans;
UNIT_TEST_BEGIN();
test_setup();
/*
* When the node is the initiator of CLEAR, nbr->next_seqno must be
* reset to 0 regardless of the presence or absent of L2 ACK to the
* CLEAR Request.
*/
/* set next_seqno to 3 as the initial state for this sub-test */
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_nbr_set_next_seqno(nbr, 3) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 3);
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(sixp_nbr_get_next_seqno(nbr) == 0);
UNIT_TEST_ASSERT((trans = sixp_trans_find(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_trans_transit_state(trans,
SIXP_TRANS_STATE_REQUEST_SENT)
== 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0);
UNIT_TEST_ASSERT(sixp_trans_transit_state(trans,
SIXP_TRANS_STATE_TERMINATING)
== 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0);
UNIT_TEST_END();
}
UNIT_TEST_REGISTER(test_next_seqno_reset_by_clear_request_2,
"test if next_seqno is reset by receiving CLEAR");
UNIT_TEST(test_next_seqno_reset_by_clear_request_2)
{
linkaddr_t peer_addr;
sixp_nbr_t *nbr;
sixp_pkt_metadata_t metadata;
UNIT_TEST_BEGIN();
test_setup();
/*
* When the node is the responder of CLEAR, nbr->next_seqno must be
* reset to 0 regardless of the presence or absent of L2 ACK to the
* CLEAR Response.
*/
/* set next_seqno to 3 as the initial state for this sub-test */
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_nbr_set_next_seqno(nbr, 3) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 3);
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_CLEAR,
TEST_SF_SFID, 10,
(const uint8_t *)&metadata,
sizeof(metadata), NULL) == 0);
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 0);
UNIT_TEST_END();
}
UNIT_TEST_REGISTER(test_detect_seqno_error_1,
"test if seqno error is handled correctly (1)");
UNIT_TEST(test_detect_seqno_error_1)
{
linkaddr_t peer_addr;
uint32_t body;
uint8_t *p;
UNIT_TEST_BEGIN();
test_setup();
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 10,
(const uint8_t *)&body,
sizeof(body), NULL) == 0);
/* return RC_ERR_RSEQNUM on receiving non-zero seqno when nbr doesn't exist */
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
/*
* 2 octets for Termination 1 IE, one octet for 6top Sub-IE ID, and
* 2 octets for Payload IE Header.
*/
p = packetbuf_hdrptr() + 5;
/* now, p pointes to the 6P header */
UNIT_TEST_ASSERT(packetbuf_totlen() == 11);
UNIT_TEST_ASSERT(p[0] == ((SIXP_PKT_TYPE_RESPONSE << 4) | SIXP_PKT_VERSION));
UNIT_TEST_ASSERT(p[1] == SIXP_PKT_RC_ERR_SEQNUM);
UNIT_TEST_ASSERT(p[2] == TEST_SF_SFID);
UNIT_TEST_ASSERT(p[3] == 0); /* we don't have a relevant nbr; 0 is returned */
UNIT_TEST_END();
}
UNIT_TEST_REGISTER(test_detect_seqno_error_2,
"test if seqno error is handled correctly (2)");
UNIT_TEST(test_detect_seqno_error_2)
{
sixp_nbr_t *nbr;
sixp_trans_t *trans;
linkaddr_t peer_addr;
uint32_t body;
uint8_t *p;
UNIT_TEST_BEGIN();
test_setup();
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT((nbr = sixp_nbr_alloc(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_nbr_set_next_seqno(nbr, 3) == 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 3);
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_ADD,
TEST_SF_SFID, 0,
(const uint8_t *)&body,
sizeof(body), NULL) == 0);
/* return RC_ERR_RSEQNUM on receiving zero when nbr->seqno is non-zero */
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
/*
* 2 octets for Termination 1 IE, one octet for 6top Sub-IE ID, and
* 2 octets for Payload IE Header.
*/
p = packetbuf_hdrptr() + 5;
/* now, p pointes to the 6P header */
UNIT_TEST_ASSERT(packetbuf_totlen() == 11);
UNIT_TEST_ASSERT(p[0] == ((SIXP_PKT_TYPE_RESPONSE << 4) | SIXP_PKT_VERSION));
UNIT_TEST_ASSERT(p[1] == SIXP_PKT_RC_ERR_SEQNUM);
UNIT_TEST_ASSERT(p[2] == TEST_SF_SFID);
UNIT_TEST_ASSERT(p[3] == 3);
UNIT_TEST_ASSERT((trans = sixp_trans_find(&peer_addr)) != NULL);
UNIT_TEST_ASSERT(sixp_trans_transit_state(trans,
SIXP_TRANS_STATE_RESPONSE_SENT)
== 0);
UNIT_TEST_ASSERT(sixp_nbr_get_next_seqno(nbr) == 4);
UNIT_TEST_END();
}
UNIT_TEST_REGISTER(test_invalid_version,
"test invalid version");
UNIT_TEST(test_invalid_version)
{
linkaddr_t peer_addr;
uint8_t *p;
sixp_pkt_t pkt;
UNIT_TEST_BEGIN();
test_setup();
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.u8[0] = 1;
UNIT_TEST_ASSERT(sixp_pkt_create(SIXP_PKT_TYPE_REQUEST,
(sixp_pkt_code_t)(uint8_t)SIXP_PKT_CMD_CLEAR,
TEST_SF_SFID, 0,
NULL, 0, NULL) == 0);
p = packetbuf_hdrptr();
p[0] |= 10; /* set version 10 which we doesn't support */
/* this 6P packet shouldn't be parsed */
UNIT_TEST_ASSERT(sixp_pkt_parse(packetbuf_hdrptr(), packetbuf_totlen(),
&pkt) == -1);
/* return RC_ERR_VERSION on receiving zero when nbr->seqno is non-zero */
sixp_input(packetbuf_hdrptr(), packetbuf_totlen(), &peer_addr);
/*
* 2 octets for Termination 1 IE, one octet for 6top Sub-IE ID, and
* 2 octets for Payload IE Header.
*/
p = packetbuf_hdrptr() + 5;
/* now, p pointes to the 6P header */
UNIT_TEST_ASSERT(packetbuf_totlen() == 11);
UNIT_TEST_ASSERT(p[0] == ((SIXP_PKT_TYPE_RESPONSE << 4) | SIXP_PKT_VERSION));
UNIT_TEST_ASSERT(p[1] == SIXP_PKT_RC_ERR_VERSION);
UNIT_TEST_ASSERT(p[2] == TEST_SF_SFID);
UNIT_TEST_ASSERT(p[3] == 0);
UNIT_TEST_END();
}
PROCESS_THREAD(test_process, ev, data) PROCESS_THREAD(test_process, ev, data)
{ {
static struct etimer et; static struct etimer et;
@ -571,7 +736,6 @@ PROCESS_THREAD(test_process, ev, data)
UNIT_TEST_RUN(test_input_no_sf); UNIT_TEST_RUN(test_input_no_sf);
UNIT_TEST_RUN(test_input_busy); UNIT_TEST_RUN(test_input_busy);
UNIT_TEST_RUN(test_input_no_memory); 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_1);
UNIT_TEST_RUN(test_output_request_2); UNIT_TEST_RUN(test_output_request_2);
@ -584,6 +748,14 @@ PROCESS_THREAD(test_process, ev, data)
UNIT_TEST_RUN(test_output_confirmation_3); UNIT_TEST_RUN(test_output_confirmation_3);
UNIT_TEST_RUN(test_output_confirmation_4); UNIT_TEST_RUN(test_output_confirmation_4);
/* testing for SeqNum Management */
UNIT_TEST_RUN(test_next_seqno_reset_by_clear_request_1);
UNIT_TEST_RUN(test_next_seqno_reset_by_clear_request_2);
UNIT_TEST_RUN(test_detect_seqno_error_1);
UNIT_TEST_RUN(test_detect_seqno_error_2);
UNIT_TEST_RUN(test_invalid_version);
printf("=check-me= DONE\n"); printf("=check-me= DONE\n");
PROCESS_END(); PROCESS_END();
} }