Contiki-NG
sixp-trans.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 * Transaction Management for 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 "sixtop-conf.h"
46#include "sixp-nbr.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
54/**
55 * \brief 6P Transaction Data Structure (for internal use)
56 */
57struct sixp_trans {
58 struct sixp_trans *next;
59 const sixtop_sf_t *sf;
60 linkaddr_t peer_addr;
61 uint8_t seqno;
65 struct {
67 void *arg;
68 uint16_t arg_len;
69 } callback;
70 struct ctimer timer;
71};
72
73static void handle_trans_timeout(void *ptr);
74static void process_trans(void *ptr);
75static void schedule_trans_process(sixp_trans_t *trans);
76static sixp_trans_mode_t determine_trans_mode(const sixp_pkt_t *req);
77
78MEMB(trans_memb, sixp_trans_t, SIXTOP_MAX_TRANSACTIONS);
79LIST(trans_list);
80
81/*---------------------------------------------------------------------------*/
82static void
83handle_trans_timeout(void *ptr)
84{
85 sixp_trans_t *trans = (sixp_trans_t *)ptr;
86
87 assert(trans != NULL);
88 if(trans == NULL) {
89 return;
90 }
91
92 if(trans->sf->timeout != NULL) {
93 trans->sf->timeout(trans->cmd,
94 (const linkaddr_t *)&trans->peer_addr);
95 }
96
97 (void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
98}
99/*---------------------------------------------------------------------------*/
100static void
101start_trans_timer(sixp_trans_t *trans)
102{
103 ctimer_set(&trans->timer, trans->sf->timeout_interval,
104 handle_trans_timeout, trans);
105}
106/*---------------------------------------------------------------------------*/
107static void
108process_trans(void *ptr)
109{
110 sixp_trans_t *trans = (sixp_trans_t *)ptr;
111
112 assert(trans != NULL);
113 if(trans == NULL) {
114 return;
115 }
116
117 /* make sure that the timer is stopped */
118 ctimer_stop(&trans->timer);
119
120 /* state-specific operation */
121 if(trans->state == SIXP_TRANS_STATE_TERMINATING) {
122 /* handle the terminating state first */
123 LOG_INFO("6P-trans: trans [peer_addr:");
124 LOG_INFO_LLADDR((const linkaddr_t *)&trans->peer_addr);
125 LOG_INFO_(", seqno:%u] is going to be freed\n", trans->seqno);
126 sixp_trans_free(trans);
127 return;
128 }
129
130 switch(trans->state) {
131 /* do for others */
132 case SIXP_TRANS_STATE_RESPONSE_SENT:
133 case SIXP_TRANS_STATE_RESPONSE_RECEIVED:
134 if(trans->mode == SIXP_TRANS_MODE_2_STEP) {
135 (void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
136 }
137 break;
138 case SIXP_TRANS_STATE_CONFIRMATION_SENT:
139 case SIXP_TRANS_STATE_CONFIRMATION_RECEIVED:
140 (void)sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
141 break;
142 case SIXP_TRANS_STATE_TERMINATING:
143 default:
144 break;
145 }
146
147 if(trans->state != SIXP_TRANS_STATE_TERMINATING) {
148 /* set the timer with a timeout values defined by the SF */
149 start_trans_timer(trans);
150 }
151}
152/*---------------------------------------------------------------------------*/
153static void
154schedule_trans_process(sixp_trans_t *trans)
155{
156 assert(trans != NULL);
157 if(trans == NULL) {
158 return;
159 }
160
161 ctimer_stop(&trans->timer);
162 ctimer_set(&trans->timer, 0, process_trans, trans); /* expires immediately */
163}
164/*---------------------------------------------------------------------------*/
165void
166sixp_trans_free(sixp_trans_t *trans)
167{
168 assert(trans != NULL);
169 if(trans == NULL) {
170 return;
171 }
172
173 if (trans->state == SIXP_TRANS_STATE_WAIT_FREE) {
174 trans->state = SIXP_TRANS_STATE_UNAVAILABLE;
175 } else {
176 /* stop the timer that may still be running */
177 ctimer_stop(&trans->timer);
178 /*
179 * remove this trans from the list so that a new trans can be
180 * started with the same peer
181 */
182 list_remove(trans_list, trans);
183 }
184
185 if(trans->state == SIXP_TRANS_STATE_REQUEST_SENDING ||
186 trans->state == SIXP_TRANS_STATE_RESPONSE_SENDING ||
187 trans->state == SIXP_TRANS_STATE_CONFIRMATION_SENDING) {
188 /* memory is freed later, when mac_callback in sixp.c is called */
189 trans->state = SIXP_TRANS_STATE_WAIT_FREE;
190 } else {
191 memset(trans, 0, sizeof(sixp_trans_t));
192 memb_free(&trans_memb, trans);
193 }
194}
195/*---------------------------------------------------------------------------*/
197determine_trans_mode(const sixp_pkt_t *req)
198{
199 uint16_t cell_list_len;
200
201 assert(req != NULL);
202 if(req == NULL) {
203 return SIXP_TRANS_MODE_UNAVAILABLE;
204 }
205
206 /*
207 * We consider a transaction as 3-step if and only if its request command is
208 * either Add or Delete AND its cell_list is empty. Otherwise, 2-step.
209 */
210 if(req->type == SIXP_PKT_TYPE_REQUEST &&
211 (req->code.cmd == SIXP_PKT_CMD_ADD ||
212 req->code.cmd == SIXP_PKT_CMD_DELETE) &&
214 NULL, &cell_list_len,
215 req->body, req->body_len) == 0 &&
216 cell_list_len == 0) {
217 return SIXP_TRANS_MODE_3_STEP;
218 }
219
220 return SIXP_TRANS_MODE_2_STEP;
221}
222/*---------------------------------------------------------------------------*/
223int
224sixp_trans_transit_state(sixp_trans_t *trans, sixp_trans_state_t new_state)
225{
227 int ret_val;
228
229 assert(trans != NULL);
230 assert(new_state != SIXP_TRANS_STATE_UNAVAILABLE);
231 /* enforce state transition rules */
232 if(trans != NULL &&
233 (new_state == SIXP_TRANS_STATE_TERMINATING ||
234 (new_state == SIXP_TRANS_STATE_REQUEST_SENDING &&
235 trans->state == SIXP_TRANS_STATE_INIT) ||
236 (new_state == SIXP_TRANS_STATE_REQUEST_SENT &&
237 trans->state == SIXP_TRANS_STATE_REQUEST_SENDING) ||
238 (new_state == SIXP_TRANS_STATE_REQUEST_RECEIVED &&
239 trans->state == SIXP_TRANS_STATE_INIT) ||
240 (new_state == SIXP_TRANS_STATE_RESPONSE_SENDING &&
241 trans->state == SIXP_TRANS_STATE_REQUEST_RECEIVED) ||
242 (new_state == SIXP_TRANS_STATE_RESPONSE_SENT &&
243 trans->state == SIXP_TRANS_STATE_RESPONSE_SENDING) ||
244 (new_state == SIXP_TRANS_STATE_RESPONSE_RECEIVED &&
245 (trans->state == SIXP_TRANS_STATE_REQUEST_SENDING ||
246 trans->state == SIXP_TRANS_STATE_REQUEST_SENT)) ||
247 (new_state == SIXP_TRANS_STATE_CONFIRMATION_RECEIVED &&
248 (trans->state == SIXP_TRANS_STATE_RESPONSE_SENT ||
249 trans->state == SIXP_TRANS_STATE_RESPONSE_SENDING) &&
250 trans->mode == SIXP_TRANS_MODE_3_STEP) ||
251 (new_state == SIXP_TRANS_STATE_CONFIRMATION_SENDING &&
252 trans->state == SIXP_TRANS_STATE_RESPONSE_RECEIVED &&
253 trans->mode == SIXP_TRANS_MODE_3_STEP) ||
254 (new_state == SIXP_TRANS_STATE_CONFIRMATION_SENT &&
255 trans->state == SIXP_TRANS_STATE_CONFIRMATION_SENDING &&
256 trans->mode == SIXP_TRANS_MODE_3_STEP))) {
257 LOG_INFO("6P-trans: trans %p state changes from %u to %u\n",
258 trans, trans->state, new_state);
259
260 if(new_state == SIXP_TRANS_STATE_REQUEST_SENT) {
261 /* next_seqno should have been updated in sixp_output() */
262 } else if(new_state == SIXP_TRANS_STATE_RESPONSE_SENT) {
263 if((nbr = sixp_nbr_find(&trans->peer_addr)) == NULL) {
264 LOG_ERR("6top: cannot update next_seqno\n");
265 } else if(trans->cmd == SIXP_PKT_CMD_CLEAR) {
266 /* next_seqno must have been reset to 0 already; keep it */
267 assert(sixp_nbr_get_next_seqno(nbr) == 0);
268 } else {
269 /* override next_seqno with the one in the request */
270 sixp_nbr_set_next_seqno(nbr, trans->seqno);
272 }
273 }
274 trans->state = new_state;
275 schedule_trans_process(trans);
276 ret_val = 0;
277 } else if (trans != NULL){
278 /* invalid transition */
279 LOG_ERR("6P-trans: invalid transition, from %u to %u, on trans %p\n",
280 trans->state, new_state, trans);
281 /* inform the corresponding SF */
282 assert(trans->sf != NULL);
283 if(trans->sf->error != NULL) {
284 trans->sf->error(SIXP_ERROR_INVALID_TRANS_STATE_TRANSITION,
285 sixp_trans_get_cmd(trans),
288 }
289 ret_val = -1;
290 } else {
291 /* trans == NULL */
292 LOG_ERR("6top: invalid argument, trans is NULL\n");
293 ret_val = -1;
294 }
295 return ret_val;
296}
297/*---------------------------------------------------------------------------*/
298const sixtop_sf_t *
299sixp_trans_get_sf(sixp_trans_t *trans)
300{
301 assert(trans != NULL);
302 if(trans == NULL) {
303 return NULL;
304 } else {
305 return trans->sf;
306 }
307}
308/*---------------------------------------------------------------------------*/
310sixp_trans_get_cmd(sixp_trans_t *trans)
311{
312 assert(trans != NULL);
313 if(trans == NULL) {
315 }
316 return trans->cmd;
317}
318/*---------------------------------------------------------------------------*/
320sixp_trans_get_state(sixp_trans_t *trans)
321{
322 assert(trans != NULL);
323 if(trans == NULL) {
324 return SIXP_TRANS_STATE_UNAVAILABLE;
325 }
326 return trans->state;
327}
328/*---------------------------------------------------------------------------*/
329int16_t
330sixp_trans_get_seqno(sixp_trans_t *trans)
331{
332 assert(trans != NULL);
333 if(trans == NULL) {
334 LOG_ERR("6P-trans: sixp_trans_get_seqno() fails because trans is NULL\n");
335 return -1;
336 }
337 return trans->seqno;
338}
339/*---------------------------------------------------------------------------*/
341sixp_trans_get_mode(sixp_trans_t *trans)
342{
343 assert(trans != NULL);
344 if(trans == NULL) {
345 LOG_ERR("6P-trans: sixp_trans_get_mode() fails because trans is NULL\n");
346 return SIXP_TRANS_MODE_UNAVAILABLE;
347 }
348 return trans->mode;
349}
350/*---------------------------------------------------------------------------*/
351const linkaddr_t *
352sixp_trans_get_peer_addr(sixp_trans_t *trans)
353{
354 assert(trans != NULL);
355 if(trans == NULL) {
356 return NULL;
357 } else {
358 return (const linkaddr_t *)&trans->peer_addr;
359 }
360}
361/*---------------------------------------------------------------------------*/
362void
364{
365 assert(trans != NULL);
366
367 if(trans == NULL || trans->callback.func == NULL) {
368 return;
369 }
370 trans->callback.func(trans->callback.arg, trans->callback.arg_len,
371 &trans->peer_addr, status);
372}
373/*---------------------------------------------------------------------------*/
374void
375sixp_trans_set_callback(sixp_trans_t *trans,
376 sixp_sent_callback_t func, void *arg, uint16_t arg_len)
377{
378 assert(trans != NULL);
379 if(trans == NULL) {
380 return;
381 }
382 trans->callback.func = func;
383 trans->callback.arg = arg;
384 trans->callback.arg_len = arg_len;
385}
386/*---------------------------------------------------------------------------*/
387sixp_trans_t *
388sixp_trans_alloc(const sixp_pkt_t *pkt, const linkaddr_t *peer_addr)
389{
390 const sixtop_sf_t *sf;
391 sixp_trans_t *trans;
392
393 assert(pkt != NULL && peer_addr != NULL);
394 if(pkt == NULL || peer_addr == NULL) {
395 LOG_ERR("6P-trans: sixp_trans_alloc() fails because of invalid argument\n");
396 return NULL;
397 }
398
399 if((sf = sixtop_find_sf(pkt->sfid)) == NULL) {
400 LOG_ERR("6P-trans: sixp_trans_alloc() fails; no suitable SF [sfid:%u]\n",
401 pkt->sfid);
402 return NULL;
403 }
404
405 if(sixp_trans_find(peer_addr) != NULL) {
406 LOG_ERR("6P-trans: sixp_trans_alloc() fails because another trans with ");
407 LOG_ERR_LLADDR((const linkaddr_t *)peer_addr);
408 LOG_ERR_("is in process\n");
409 return NULL;
410 }
411
412 if((trans = memb_alloc(&trans_memb)) == NULL) {
413 LOG_ERR("6P-trans: sixp_trans_alloc() fails because of lack of memory\n");
414 return NULL;
415 }
416
417 memset(trans, 0, sizeof(sixp_trans_t));
418 trans->sf = sf;
419 trans->peer_addr = *peer_addr;
420 trans->seqno = pkt->seqno;
421 trans->cmd = pkt->code.value;
422 trans->state = SIXP_TRANS_STATE_INIT;
423 trans->mode = determine_trans_mode(pkt);
424 list_add(trans_list, trans);
425 start_trans_timer(trans);
426
427 return trans;
428}
429/*---------------------------------------------------------------------------*/
430sixp_trans_t *
431sixp_trans_find(const linkaddr_t *peer_addr)
432{
433 sixp_trans_t *trans;
434
435 assert(peer_addr != NULL);
436 if(peer_addr == NULL) {
437 return NULL;
438 }
439
440 /*
441 * XXX: we don't support concurrent 6P transactions which is mentioned in
442 * Section 4.3.3, draft-ietf-6tisch-6top-protocol-03.
443 *
444 * The assumption here is that there is one transactions for a single peer at
445 * most.
446 */
447 for(trans = list_head(trans_list);
448 trans != NULL; trans = trans->next) {
449 if(memcmp(peer_addr, &trans->peer_addr, sizeof(linkaddr_t)) == 0) {
450 return trans;
451 }
452 }
453
454 return NULL;
455}
456/*---------------------------------------------------------------------------*/
457void
458sixp_trans_terminate(sixp_trans_t *trans)
459{
460 assert(trans != NULL);
461 if(trans == NULL) {
462 return;
463 } else {
464 sixp_trans_transit_state(trans, SIXP_TRANS_STATE_TERMINATING);
465 }
466}
467/*---------------------------------------------------------------------------*/
468void
469sixp_trans_abort(sixp_trans_t *trans)
470{
471 assert(trans != NULL);
472 if(trans == NULL) {
473 return;
474 } else {
475 LOG_INFO("6P-trans: trans [peer_addr:");
476 LOG_INFO_LLADDR((const linkaddr_t *)&trans->peer_addr);
477 LOG_INFO_(", seqno:%u] is going to be aborted\n", trans->seqno);
480 /* process_trans() should be scheduled, which we will be stop */
481 assert(ctimer_expired(&trans->timer) == 0);
482 ctimer_stop(&trans->timer);
483 /* call process_trans() directly*/
484 process_trans((void *)trans);
485 }
486}
487/*---------------------------------------------------------------------------*/
488int
490{
491 sixp_trans_t *trans, *next_trans;
492
493 /* make sure there's no timer task left before the initialization */
494 for(trans = list_head(trans_list);
495 trans != NULL; trans = next_trans) {
496 next_trans = trans->next;
497 ctimer_stop(&trans->timer);
498 sixp_trans_free(trans);
499 }
500
501 list_init(trans_list);
502 memb_init(&trans_memb);
503 return 0;
504}
505/*---------------------------------------------------------------------------*/
506/** @} */
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition: ctimer.c:149
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
int ctimer_expired(struct ctimer *c)
Check if a callback timer has expired.
Definition: ctimer.c:161
void list_init(list_t list)
Initialize a list.
Definition: list.c:57
#define LIST(name)
Declare a linked list.
Definition: list.h:89
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition: list.c:89
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
Definition: list.c:152
void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition: list.c:63
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
Definition: memb.c:78
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
Definition: memb.c:59
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
Definition: memb.c:52
#define MEMB(name, structure, num)
Declare a memory block.
Definition: memb.h:91
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_nbr_set_next_seqno(sixp_nbr_t *nbr, uint16_t seqno)
Set the specified value to the next sequence number of a neighbor.
Definition: sixp-nbr.c:132
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_pkt_get_cell_list(sixp_pkt_type_t type, sixp_pkt_code_t code, const uint8_t **cell_list, sixp_pkt_offset_t *cell_list_len, const uint8_t *body, uint16_t body_len)
Read CellList in "Other Fields" of 6P packet.
Definition: sixp-pkt.c:608
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
void sixp_trans_terminate(sixp_trans_t *trans)
Helper function to terminate a transaction.
Definition: sixp-trans.c:458
int16_t sixp_nbr_get_next_seqno(sixp_nbr_t *nbr)
Get the next sequence number of a neighbor.
Definition: sixp-nbr.c:121
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
sixp_output_status_t
6P Send Status, which represents sixp_output() result.
Definition: sixp.h:65
sixp_trans_mode_t
6P Transaction Modes (for internal use)
Definition: sixp-trans.h:66
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
#define SIXTOP_MAX_TRANSACTIONS
The maximum number of transactions which the sixtop module can handle at the same time.
Definition: sixtop-conf.h:61
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
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_trans_mode_t sixp_trans_get_mode(sixp_trans_t *trans)
Return the mode, 2-step or 3-step, of a specified transaction.
Definition: sixp-trans.c:341
sixp_pkt_cmd_t
6P Command Identifiers
Definition: sixp-pkt.h:72
@ SIXP_OUTPUT_STATUS_ABORTED
ABORTED.
Definition: sixp.h:68
@ SIXP_PKT_TYPE_REQUEST
6P Request
Definition: sixp-pkt.h:63
@ SIXP_PKT_CMD_UNAVAILABLE
for internal use
Definition: sixp-pkt.h:80
@ SIXP_PKT_CMD_CLEAR
CMD_CLEAR.
Definition: sixp-pkt.h:79
@ SIXP_PKT_CMD_ADD
CMD_ADD.
Definition: sixp-pkt.h:73
@ SIXP_PKT_CMD_DELETE
CMD_DELETE.
Definition: sixp-pkt.h:74
Header file for the logging system.
Neighbor Management APIs for 6top Protocol (6P)
Transaction Management APIs for 6top Protocol (6P)
6top Configuration
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
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
A timer.
Definition: timer.h:82
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