41#include "contiki-lib.h"
42#include "lib/assert.h"
51#define LOG_MODULE "6top"
52#define LOG_LEVEL LOG_LEVEL_6TOP
54static void mac_callback(
void *ptr,
int status,
int transmissions);
56 const sixp_pkt_t *pkt,
const linkaddr_t *dest_addr);
57static void handle_schedule_inconsistency(
const sixtop_sf_t *sf,
59 const linkaddr_t *peer_addr);
62mac_callback(
void *ptr,
int status,
int transmissions)
64 sixp_trans_t *trans = (sixp_trans_t *)ptr;
67 assert(trans != NULL);
69 LOG_ERR(
"6P: mac_callback() fails because trans is NULL\n");
74 if(sf != NULL && sf->
error != NULL) {
75 sf->
error(SIXP_ERROR_TX_AFTER_TRANSACTION_TERMINATION,
85 new_state = SIXP_TRANS_STATE_UNAVAILABLE;
87 switch(current_state) {
88 case SIXP_TRANS_STATE_REQUEST_SENDING:
89 new_state = SIXP_TRANS_STATE_REQUEST_SENT;
91 case SIXP_TRANS_STATE_RESPONSE_SENDING:
92 new_state = SIXP_TRANS_STATE_RESPONSE_SENT;
94 case SIXP_TRANS_STATE_CONFIRMATION_SENDING:
95 new_state = SIXP_TRANS_STATE_CONFIRMATION_SENT;
98 LOG_ERR(
"6P: mac_callback() fails because of an unexpected state (%u)\n",
101 new_state = current_state;
111 if(current_state == SIXP_TRANS_STATE_REQUEST_SENDING) {
113 new_state = SIXP_TRANS_STATE_TERMINATING;
116 new_state = current_state;
120 if(new_state != current_state &&
122 LOG_ERR(
"6P: mac_callback() fails because of state transition failure\n");
123 LOG_ERR(
"6P: something wrong; we're terminating the trans %p\n", trans);
137 const sixp_pkt_t *pkt,
const linkaddr_t *dest_addr)
142 assert(dest_addr != NULL);
152 pkt->
sfid, pkt->
seqno, NULL, 0, NULL) < 0) {
153 LOG_ERR(
"6P: failed to create a 6P packet to return an error [rc:%u]\n",
177 NULL, 0, dest_addr, NULL, NULL, 0);
179 LOG_ERR(
"6P: send an error code %u to ", rc);
180 LOG_ERR_LLADDR(dest_addr);
186handle_schedule_inconsistency(
const sixtop_sf_t *sf,
188 const linkaddr_t *peer_addr)
190 assert(recved_pkt != NULL);
191 assert(peer_addr != NULL);
194 recved_pkt, peer_addr) < 0) {
195 LOG_ERR(
"6P: sixp_input() fails to return an error response\n");
197 if(sf != NULL && sf->
error != NULL) {
198 sf->
error(SIXP_ERROR_SCHEDULE_INCONSISTENCY,
205sixp_input(
const uint8_t *buf, uint16_t len,
const linkaddr_t *src_addr)
214 assert(buf != NULL && src_addr != NULL);
215 if(buf == NULL || src_addr == NULL) {
220 if(pkt.
version != SIXP_PKT_VERSION) {
221 LOG_ERR(
"6P: sixp_input() unsupported version %u\n", pkt.
version);
224 LOG_ERR(
"6P: sixp_input() fails to send RC_ERR_VERSION\n");
227 LOG_ERR(
"6P: sixp_input() fails because of a malformed 6P packet\n");
235 LOG_ERR(
"6P: sixp_input() fails because of unsupported type [type:%u]\n",
241 LOG_ERR(
"6P: sixp_input() fails because SF [sfid:%u] is unavailable\n",
249 LOG_ERR(
"6P: sixp_input() fails to return an error response\n");
267 handle_schedule_inconsistency(sf, (
const sixp_pkt_t *)&pkt, src_addr);
271 LOG_ERR(
"6P: sixp_input() fails because another request [peer_addr:");
272 LOG_ERR_LLADDR((
const linkaddr_t *)src_addr);
285 LOG_ERR(
"6P: sixp_input() fails to return an error response");
293 LOG_INFO(
"6P: sixp_input() reset nbr's next_seqno by CLEAR Request\n");
298 LOG_ERR(
"6P: sixp_input() fails because of lack of memory\n");
301 LOG_ERR(
"6P: sixp_input() fails to return an error response\n");
315 SIXP_TRANS_STATE_REQUEST_RECEIVED);
316 handle_schedule_inconsistency(sf, (
const sixp_pkt_t *)&pkt, src_addr);
325 LOG_ERR(
"6P: sixp_input() fails because of no trans [peer_addr:");
326 LOG_ERR_LLADDR((
const linkaddr_t *)src_addr);
330 seqno != pkt.
seqno) {
331 LOG_ERR(
"6P: sixp_input() fails because of invalid seqno [seqno:%u, %u]\n",
345 assert(trans != NULL);
349 SIXP_TRANS_STATE_REQUEST_RECEIVED);
353 SIXP_TRANS_STATE_RESPONSE_RECEIVED);
357 SIXP_TRANS_STATE_CONFIRMATION_RECEIVED);
360 LOG_ERR(
"6P: sixp_input() fails because of unsupported type [type:%u]\n",
365 LOG_ERR(
"6P: sixp_input() fails because of state transition failure\n");
366 LOG_ERR(
"6P: maybe a duplicate packet to trans:%p\n", trans);
367 }
else if(sf->
input != NULL) {
377 const uint8_t *body, uint16_t body_len,
378 const linkaddr_t *dest_addr,
386 assert(dest_addr != NULL);
392 LOG_ERR(
"6P: sixp_output() fails because another trans for [peer_addr:");
393 LOG_ERR_LLADDR((
const linkaddr_t *)dest_addr);
394 LOG_ERR_(
"] is in process\n");
402 LOG_ERR(
"6P: sixp_output() fails because of no transaction [peer_addr:");
403 LOG_ERR_LLADDR((
const linkaddr_t *)dest_addr);
407 SIXP_TRANS_STATE_REQUEST_RECEIVED) {
408 LOG_ERR(
"6P: sixp_output() fails because of invalid transaction state\n");
415 LOG_ERR(
"6P: sixp_output() fails because of no transaction [peer_addr:");
416 LOG_ERR_LLADDR((
const linkaddr_t *)dest_addr);
420 SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
421 LOG_ERR(
"6P: sixp_output() fails because of invalid transaction state\n");
427 LOG_ERR(
"6P: sixp_output() fails because of unsupported type [type:%u]\n",
446 LOG_ERR(
"6P: sixp_output() fails because of no memory for another nbr\n");
454 LOG_ERR(
"6P: sixp_output() fails because it fails to allocate a nbr\n");
458 LOG_ERR(
"6P: sixp_output() fails to get the next sequence number\n");
462 assert(trans != NULL);
464 LOG_ERR(
"6P: sixp_output() fails because it fails to get seqno\n");
474 LOG_ERR(
"6P: sixp_output() fails to create a 6P packet\n");
480 assert(trans == NULL);
482 LOG_ERR(
"6P: sixp_output() is aborted because of no memory\n");
486 LOG_DBG(
"6P: sixp_output() allocates trans:%p\n", trans);
490 assert(trans != NULL);
495 if(state == SIXP_TRANS_STATE_INIT) {
506 LOG_INFO(
"6P: sixp_output() reset nbr's next_seqno by CLEAR Request\n");
512 }
else if(state == SIXP_TRANS_STATE_REQUEST_RECEIVED) {
514 }
else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
518 LOG_ERR(
"6P: sixp_output() is called trans:%p whose state is %u\n",
const linkaddr_t * sixp_trans_get_peer_addr(sixp_trans_t *trans)
Return the peer addr of a specified transaction.
const sixtop_sf_t * sixtop_find_sf(uint8_t sfid)
Find a SF which has been added by SFID.
struct sixp_nbr sixp_nbr_t
6P Neighbor Data Structure (for internal use)
void sixp_trans_abort(sixp_trans_t *trans)
Helper function to abort a transaction immediately.
int sixp_pkt_create(sixp_pkt_type_t type, sixp_pkt_code_t code, uint8_t sfid, uint8_t seqno, const uint8_t *body, uint16_t body_len, sixp_pkt_t *pkt)
Create a 6P packet.
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)
Output a 6P packet.
int sixp_pkt_parse(const uint8_t *buf, uint16_t len, sixp_pkt_t *pkt)
Parse a 6P packet.
sixp_pkt_cmd_t sixp_trans_get_cmd(sixp_trans_t *trans)
Return the command associated with a specified transaction.
void sixp_trans_invoke_callback(sixp_trans_t *trans, sixp_output_status_t status)
Invoke the output callback of a specified transaction.
sixp_trans_t * sixp_trans_find(const linkaddr_t *peer_addr)
Find a transaction.
int sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state)
Change the state of a specified transaction.
void sixp_trans_free(sixp_trans_t *trans)
Free a transaction.
int16_t sixp_trans_get_seqno(sixp_trans_t *trans)
Return the sequence number associated with a specified transaction.
sixp_trans_state_t sixp_trans_get_state(sixp_trans_t *trans)
Return the state of a specified transaction.
int sixp_nbr_init(void)
Initialize 6p Neighbor Table.
sixp_nbr_t * sixp_nbr_find(const linkaddr_t *addr)
Find a neighbor.
int sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr)
Increment the next sequence number of a neighbor.
int16_t sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
Get the next sequence number of a neighbor.
sixp_nbr_t * sixp_nbr_alloc(const linkaddr_t *addr)
Allocate a neighbor.
void sixp_init(void)
Initialize 6P Module It invokes sixp_nbr_init() and sixp_trans_init().
void sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
Input a 6P packet.
void(* sixp_sent_callback_t)(void *arg, uint16_t arg_len, const linkaddr_t *dest_addr, sixp_output_status_t status)
6P Packet Sent Handler
const sixtop_sf_t * sixp_trans_get_sf(sixp_trans_t *trans)
Return the scheduling function associated with a specified transaction.
int sixp_nbr_reset_next_seqno(sixp_nbr_t *nbr)
Reset the next sequence number of a neighbor to zero.
int sixp_trans_init(void)
Initialize Memory and List for 6P transactions This function removes and frees existing transactions.
sixp_trans_state_t
6P Transaction States (for internal use)
int sixtop_output(const linkaddr_t *dest_addr, mac_callback_t callback, void *arg)
Output a 6P packet which is supposestored in packetbuf.
sixp_pkt_rc_t
6P Return Codes
sixp_trans_t * sixp_trans_alloc(const sixp_pkt_t *pkt, const linkaddr_t *peer_addr)
Allocate a transaction.
void sixp_trans_set_callback(sixp_trans_t *trans, sixp_sent_callback_t func, void *arg, uint16_t arg_len)
Set an output callback to a specified transaction.
sixp_pkt_type_t
6P Message Types
sixp_pkt_cmd_t
6P Command Identifiers
@ SIXP_OUTPUT_STATUS_FAILURE
FAILURE.
@ SIXP_OUTPUT_STATUS_SUCCESS
SUCCESS.
@ SIXP_PKT_RC_ERR_SFID
RC_ERR_SFID.
@ SIXP_PKT_RC_ERR_SEQNUM
RC_ERR_SEQNUM.
@ SIXP_PKT_RC_ERR_BUSY
RC_ERR_BUSY.
@ SIXP_PKT_RC_ERR_VERSION
RC_ERR_VERSION.
@ SIXP_PKT_TYPE_RESPONSE
6P Response
@ SIXP_PKT_TYPE_REQUEST
6P Request
@ SIXP_PKT_TYPE_CONFIRMATION
6P Confirmation
@ SIXP_PKT_CMD_CLEAR
CMD_CLEAR.
Header file for the logging system.
@ MAC_TX_OK
The MAC layer transmission was OK.
Neighbor Management APIs for 6top Protocol (6P)
6top Protocol (6P) Packet Manipulation APIs
Transaction Management APIs for 6top Protocol (6P)
6TiSCH Operation Sublayer (6top) APIs
sixp_pkt_type_t type
Type.
sixp_pkt_code_t code
Code.
const uint8_t * body
Other Fields...
sixp_pkt_version_t version
Version.
uint16_t body_len
The length of Other Fields.
/brief Scheduling Function Driver
sixtop_sf_error error
Internal Error Handler.
sixtop_sf_input input
Input Handler.
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
6P Codes integrating Command IDs and Return Codes
sixp_pkt_cmd_t cmd
6P Command Identifier
uint8_t value
8-bit unsigned integer value