49 #include "net/nbr-table.h" 60 #define LOG_MODULE "TSCH Sched" 61 #define LOG_LEVEL LOG_LEVEL_MAC 93 LOG_INFO(
"add_slotframe %u %u\n",
106 while((sf =
list_head(slotframe_list))) {
118 if(slotframe != NULL) {
121 while((l =
list_head(slotframe->links_list))) {
127 LOG_INFO(
"remove slotframe %u %u\n", slotframe->handle, slotframe->size.val);
144 if(sf->handle == handle) {
163 if(l->handle == handle) {
175 print_link_options(uint16_t link_options)
177 static char buffer[20];
181 if(link_options & LINK_OPTION_TX) {
182 strcat(buffer,
"Tx|");
184 if(link_options & LINK_OPTION_RX) {
185 strcat(buffer,
"Rx|");
187 if(link_options & LINK_OPTION_SHARED) {
188 strcat(buffer,
"Sh|");
190 length = strlen(buffer);
192 buffer[length - 1] =
'\0';
202 case LINK_TYPE_NORMAL:
204 case LINK_TYPE_ADVERTISING:
206 case LINK_TYPE_ADVERTISING_ONLY:
217 uint16_t timeslot, uint16_t channel_offset)
220 if(slotframe != NULL) {
224 if(timeslot > (slotframe->size.val - 1)) {
225 LOG_ERR(
"! add_link invalid timeslot: %u\n", timeslot);
233 LOG_ERR(
"! add_link memb_alloc couldn't take lock\n");
237 LOG_ERR(
"! add_link memb_alloc failed\n");
240 static int current_link_handle = 0;
245 l->handle = current_link_handle++;
246 l->link_options = link_options;
248 l->slotframe_handle = slotframe->handle;
249 l->timeslot = timeslot;
250 l->channel_offset = channel_offset;
252 if(address == NULL) {
257 LOG_INFO(
"add_link sf=%u opt=%s type=%s ts=%u ch=%u addr=",
259 print_link_options(link_options),
260 print_link_type(link_type), timeslot, channel_offset);
261 LOG_INFO_LLADDR(address);
266 if(l->link_options & LINK_OPTION_TX) {
271 if(!(l->link_options & LINK_OPTION_SHARED)) {
272 n->dedicated_tx_links_count++;
286 if(slotframe != NULL && l != NULL && l->slotframe_handle == slotframe->handle) {
288 uint8_t link_options;
293 link_options = l->link_options;
298 if(l == current_link) {
301 LOG_INFO(
"remove_link sf=%u opt=%s type=%s ts=%u ch=%u addr=",
303 print_link_options(l->link_options),
304 print_link_type(l->link_type), l->timeslot, l->channel_offset);
305 LOG_INFO_LLADDR(&l->addr);
315 if(link_options & LINK_OPTION_TX) {
319 if(!(link_options & LINK_OPTION_SHARED)) {
320 n->dedicated_tx_links_count--;
327 LOG_ERR(
"! remove_link memb_alloc couldn't take lock\n");
336 uint16_t timeslot, uint16_t channel_offset)
345 uint16_t timeslot, uint16_t channel_offset)
348 if(slotframe != NULL) {
352 if(l->timeslot == timeslot && l->channel_offset == channel_offset) {
366 if(!(a->link_options & LINK_OPTION_TX)) {
378 return a_packet_count >= b_packet_count ? a : b;
391 uint16_t time_to_curr_best = 0;
405 uint16_t time_to_timeslot =
406 l->timeslot > timeslot ?
407 l->timeslot - timeslot :
408 sf->size.val + l->timeslot - timeslot;
409 if(curr_best == NULL || time_to_timeslot < time_to_curr_best) {
410 time_to_curr_best = time_to_timeslot;
413 }
else if(time_to_timeslot == time_to_curr_best) {
417 if((curr_best->link_options & LINK_OPTION_TX) == (l->link_options & LINK_OPTION_TX)) {
419 if(l->slotframe_handle != curr_best->slotframe_handle) {
420 if(l->slotframe_handle < curr_best->slotframe_handle) {
425 new_best = TSCH_LINK_COMPARATOR(curr_best, l);
429 if(l->link_options & LINK_OPTION_TX) {
435 if(curr_backup == NULL) {
437 if(new_best != l && (l->link_options & LINK_OPTION_RX)) {
441 if(new_best != curr_best && (curr_best->link_options & LINK_OPTION_RX)) {
442 curr_backup = curr_best;
447 if(new_best != NULL) {
448 curr_best = new_best;
456 if(time_offset != NULL) {
457 *time_offset = time_to_curr_best;
460 if(backup_link != NULL) {
461 *backup_link = curr_backup;
496 (LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING),
497 LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
520 LOG_PRINT(
"----- start slotframe list -----\n");
525 LOG_PRINT(
"Slotframe Handle %u, size %u\n", sf->handle, sf->size.val);
528 LOG_PRINT(
"* Link Options %02x, type %u, timeslot %u, channel offset %u, address %u\n",
529 l->link_options, l->link_type, l->timeslot, l->channel_offset, l->addr.u8[7]);
536 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_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.
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)
Adds a link to a slotframe.
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.