Contiki-NG
Loading...
Searching...
No Matches
sixp.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016, Yasuyuki Tanaka
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/**
31 * \addtogroup sixtop
32 * @{
33 */
34/**
35 * \file
36 * 6top Protocol (6P)
37 * \author
38 * Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
39 */
40
41#include "contiki-lib.h"
42#include "lib/assert.h"
43
44#include "sixtop.h"
45#include "sixp-nbr.h"
46#include "sixp-pkt.h"
47#include "sixp-trans.h"
48
49/* Log configuration */
50#include "sys/log.h"
51#define LOG_MODULE "6top"
52#define LOG_LEVEL LOG_LEVEL_6TOP
53
54static void mac_callback(void *ptr, int status, int transmissions);
55static int send_back_error(sixp_pkt_type_t type, sixp_pkt_rc_t rc,
56 const sixp_pkt_t *pkt, const linkaddr_t *dest_addr);
57static void handle_schedule_inconsistency(const sixtop_sf_t *sf,
58 const sixp_pkt_t *recved_pkt,
59 const linkaddr_t *peer_addr);
60/*---------------------------------------------------------------------------*/
61static void
62mac_callback(void *ptr, int status, int transmissions)
63{
64 sixp_trans_t *trans = (sixp_trans_t *)ptr;
65 sixp_trans_state_t new_state, current_state;
66
67 assert(trans != NULL);
68 if(trans == NULL) {
69 LOG_ERR("6P: mac_callback() fails because trans is NULL\n");
70 return;
71 } else if(sixp_trans_get_state(trans) == SIXP_TRANS_STATE_WAIT_FREE) {
72 /* the transaction has been invalidated; free it now */
73 const sixtop_sf_t *sf = sixp_trans_get_sf(trans);
74 if(sf != NULL && sf->error != NULL) {
75 sf->error(SIXP_ERROR_TX_AFTER_TRANSACTION_TERMINATION,
76 sixp_trans_get_cmd(trans),
79 }
80 sixp_trans_free(trans);
81 return;
82 }
83
84 current_state = sixp_trans_get_state(trans);
85 new_state = SIXP_TRANS_STATE_UNAVAILABLE;
86 if(status == MAC_TX_OK) {
87 switch(current_state) {
88 case SIXP_TRANS_STATE_REQUEST_SENDING:
89 new_state = SIXP_TRANS_STATE_REQUEST_SENT;
90 break;
91 case SIXP_TRANS_STATE_RESPONSE_SENDING:
92 new_state = SIXP_TRANS_STATE_RESPONSE_SENT;
93 break;
94 case SIXP_TRANS_STATE_CONFIRMATION_SENDING:
95 new_state = SIXP_TRANS_STATE_CONFIRMATION_SENT;
96 break;
97 default:
98 LOG_ERR("6P: mac_callback() fails because of an unexpected state (%u)\n",
99 current_state);
100 /* don't change the state */
101 new_state = current_state;
102 break;
103 }
104 } else {
105 /*
106 * In a case of transmission failure of a request, a corresponding SF would
107 * retransmit the request with a new transaction. For a response or a
108 * confirmation, the same transaction will be used for retransmission as
109 * long as it doesn't have timeout.
110 */
111 if(current_state == SIXP_TRANS_STATE_REQUEST_SENDING) {
112 /* request case */
113 new_state = SIXP_TRANS_STATE_TERMINATING;
114 } else {
115 /* response or confirmation case: stay the same state */
116 new_state = current_state;
117 }
118 }
119
120 if(new_state != current_state &&
121 sixp_trans_transit_state(trans, new_state) != 0) {
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);
124 (void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
125 return;
126 }
127
129 status == MAC_TX_OK ?
132 sixp_trans_set_callback(trans, NULL, NULL, 0);
133}
134/*---------------------------------------------------------------------------*/
135static int
136send_back_error(sixp_pkt_type_t type, sixp_pkt_rc_t rc,
137 const sixp_pkt_t *pkt, const linkaddr_t *dest_addr)
138{
139 sixp_trans_t *trans;
140
141 assert(pkt != NULL);
142 assert(dest_addr != NULL);
143
144 if((rc == SIXP_PKT_RC_ERR_VERSION) ||
145 (rc == SIXP_PKT_RC_ERR_SFID) ||
146 (rc == SIXP_PKT_RC_ERR_BUSY) ||
147 (rc == SIXP_PKT_RC_ERR_SEQNUM &&
148 (trans = sixp_trans_find(dest_addr)) != NULL &&
149 sixp_trans_get_state(trans) != SIXP_TRANS_STATE_REQUEST_RECEIVED)) {
150 /* create a 6P packet within packetbuf */
151 if(sixp_pkt_create(type, (sixp_pkt_code_t)(uint8_t)rc,
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",
154 rc);
155 return -1;
156 }
157 /*
158 * for RC_ERR_VERSION and RC_ERR_SFID, we don't care about how the
159 * transmission goes for unsupported packets; no need to set
160 * callback.
161 *
162 * for RC_ERR_BUSY, we cannot allocate another transaction. so we call
163 * sixtop_output() directly
164 *
165 * when we're going to send RC_ERR_SEQNUM to a peer to whom we
166 * have a transaction under way, we call sixtop_output() directly
167 * to prevent allocating another transaction
168 */
169 sixtop_output(dest_addr, NULL, NULL);
170 } else {
171 /*
172 * 6P creates a transaction to send an error other than listed
173 * above. we use sixp_output to make 'nbr' have a correct
174 * next_seqno.
175 */
176 sixp_output(type, (sixp_pkt_code_t)(uint8_t)rc, pkt->sfid,
177 NULL, 0, dest_addr, NULL, NULL, 0);
178 }
179 LOG_ERR("6P: send an error code %u to ", rc);
180 LOG_ERR_LLADDR(dest_addr);
181 LOG_ERR_("\n");
182 return 0;
183}
184/*---------------------------------------------------------------------------*/
185static void
186handle_schedule_inconsistency(const sixtop_sf_t *sf,
187 const sixp_pkt_t *recved_pkt,
188 const linkaddr_t *peer_addr)
189{
190 assert(recved_pkt != NULL);
191 assert(peer_addr != NULL);
192
194 recved_pkt, peer_addr) < 0) {
195 LOG_ERR("6P: sixp_input() fails to return an error response\n");
196 }
197 if(sf != NULL && sf->error != NULL) {
198 sf->error(SIXP_ERROR_SCHEDULE_INCONSISTENCY,
199 (sixp_pkt_cmd_t)recved_pkt->code.value, recved_pkt->seqno,
200 peer_addr);
201 }
202}
203/*---------------------------------------------------------------------------*/
204void
205sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
206{
207 sixp_pkt_t pkt;
208 sixp_trans_t *trans;
210 const sixtop_sf_t *sf;
211 int16_t seqno;
212 int ret;
213
214 assert(buf != NULL && src_addr != NULL);
215 if(buf == NULL || src_addr == NULL) {
216 return;
217 }
218
219 if(sixp_pkt_parse(buf, len, &pkt) < 0) {
220 if(pkt.version != SIXP_PKT_VERSION) {
221 LOG_ERR("6P: sixp_input() unsupported version %u\n", pkt.version);
223 (const sixp_pkt_t *)&pkt, src_addr) < 0) {
224 LOG_ERR("6P: sixp_input() fails to send RC_ERR_VERSION\n");
225 }
226 } else {
227 LOG_ERR("6P: sixp_input() fails because of a malformed 6P packet\n");
228 }
229 return;
230 }
231
232 if(pkt.type != SIXP_PKT_TYPE_REQUEST &&
235 LOG_ERR("6P: sixp_input() fails because of unsupported type [type:%u]\n",
236 pkt.type);
237 return;
238 }
239
240 if((sf = sixtop_find_sf(pkt.sfid)) == NULL) {
241 LOG_ERR("6P: sixp_input() fails because SF [sfid:%u] is unavailable\n",
242 pkt.sfid);
243 /*
244 * XXX: what if the incoming packet is a response? confirmation should be
245 * sent back?
246 */
248 (const sixp_pkt_t *)&pkt, src_addr) < 0) {
249 LOG_ERR("6P: sixp_input() fails to return an error response\n");
250 };
251 return;
252 }
253
254 /* Transaction Management */
255 trans = sixp_trans_find(src_addr);
256
257 if(pkt.type == SIXP_PKT_TYPE_REQUEST) {
258 if(trans != NULL) {
259 if(pkt.code.cmd != SIXP_PKT_CMD_CLEAR &&
260 ((pkt.seqno == 0 && sixp_trans_get_seqno(trans) != 0) ||
261 (pkt.seqno != 0 && sixp_trans_get_seqno(trans) == 0))) {
262 /*
263 * seems the peer had power-cycle; we're going to send back
264 * RC_ERR_SEQNUM. in this case, we don't want to allocate
265 * another transaction for this new request.
266 */
267 handle_schedule_inconsistency(sf, (const sixp_pkt_t *)&pkt, src_addr);
268 return;
269 } else {
270 /* Error: not supposed to have another transaction with the peer. */
271 LOG_ERR("6P: sixp_input() fails because another request [peer_addr:");
272 LOG_ERR_LLADDR((const linkaddr_t *)src_addr);
273 LOG_ERR_(" seqno:%u] is in process\n", sixp_trans_get_seqno(trans));
274 /*
275 * Although RFC 8480 says in Section 3.4.3 that we MUST send
276 * RC_RESET back in this case, we use RC_ERR_BUSY
277 * instead. RC_RESET requires the peer to revert SeqNum update
278 * by the corresponding transaction, which may cause
279 * unnecessary SeqNum disagreement. This also would make the
280 * implementation complex. At this moment, no benefit is seen
281 * in using RC_RESET over RC_ERR_BUSY.
282 */
284 (const sixp_pkt_t *)&pkt, src_addr) < 0) {
285 LOG_ERR("6P: sixp_input() fails to return an error response");
286 }
287 return;
288 }
289 }
290
291 if((pkt.code.cmd == SIXP_PKT_CMD_CLEAR) &&
292 (nbr = sixp_nbr_find(src_addr)) != NULL) {
293 LOG_INFO("6P: sixp_input() reset nbr's next_seqno by CLEAR Request\n");
295 }
296
297 if((trans = sixp_trans_alloc(&pkt, src_addr)) == NULL) {
298 LOG_ERR("6P: sixp_input() fails because of lack of memory\n");
300 (const sixp_pkt_t *)&pkt, src_addr) < 0) {
301 LOG_ERR("6P: sixp_input() fails to return an error response\n");
302 }
303 return;
304 }
305
306 /* Inconsistency Management */
307 if(pkt.code.cmd != SIXP_PKT_CMD_CLEAR &&
308 (((nbr = sixp_nbr_find(src_addr)) == NULL &&
309 (pkt.seqno != 0)) ||
310 ((nbr != NULL) &&
312 pkt.seqno == 0))) {
313 if(trans != NULL) {
315 SIXP_TRANS_STATE_REQUEST_RECEIVED);
316 handle_schedule_inconsistency(sf, (const sixp_pkt_t *)&pkt, src_addr);
317 }
318 return;
319 }
320
321 } else if(pkt.type == SIXP_PKT_TYPE_RESPONSE ||
323 if(trans == NULL) {
324 /* Error: should have a transaction for incoming packet */
325 LOG_ERR("6P: sixp_input() fails because of no trans [peer_addr:");
326 LOG_ERR_LLADDR((const linkaddr_t *)src_addr);
327 LOG_ERR_("]\n");
328 return;
329 } else if((seqno = sixp_trans_get_seqno(trans)) < 0 ||
330 seqno != pkt.seqno) {
331 LOG_ERR("6P: sixp_input() fails because of invalid seqno [seqno:%u, %u]\n",
332 seqno, pkt.seqno);
333 /*
334 * Figure 31 of RFC 8480 implies there is a chance to receive a
335 * 6P Response having RC_ERR_SEQNUM and SeqNum of 0. But, it
336 * shouldn't happen according to the definition of SeqNum
337 * described Section 3.2.2 of RFC 8480. We discard such a 6P
338 * Response silently without taking any action.
339 */
340 return;
341 }
342 }
343
344 /* state transition */
345 assert(trans != NULL);
346 switch(pkt.type) {
348 ret = sixp_trans_transit_state(trans,
349 SIXP_TRANS_STATE_REQUEST_RECEIVED);
350 break;
352 ret = sixp_trans_transit_state(trans,
353 SIXP_TRANS_STATE_RESPONSE_RECEIVED);
354 break;
356 ret = sixp_trans_transit_state(trans,
357 SIXP_TRANS_STATE_CONFIRMATION_RECEIVED);
358 break;
359 default:
360 LOG_ERR("6P: sixp_input() fails because of unsupported type [type:%u]\n",
361 pkt.type);
362 return;
363 }
364 if(ret < 0) {
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) {
368 sf->input(pkt.type, pkt.code, pkt.body, pkt.body_len, src_addr);
369 } else {
370 }
371
372 return;
373}
374/*---------------------------------------------------------------------------*/
375int
377 const uint8_t *body, uint16_t body_len,
378 const linkaddr_t *dest_addr,
379 sixp_sent_callback_t func, void *arg, uint16_t arg_len)
380{
381 sixp_trans_t *trans;
383 int16_t seqno;
384 sixp_pkt_t pkt;
385
386 assert(dest_addr != NULL);
387
388 /* validate the state of a transaction with a specified peer */
389 trans = sixp_trans_find(dest_addr);
390 if(type == SIXP_PKT_TYPE_REQUEST) {
391 if(trans != 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");
395 return -1;
396 } else {
397 /* ready to send a request */
398 /* we're going to allocate a new transaction later */
399 }
400 } else if(type == SIXP_PKT_TYPE_RESPONSE) {
401 if(trans == NULL) {
402 LOG_ERR("6P: sixp_output() fails because of no transaction [peer_addr:");
403 LOG_ERR_LLADDR((const linkaddr_t *)dest_addr);
404 LOG_ERR_("]\n");
405 return -1;
406 } else if(sixp_trans_get_state(trans) !=
407 SIXP_TRANS_STATE_REQUEST_RECEIVED) {
408 LOG_ERR("6P: sixp_output() fails because of invalid transaction state\n");
409 return -1;
410 } else {
411 /* ready to send a response */
412 }
413 } else if(type == SIXP_PKT_TYPE_CONFIRMATION) {
414 if(trans == NULL) {
415 LOG_ERR("6P: sixp_output() fails because of no transaction [peer_addr:");
416 LOG_ERR_LLADDR((const linkaddr_t *)dest_addr);
417 LOG_ERR_("]\n");
418 return -1;
419 } else if(sixp_trans_get_state(trans) !=
420 SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
421 LOG_ERR("6P: sixp_output() fails because of invalid transaction state\n");
422 return -1;
423 } else {
424 /* ready to send a confirmation */
425 }
426 } else {
427 LOG_ERR("6P: sixp_output() fails because of unsupported type [type:%u]\n",
428 type);
429 return -1;
430 }
431
432 nbr = sixp_nbr_find(dest_addr);
433
434 /*
435 * Make sure we have a nbr for the peer if the packet is a response
436 * with success so that we can manage the schedule generation unless
437 * the request is CLEAR or in an unsupported format, in such a case
438 * we're going to return RC_ERR_VERSION or RC_ERR_SFID.
439 */
440 if(nbr == NULL &&
441 type == SIXP_PKT_TYPE_RESPONSE &&
444 code.value != SIXP_PKT_RC_ERR_SFID &&
445 (nbr = sixp_nbr_alloc(dest_addr)) == NULL) {
446 LOG_ERR("6P: sixp_output() fails because of no memory for another nbr\n");
447 return -1;
448 }
449
450 /* set SeqNum */
451 if(type == SIXP_PKT_TYPE_REQUEST) {
452 if(nbr == NULL &&
453 (nbr = sixp_nbr_alloc(dest_addr)) == NULL) {
454 LOG_ERR("6P: sixp_output() fails because it fails to allocate a nbr\n");
455 return -1;
456 }
457 if((seqno = sixp_nbr_get_next_seqno(nbr)) < 0){
458 LOG_ERR("6P: sixp_output() fails to get the next sequence number\n");
459 return -1;
460 }
461 } else {
462 assert(trans != NULL);
463 if((seqno = sixp_trans_get_seqno(trans)) < 0) {
464 LOG_ERR("6P: sixp_output() fails because it fails to get seqno\n");
465 return -1;
466 }
467 }
468
469 /* create a 6P packet within packetbuf */
470 if(sixp_pkt_create(type, code, sfid,
471 (uint8_t)seqno,
472 body, body_len,
473 type == SIXP_PKT_TYPE_REQUEST ? &pkt : NULL) < 0) {
474 LOG_ERR("6P: sixp_output() fails to create a 6P packet\n");
475 return -1;
476 }
477
478 /* allocate a transaction for a sending request */
479 if(type == SIXP_PKT_TYPE_REQUEST) {
480 assert(trans == NULL);
481 if((trans = sixp_trans_alloc(&pkt, dest_addr)) == NULL) {
482 LOG_ERR("6P: sixp_output() is aborted because of no memory\n");
483 return -1;
484 } else {
485 /* ready for proceed */
486 LOG_DBG("6P: sixp_output() allocates trans:%p\n", trans);
487 }
488 }
489
490 assert(trans != NULL);
491 sixp_trans_set_callback(trans, func, arg, arg_len);
492 if(sixtop_output(dest_addr, mac_callback, trans) == 0) {
493 /* sixtop_output() call ends without an error */
495 if(state == SIXP_TRANS_STATE_INIT) {
496 /*
497 * increment/update next_seqno immediately to prevent the next
498 * request from having the same seqno, although RFC8480
499 * describes a different way to manage seqno. If the next
500 * request has the same seqno as the previous request, a delayed
501 * response, which is for the previous transaction, may be
502 * handled mistakenly for the next request when the previous
503 * transaction is expired.
504 */
505 if(code.cmd == SIXP_PKT_CMD_CLEAR) {
506 LOG_INFO("6P: sixp_output() reset nbr's next_seqno by CLEAR Request\n");
508 } else {
510 }
511 sixp_trans_transit_state(trans, SIXP_TRANS_STATE_REQUEST_SENDING);
512 } else if(state == SIXP_TRANS_STATE_REQUEST_RECEIVED) {
513 sixp_trans_transit_state(trans, SIXP_TRANS_STATE_RESPONSE_SENDING);
514 } else if(state == SIXP_TRANS_STATE_RESPONSE_RECEIVED) {
515 sixp_trans_transit_state(trans, SIXP_TRANS_STATE_CONFIRMATION_SENDING);
516 } else {
517 /* shouldn't come here */
518 LOG_ERR("6P: sixp_output() is called trans:%p whose state is %u\n",
519 trans, state);
520 }
521 } else {
522 if(type == SIXP_PKT_TYPE_REQUEST) {
523 /* abort the transaction now */
524 sixp_trans_abort(trans);
525 }
526 }
527
528 return 0;
529}
530/*---------------------------------------------------------------------------*/
531void
533{
536}
537/*---------------------------------------------------------------------------*/
538/** @} */
const linkaddr_t * sixp_trans_get_peer_addr(sixp_trans_t *trans)
Return the peer addr of a specified transaction.
Definition sixp-trans.c:352
const sixtop_sf_t * sixtop_find_sf(uint8_t sfid)
Find a SF which has been added by SFID.
Definition sixtop.c:110
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.
Definition sixp-trans.c:469
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.
Definition sixp-pkt.c:1086
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.
Definition sixp.c:376
int sixp_pkt_parse(const uint8_t *buf, uint16_t len, sixp_pkt_t *pkt)
Parse a 6P packet.
Definition sixp-pkt.c:947
sixp_pkt_cmd_t sixp_trans_get_cmd(sixp_trans_t *trans)
Return the command associated with a specified transaction.
Definition sixp-trans.c:310
void sixp_trans_invoke_callback(sixp_trans_t *trans, sixp_output_status_t status)
Invoke the output callback of a specified transaction.
Definition sixp-trans.c:363
sixp_trans_t * sixp_trans_find(const linkaddr_t *peer_addr)
Find a transaction.
Definition sixp-trans.c:431
int sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state)
Change the state of a specified transaction.
Definition sixp-trans.c:224
void sixp_trans_free(sixp_trans_t *trans)
Free a transaction.
Definition sixp-trans.c:166
int16_t sixp_trans_get_seqno(sixp_trans_t *trans)
Return the sequence number associated with a specified transaction.
Definition sixp-trans.c:330
sixp_trans_state_t sixp_trans_get_state(sixp_trans_t *trans)
Return the state of a specified transaction.
Definition sixp-trans.c:320
int sixp_nbr_init(void)
Initialize 6p Neighbor Table.
Definition sixp-nbr.c:175
sixp_nbr_t * sixp_nbr_find(const linkaddr_t *addr)
Find a neighbor.
Definition sixp-nbr.c:70
int sixp_nbr_increment_next_seqno(sixp_nbr_t *nbr)
Increment the next sequence number of a neighbor.
Definition sixp-nbr.c:156
int16_t sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
Get the next sequence number of a neighbor.
Definition sixp-nbr.c:121
sixp_nbr_t * sixp_nbr_alloc(const linkaddr_t *addr)
Allocate a neighbor.
Definition sixp-nbr.c:80
void sixp_init(void)
Initialize 6P Module It invokes sixp_nbr_init() and sixp_trans_init().
Definition sixp.c:532
void sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
Input a 6P packet.
Definition sixp.c:205
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
Definition sixp.h:74
const sixtop_sf_t * sixp_trans_get_sf(sixp_trans_t *trans)
Return the scheduling function associated with a specified transaction.
Definition sixp-trans.c:299
int sixp_nbr_reset_next_seqno(sixp_nbr_t *nbr)
Reset the next sequence number of a neighbor to zero.
Definition sixp-nbr.c:144
int sixp_trans_init(void)
Initialize Memory and List for 6P transactions This function removes and frees existing transactions.
Definition sixp-trans.c:489
sixp_trans_state_t
6P Transaction States (for internal use)
Definition sixp-trans.h:47
int sixtop_output(const linkaddr_t *dest_addr, mac_callback_t callback, void *arg)
Output a 6P packet which is supposestored in packetbuf.
Definition sixtop.c:125
sixp_pkt_rc_t
6P Return Codes
Definition sixp-pkt.h:86
sixp_trans_t * sixp_trans_alloc(const sixp_pkt_t *pkt, const linkaddr_t *peer_addr)
Allocate a transaction.
Definition sixp-trans.c:388
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.
Definition sixp-trans.c:375
sixp_pkt_type_t
6P Message Types
Definition sixp-pkt.h:62
sixp_pkt_cmd_t
6P Command Identifiers
Definition sixp-pkt.h:72
@ SIXP_OUTPUT_STATUS_FAILURE
FAILURE.
Definition sixp.h:67
@ SIXP_OUTPUT_STATUS_SUCCESS
SUCCESS.
Definition sixp.h:66
@ SIXP_PKT_RC_ERR_SFID
RC_ERR_SFID.
Definition sixp-pkt.h:92
@ SIXP_PKT_RC_ERR_SEQNUM
RC_ERR_SEQNUM.
Definition sixp-pkt.h:93
@ SIXP_PKT_RC_ERR_BUSY
RC_ERR_BUSY.
Definition sixp-pkt.h:95
@ SIXP_PKT_RC_ERR_VERSION
RC_ERR_VERSION.
Definition sixp-pkt.h:91
@ SIXP_PKT_TYPE_RESPONSE
6P Response
Definition sixp-pkt.h:64
@ SIXP_PKT_TYPE_REQUEST
6P Request
Definition sixp-pkt.h:63
@ SIXP_PKT_TYPE_CONFIRMATION
6P Confirmation
Definition sixp-pkt.h:65
@ SIXP_PKT_CMD_CLEAR
CMD_CLEAR.
Definition sixp-pkt.h:79
Header file for the logging system.
@ MAC_TX_OK
The MAC layer transmission was OK.
Definition mac.h:93
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
6top IE Structure
Definition sixp-pkt.h:121
uint8_t sfid
SFID.
Definition sixp-pkt.h:125
sixp_pkt_type_t type
Type.
Definition sixp-pkt.h:123
sixp_pkt_code_t code
Code.
Definition sixp-pkt.h:124
const uint8_t * body
Other Fields...
Definition sixp-pkt.h:127
sixp_pkt_version_t version
Version.
Definition sixp-pkt.h:122
uint8_t seqno
SeqNum.
Definition sixp-pkt.h:126
uint16_t body_len
The length of Other Fields.
Definition sixp-pkt.h:128
/brief Scheduling Function Driver
Definition sixtop.h:104
sixtop_sf_error error
Internal Error Handler.
Definition sixtop.h:110
sixtop_sf_input input
Input Handler.
Definition sixtop.h:108
static uip_ds6_nbr_t * nbr
Pointer to llao option in uip_buf.
Definition uip-nd6.c:106
6P Codes integrating Command IDs and Return Codes
Definition sixp-pkt.h:103
sixp_pkt_cmd_t cmd
6P Command Identifier
Definition sixp-pkt.h:104
uint8_t value
8-bit unsigned integer value
Definition sixp-pkt.h:106