Search code examples
contikicontiki-ng

Separating RPL and application timeslots on TSCH Schedule (Contiki-NG)


I'm trying to build a TSCH Schedule that makes the RPL transmit into a timeslot and my application transmit in another timeslot, does someone know if is that possible?

I tried to use the following function to schedule my TSCH slotframe, but currently I can't figure out how to make TSCH identify RPL and application messages.

void my_tsch_scheduler(int advertising, int rx, int tx) {
  struct tsch_slotframe *sf_min;
  tsch_schedule_remove_all_slotframes();
  sf_min = tsch_schedule_add_slotframe(0, TSCH_SCHEDULE_DEFAULT_LENGTH);

  tsch_schedule_add_link(sf_min, LINK_OPTION_TX | LINK_OPTION_RX,
      LINK_TYPE_ADVERTISING, &tsch_broadcast_address, 0, 0);

  tsch_schedule_add_link(sf_min, LINK_OPTION_TX | LINK_OPTION_RX,
      LINK_TYPE_NORMAL, &tsch_broadcast_address, 3, 0);
}

Solution

  • Let's say you have two data slots scheduled at cells (3, 0) and (4, 0) and you want to use the first one for sending RPL messages and the second one for sending data:

    void my_tsch_scheduler(int advertising, int rx, int tx) {
      struct tsch_slotframe *sf_min;
      tsch_schedule_remove_all_slotframes();
      sf_min = tsch_schedule_add_slotframe(0, TSCH_SCHEDULE_DEFAULT_LENGTH);
    
      tsch_schedule_add_link(sf_min, LINK_OPTION_TX | LINK_OPTION_RX,
          LINK_TYPE_ADVERTISING, &tsch_broadcast_address, 0, 0);
    
      tsch_schedule_add_link(sf_min, LINK_OPTION_TX | LINK_OPTION_RX,
          LINK_TYPE_NORMAL, &tsch_broadcast_address, 3, 0); /* RPL */
      tsch_schedule_add_link(sf_min, LINK_OPTION_TX | LINK_OPTION_RX,
          LINK_TYPE_NORMAL, &tsch_broadcast_address, 4, 0); /* data */
    }
    

    The idea is to use a packet selector - a callback function that will inspect th packet and tell TSCH which cell to use.

    The selector needs to have specific declaration like:

    int my_callback_packet_ready(void);
    

    In the selector you can look at packetbuf attributes to figure out whether this is a RPL message, an EB message, or a regular data message:

    int my_callback_packet_ready(void) {
      const uint16_t slotframe = 0;
      const uint16_t channel_offset = 0;
      uint16_t timeslot = 0xffff;
    
      if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_BEACONFRAME) {
         /* EB packet */
         timeslot = 0;
      } else if (packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID) == UIP_PROTO_ICMP6
         && (packetbuf_attr(PACKETBUF_ATTR_CHANNEL) >> 8) == ICMP6_RPL) {
         /* RPL packet */
         timeslot = 3;
      } else {
         /* data packet */
         timeslot = 4;
      }
    
    #if TSCH_WITH_LINK_SELECTOR
      packetbuf_set_attr(PACKETBUF_ATTR_TSCH_SLOTFRAME, slotframe);
      packetbuf_set_attr(PACKETBUF_ATTR_TSCH_TIMESLOT, timeslot);
      packetbuf_set_attr(PACKETBUF_ATTR_TSCH_CHANNEL_OFFSET, channel_offset);
    #endif
    
      return 1;
    }
    

    The you need to enable selector, and define the selector callback in application's configuration:

    #define TSCH_CONF_WITH_LINK_SELECTOR 1
    #define TSCH_CALLBACK_PACKET_READY my_callback_packet_ready