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);
227 }
else if(channel_offset > 15) {
228 LOG_ERR(
"! add_link invalid channel_offset: %u\n", channel_offset);
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");
340 return slotframe != NULL &&
349 if(slotframe != NULL) {
353 if(l->timeslot == timeslot) {
369 uint16_t time_to_curr_best = 0;
383 uint16_t time_to_timeslot =
384 l->timeslot > timeslot ?
385 l->timeslot - timeslot :
386 sf->size.val + l->timeslot - timeslot;
387 if(curr_best == NULL || time_to_timeslot < time_to_curr_best) {
388 time_to_curr_best = time_to_timeslot;
391 }
else if(time_to_timeslot == time_to_curr_best) {
395 if((curr_best->link_options & LINK_OPTION_TX) == (l->link_options & LINK_OPTION_TX)) {
397 if(l->slotframe_handle < curr_best->slotframe_handle) {
402 if(l->link_options & LINK_OPTION_TX) {
408 if(curr_backup == NULL) {
410 if(new_best != l && (l->link_options & LINK_OPTION_RX)) {
414 if(new_best != curr_best && (curr_best->link_options & LINK_OPTION_RX)) {
415 curr_backup = curr_best;
420 if(new_best != NULL) {
421 curr_best = new_best;
429 if(time_offset != NULL) {
430 *time_offset = time_to_curr_best;
433 if(backup_link != NULL) {
434 *backup_link = curr_backup;
469 (LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING),
470 LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
493 LOG_PRINT(
"----- start slotframe list -----\n");
498 LOG_PRINT(
"Slotframe Handle %u, size %u\n", sf->handle, sf->size.val);
501 LOG_PRINT(
"* Link Options %02x, type %u, timeslot %u, channel offset %u, address %u\n",
502 l->link_options, l->link_type, l->timeslot, l->channel_offset, l->addr.u8[7]);
509 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_slotframe * tsch_schedule_slotframe_next(struct tsch_slotframe *sf)
Access the next item in the list of slotframes.
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.
struct tsch_link * tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot)
Looks within a slotframe for a link with a given timeslot.
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.
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...
int tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot)
Removes a link from a slotframe and timeslot.
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
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.
void list_init(list_t list)
Initialize a list.
#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().
char memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously 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.