50 #include "net/nbr-table.h" 61 #define LOG_MODULE "TSCH Sched" 62 #define LOG_LEVEL LOG_LEVEL_MAC 94 LOG_INFO(
"add_slotframe %u %u\n",
107 while((sf =
list_head(slotframe_list))) {
119 if(slotframe != NULL) {
122 while((l =
list_head(slotframe->links_list))) {
128 LOG_INFO(
"remove slotframe %u %u\n", slotframe->handle, slotframe->size.val);
145 if(sf->handle == handle) {
164 if(l->handle == handle) {
176 print_link_options(uint16_t link_options)
178 static char buffer[20];
182 if(link_options & LINK_OPTION_TX) {
183 strcat(buffer,
"Tx|");
185 if(link_options & LINK_OPTION_RX) {
186 strcat(buffer,
"Rx|");
188 if(link_options & LINK_OPTION_SHARED) {
189 strcat(buffer,
"Sh|");
191 length = strlen(buffer);
193 buffer[length - 1] =
'\0';
203 case LINK_TYPE_NORMAL:
205 case LINK_TYPE_ADVERTISING:
207 case LINK_TYPE_ADVERTISING_ONLY:
218 uint16_t timeslot, uint16_t channel_offset, uint8_t do_remove)
221 if(slotframe != NULL) {
225 if(timeslot > (slotframe->size.val - 1)) {
226 LOG_ERR(
"! add_link invalid timeslot: %u\n", timeslot);
236 LOG_ERR(
"! add_link memb_alloc couldn't take lock\n");
240 LOG_ERR(
"! add_link memb_alloc failed\n");
243 static int current_link_handle = 0;
248 l->handle = current_link_handle++;
249 l->link_options = link_options;
251 l->slotframe_handle = slotframe->handle;
252 l->timeslot = timeslot;
253 l->channel_offset = channel_offset;
255 if(address == NULL) {
260 LOG_INFO(
"add_link sf=%u opt=%s type=%s ts=%u ch=%u addr=",
262 print_link_options(link_options),
263 print_link_type(link_type), timeslot, channel_offset);
264 LOG_INFO_LLADDR(address);
269 if(l->link_options & LINK_OPTION_TX) {
274 if(!(l->link_options & LINK_OPTION_SHARED)) {
275 n->dedicated_tx_links_count++;
289 if(slotframe != NULL && l != NULL && l->slotframe_handle == slotframe->handle) {
291 uint8_t link_options;
296 link_options = l->link_options;
301 if(l == current_link) {
304 LOG_INFO(
"remove_link sf=%u opt=%s type=%s ts=%u ch=%u addr=",
306 print_link_options(l->link_options),
307 print_link_type(l->link_type), l->timeslot, l->channel_offset);
308 LOG_INFO_LLADDR(&l->addr);
318 if(link_options & LINK_OPTION_TX) {
322 if(!(link_options & LINK_OPTION_SHARED)) {
323 n->dedicated_tx_links_count--;
330 LOG_ERR(
"! remove_link memb_alloc couldn't take lock\n");
339 uint16_t timeslot, uint16_t channel_offset)
343 if(slotframe != NULL) {
348 if(l->timeslot == timeslot && l->channel_offset == channel_offset) {
363 uint16_t timeslot, uint16_t channel_offset)
366 if(slotframe != NULL) {
370 if(l->timeslot == timeslot && l->channel_offset == channel_offset) {
384 if(!(a->link_options & LINK_OPTION_TX)) {
396 return a_packet_count >= b_packet_count ? a : b;
409 uint16_t time_to_curr_best = 0;
423 uint16_t time_to_timeslot =
424 l->timeslot > timeslot ?
425 l->timeslot - timeslot :
426 sf->size.val + l->timeslot - timeslot;
427 if(curr_best == NULL || time_to_timeslot < time_to_curr_best) {
428 time_to_curr_best = time_to_timeslot;
431 }
else if(time_to_timeslot == time_to_curr_best) {
435 if((curr_best->link_options & LINK_OPTION_TX) == (l->link_options & LINK_OPTION_TX)) {
437 if(l->slotframe_handle != curr_best->slotframe_handle) {
438 if(l->slotframe_handle < curr_best->slotframe_handle) {
443 new_best = TSCH_LINK_COMPARATOR(curr_best, l);
447 if(l->link_options & LINK_OPTION_TX) {
454 if(new_best != l && (l->link_options & LINK_OPTION_RX)) {
455 if(curr_backup == NULL || l->slotframe_handle < curr_backup->slotframe_handle) {
460 if(new_best != curr_best && (curr_best->link_options & LINK_OPTION_RX)) {
461 if(curr_backup == NULL || curr_best->slotframe_handle < curr_backup->slotframe_handle) {
462 curr_backup = curr_best;
467 if(new_best != NULL) {
468 curr_best = new_best;
476 if(time_offset != NULL) {
477 *time_offset = time_to_curr_best;
480 if(backup_link != NULL) {
481 *backup_link = curr_backup;
516 (LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING),
517 LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
540 LOG_PRINT(
"----- start slotframe list -----\n");
545 LOG_PRINT(
"Slotframe Handle %u, size %u\n", sf->handle, sf->size.val);
548 LOG_PRINT(
"* Link Options %02x, type %u, timeslot %u, channel offset %u, address %u\n",
549 l->link_options, l->link_type, l->timeslot, l->channel_offset, l->addr.u8[7]);
556 LOG_PRINT(
"----- end slotframe list -----\n");
#define TSCH_ASN_DIVISOR_INIT(div, val_)
Initialize a struct asn_divisor_t.
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
struct tsch_neighbor * tsch_queue_get_nbr(const linkaddr_t *addr)
Get a TSCH neighbor.
struct tsch_slotframe * tsch_schedule_slotframe_next(struct tsch_slotframe *sf)
Access the next item in the list of slotframes.
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
int tsch_schedule_init(void)
Module initialization, call only once at init.
int tsch_get_lock(void)
Takes the TSCH lock.
void tsch_release_lock(void)
Releases the TSCH lock.
TSCH neighbor information.
802.15.4e slotframe (contains links)
struct tsch_slotframe * tsch_schedule_add_slotframe(uint16_t handle, uint16_t size)
Creates and adds a new slotframe.
const linkaddr_t linkaddr_null
The null link-layer address.
struct tsch_slotframe * tsch_schedule_get_slotframe_by_handle(uint16_t handle)
Looks up a slotframe by handle.
int tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot, uint16_t channel_offset)
Removes a link from a slotframe and timeslot.
struct tsch_link * tsch_schedule_add_link(struct tsch_slotframe *slotframe, uint8_t link_options, enum link_type link_type, const linkaddr_t *address, uint16_t timeslot, uint16_t channel_offset, uint8_t do_remove)
Adds a link to a slotframe.
struct tsch_neighbor * tsch_queue_add_nbr(const linkaddr_t *addr)
Add a TSCH neighbor queue.
Header file for the Packet queue buffer management
struct tsch_link * tsch_schedule_get_next_active_link(struct tsch_asn_t *asn, uint16_t *time_offset, struct tsch_link **backup_link)
Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag)
void tsch_schedule_print(void)
Prints out the current schedule (all slotframes and links)
void * list_head(list_t list)
Get a pointer to the first element of a list.
Header file for the real-time timer module.
#define TSCH_ASN_MOD(asn, div)
Returns the result (16 bits) of a modulo operation on ASN, with divisor being a struct asn_divisor_t...
Header file for the Contiki process interface.
Main API declarations for TSCH.
int tsch_schedule_remove_link(struct tsch_slotframe *slotframe, struct tsch_link *l)
Removes a link.
802.15.4 frame creation and parsing functions
int ringbufindex_elements(const struct ringbufindex *r)
Return the number of elements currently in the ring buffer.
Memory block allocation routines.
int tsch_is_locked(void)
Checks if the TSCH lock is set.
struct tsch_slotframe * tsch_schedule_slotframe_head(void)
Access the first item in the list of slotframes.
link_type
802.15.4e link types.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
int tsch_schedule_remove_slotframe(struct tsch_slotframe *slotframe)
Removes a slotframe.
void list_add(list_t list, void *item)
Add an item at the end of a list.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
void list_init(list_t list)
Initialize a list.
struct tsch_link * tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot, uint16_t channel_offset)
Looks within a slotframe for a link with a given timeslot.
#define LIST(name)
Declare a linked list.
int tsch_schedule_remove_all_slotframes(void)
Removes all slotframes, resulting in an empty schedule.
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
struct tsch_link * tsch_schedule_get_link_by_handle(uint16_t handle)
Looks for a link from a handle.
An IEEE 802.15.4-2015 TSCH link (also called cell or slot)
Header file for the Packet buffer (packetbuf) management
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
Header file for the logging system
Header file for the LED HAL.
The ASN is an absolute slot number over 5 bytes.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
void tsch_schedule_create_minimal(void)
Create a 6tisch minimal schedule with length TSCH_SCHEDULE_DEFAULT_LENGTH.
void * list_item_next(void *item)
Get the next item following this item.
#define MEMB(name, structure, num)
Declare a memory block.