Skip to content

upload the mlbot files #2611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/net/mac/tsch/mlbot/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONTIKI_SOURCEFILES += mlbot.c
22 changes: 22 additions & 0 deletions core/net/mac/tsch/mlbot/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Cambios hecho en documentos que no son MLBOT

## tsch.c

* **add**
*#include "net/mac/tsch/mlbot/mlbot.h"*, en la sección de los include
* **add**


##tsch-slot-operation.c
* **add**
*#include "net/mac/tsch/mlbot/mlbot.h"*, en la sección de los include
* **add**
* #if TSCH_MLBOT_ON
/* Aqui se acaba de poner un EB en la cola, por lo que se le informa a MLBOT */
eb_has_send = 1;

if (process_post(&mlbot_process, PROCESS_EVENT_POLL, NULL) != PROCESS_ERR_OK){
PRINTF ("MLBOT: The event EB send could not be posted to mlbot process");
/* !!!!! aqui se puede tomar un desición para asegurar que mlbot se entere, o no */
}
#endif*
250 changes: 250 additions & 0 deletions core/net/mac/tsch/mlbot/mlbot-packet.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
/*
* Copyright (c) 2019, Sancti Spiritus, Cuba.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/

/**
* \file
* MLBOT packet format management
* \author
* Bernardo Yaser León Ávila <bernardoyla@gmail.com>
*/

/*---------------------------------------------------------------------------*/
/* Includes */

#include "contiki.h"
#include "net/packetbuf.h"
#include "net/netstack.h"

#include "net/mac/tsch/tsch.h"
#include "net/mac/tsch/tsch-packet.h"
#include "net/mac/tsch/tsch-log.h"

//#include "net/mac/framer-802154.h"
#include "net/mac/tsch/mlbot/mlbot-packet.h"
#include "net/mac/tsch/mlbot/mlbot.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#if TSCH_LOG_LEVEL >= 1
#define DEBUG DEBUG_PRINT
#else /* TSCH_LOG_LEVEL */
#define DEBUG DEBUG_NONE
#endif /* TSCH_LOG_LEVEL */
#include "net/net-debug.h"


/*---------------------------------------------------------------------------*/
/* LB packet init
* Aqui nos aseguramos de que la estructura del nuevo LB este completamente limpia
*/
uint8_t mlbot_lb_init (light_beacon_t *lb){

//hay que hacer algo con esto o quitarlo
lb->lb_handle = 1;
linkaddr_copy((linkaddr_t *)&lb->src_addr, &linkaddr_node_addr);
lb->src_pid = frame802154_get_pan_id();

lb->payload.mac_join_metric = tsch_join_priority;
lb->payload.next_eb_channel = 0;
lb->payload.time_until_next_eb.ls2b = 0L;
lb->payload.time_until_next_eb.ms1b = 0;

lb->next_eb_clock_time = 0;
lb->link.lqi = 0;
lb->link.rssi = 0;

return (lb->lb_handle);

}

/*---------------------------------------------------------------------------*/
/* Create an LB packet
El LB no tiene IEs y siempre tiene un tamaño fijo.
Aquí se ensambla el frame que va a contener el LB
en el lb_frame, y luego se construye en el buffer buf
Param lb Es un light beacon en una estructura tipo light_beacon_t
Param buf Es el buffer donde será costruido el frame
retrun / tamanno del header del paquete creado
*/
int mlbot_packet_create_lb(light_beacon_t *lb, uint8_t *buf)
{
uint8_t hdr_len = 0;
//uint32_t temp_time_until_next_eb;

frame802154_t lb_frame;
/* Reservamos memoria para todo el payload */
uint8_t lb_payload[5];
lb_frame.payload = &lb_payload[0];

/* Create 802.15.4 header */
lb_frame.fcf.frame_type = FRAME802154_BEACONFRAME;
lb_frame.fcf.ie_list_present = 0;
lb_frame.fcf.frame_version = FRAME802154_IEEE802154E_2012;
lb_frame.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;
lb_frame.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
lb_frame.fcf.sequence_number_suppression = 1;

lb_frame.fcf.panid_compression = 0;
lb_frame.src_pid = frame802154_get_pan_id();
lb_frame.dest_pid = frame802154_get_pan_id();
linkaddr_copy((linkaddr_t *)&lb_frame.src_addr, &linkaddr_node_addr);
lb_frame.dest_addr[0] = 0xff;
lb_frame.dest_addr[1] = 0xff;

/* Prepare the LB payload
* Have 3 fields
* macNextEbChannel: 1 byte (5 bits to be use)
* macJoinMetric: 1 byte
* macNextEbOffser: 2 - 3 bytes
*/

lb_payload[0] = lb->payload.next_eb_channel;
lb_payload[1] = lb->payload.mac_join_metric;

/* En el payload el time_until_next_eb sera organizada desde el byte ls hasta ms */
lb_payload[2] = 0x00FF & lb->payload.time_until_next_eb.ls2b;
lb_payload[3] = 0x00FF & lb->payload.time_until_next_eb.ls2b >> 8;

lb_frame.payload_len = 4;

/* Si hay algo en el 3er byte se envia */
if (lb->payload.time_until_next_eb.ms1b != 0){
lb_payload[4] = lb->payload.time_until_next_eb.ms1b;
lb_frame.payload_len ++;
}

PRINTF("TSCH-MLBOT: LB payload -> next_ch: %u, jp: %u, next_time: %#02X%02X",
lb_frame.payload[0],
lb_frame.payload[1],
lb_frame.payload[3], lb_frame.payload[2]);
if (lb_frame.payload_len == 5){
PRINTF("+%u",lb_frame.payload[4]);
}
PRINTF("\n");

/* Creat the frame, the dow build the header and return it size */
if((hdr_len = frame802154_create(&lb_frame, buf)) == 0) {
return 0;
}

int frame_len = hdr_len;

int i;
for (i = 0; i < lb_frame.payload_len; i++){
buf[frame_len] = lb_frame.payload[i];
frame_len ++;
}

return frame_len;
}

/*---------------------------------------------------------------------------*/
/* Update Time until next LB and next channel in LB packet */
int mlbot_packet_update_lb(light_beacon_t *lb, uint8_t *buf)
{
PRINTF ("Update a LB packet");
return 1;
}

/*---------------------------------------------------------------------------*/
/*Parse an LB payload
* \brief Parse an LB packet payload. This funtion may used when
tsch_packet_parse_eb read a beacon and is not a EB.
\param lb Light beacon struct to store the data parsed
\param frame A beacon frame.
*/
int mlbot_packet_parse_lb(frame802154_t *frame, light_beacon_t *lb)
{
/* Is not a LB if */
if (frame->fcf.frame_type != FRAME802154_BEACONFRAME ||
frame->fcf.ie_list_present == 0 ||
frame->payload_len == 0 || frame->payload_len > 5 ){
PRINTF("TSCH-MLBOT:! parse_lb: frame is not a LB to");
return 0;
}

/* Read the LB payload
* Have 3 fields
* macNextEbChannel: 1 byte (5 bits to be use)
* macJoinMetric: 1 byte
* macNextEbOffser: 2 - 3 bytes
*/
lb->payload.next_eb_channel = frame->payload[0];
lb->payload.mac_join_metric = frame->payload[1];

lb->payload.time_until_next_eb.ls2b = (uint16_t)frame->payload[2];
lb->payload.time_until_next_eb.ls2b = lb->payload.time_until_next_eb.ls2b | ((uint16_t)frame->payload[3] << 8);

/* Load in clock_time when the next EB come from this node*/
lb->next_eb_clock_time = (uint32_t)lb->payload.time_until_next_eb.ls2b;
lb->next_eb_clock_time = lb->next_eb_clock_time | ((uint32_t)lb->payload.time_until_next_eb.ms1b << 16);
lb->next_eb_clock_time = clock_time() + lb->next_eb_clock_time;

if (frame->payload_len == 5){
lb->payload.time_until_next_eb.ms1b = frame->payload[4];
}

/* Read the address and panid */
linkaddr_copy((linkaddr_t *)&lb->src_addr, (linkaddr_t *)&frame->src_addr);
lb->src_pid = frame->src_pid;

/* Read the radio and link paramenters */
lb->link.rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI);
lb->link.lqi = packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY);

/* Add new neighbor */
/* Esto hay que hacerlo con una lista
cotiki ya trae implementaciones para las listas

LIST(name_list);
list_add(name_list, n);
list_remove(name_list, n);
list_head(name_list);
list_init(name_list);
todos definidos en list.h
*/

/* struct tsch_neighbor *n = NULL;
n = tsch_queue_get_nbr(lb->src_addr);

if (mlbot_neighbor_amount != 0){

!!!!!!!!!

}
mlbot_neighbor_amount ++;
lb->lb_handle = mlbot_neighbor_amount;
*/
return 0;
}
121 changes: 121 additions & 0 deletions core/net/mac/tsch/mlbot/mlbot-packet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@

/*
* Copyright (c) 2019, Sancti Spiritus, Cuba.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/


/* Includes */

#ifndef __MLBOT_PACKET_H__
#define __MLBOT_PACKET_H__

#include "contiki.h"
#include "dev/radio.h"

#include "net/mac/frame802154.h"

/* Configuration */



/* Define tipes */

/**
* \brief The nextEbOffset need just 3 bytes, and most of cases, just 2.
*/
typedef struct {
uint8_t ms1b;
uint16_t ls2b;
} eb_offset;

/**
* \brief Defines the LB informations fields.
*/
typedef struct {
uint8_t next_eb_channel; /**< 5 bit. Next EB channel */
eb_offset time_until_next_eb; /**< 3 byte. Time in miliseconds until the next EB */
uint8_t mac_join_metric; /**< 1 byte. Join metric */ //Puede ser menor, TSCH_MAX_JOIN_PRIORITY tiene hasta 32, 5 bits
} payload_lb_t;

/**
* \brief Defines the LB link quality params.
*/
typedef struct {
radio_value_t rssi; /**< Received Signal Strenght Indicator */
radio_value_t lqi; /**< Link Quality Indicator */
} link_lb_t;

/**
* \brief Defines all LB data. //Creo se pueda identificar el LB por su fuente (addr y pan ID)
* //El resto de los parametros se actualizan cada nuevo lb de dicha fuente
*/
typedef struct {
/* The fields src_addr must come first to ensure they are aligned to the
* CPU word size. Needed as they are accessed directly as linkaddr_t*. Note we cannot use
* the type linkaddr_t directly here, as we always need 8 bytes, not LINKADDR_SIZE bytes. */
uint8_t lb_handle;
uint8_t src_addr[8]; /**< Source address */
uint16_t src_pid; /**< Source PAN ID */
payload_lb_t payload; /**< Payload field */
clock_time_t next_eb_clock_time; /**< Time in clock_time when the next EB will be send */
link_lb_t link; /**< Link quality indicators */
} light_beacon_t;


/* Prototypes */

/*---------------------------------------------------------------------------*/
/* Create LB packet */

int mlbot_packet_create_lb(light_beacon_t *lb, uint8_t *buf);

/*---------------------------------------------------------------------------*/
/* Update Time until next EB and next channel in LB packet */
int mlbot_packet_update_lb(light_beacon_t *lb, uint8_t *buf);

/*---------------------------------------------------------------------------*/
/*Parse an LB payload
* \brief Parse an LB packet payload. This funtion may used when
tsch_packet_parse_eb read a beacon and is not a EB.
\param lb Light beacon struct to store the data parsed
\param frame A beacon frame.
*/
int mlbot_packet_parse_lb(frame802154_t *frame, light_beacon_t *lb);


/*---------------------------------------------------------------------------*/
/* Init the lb buffer to tx */
uint8_t mlbot_lb_init (light_beacon_t *lb);

/** @} */
#endif /* MLBOT_PACKET_H */
/** @} */
/** @} */
240 changes: 240 additions & 0 deletions core/net/mac/tsch/mlbot/mlbot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
/*
* Copyright (c) 2019, Sancti Spiritus, Cuba.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/

/**
* \file
* MLBOT packet format management
* \author
* Bernardo Yaser León Ávila <bernardoyla@gmail.com>
*/

/*---------------------------------------------------------------------------*/
/* Includes */

#include "contiki.h"
#include "sys/rtimer.h"

#include "net/netstack.h"

#include "net/mac/tsch/tsch-log.h"
#include "net/mac/tsch/tsch-slot-operation.h"
#include "net/mac/tsch/tsch-schedule.h"
#include "net/mac/tsch/tsch-asn.h"

#include "net/mac/tsch/mlbot/mlbot.h"
#include "net/mac/tsch/mlbot/mlbot-packet.h"


#include <stdio.h>
#include <string.h>

#if TSCH_LOG_LEVEL >= 1
#define DEBUG DEBUG_PRINT
#else /* TSCH_LOG_LEVEL */
#define DEBUG DEBUG_NONE
#endif /* TSCH_LOG_LEVEL */
#include "net/net-debug.h"

/*---------------------------------------------------------------------------*/
/* Create gloval vars
*/
long unsigned next_eb_scheduled;

uint16_t mlbot_lb_interval;

int lb_sended;

/* Timestamp in which the next EB will be transmitted */
rtimer_clock_t next_time_eb;
/* Time in ms needed for the next EB to be transmitted */
static unsigned long next_time_to_eb;
/* ASN where the next EB will be transmitted */
static struct tsch_asn_t next_asn_eb;
/* How many ASN left to reach the next EB */
static uint16_t asn_until_next_eschedule_eb;

light_beacon_t lb;
uint8_t lb_packet_buf [LB_MAX_LEN];
uint8_t lb_packet_buf_lengt;

/*---------------------------------------------------------------------------*/
/* The main MLBOT process */
PROCESS(mlbot_process, "MLBOT: main process");


/*---------------------------------------------------------------------------*/
/**** Funtions ****/

/*---------------------------------------------------------------------------*/
/* Here it is checked if the package I enter is a valid LB */
int check_lb_packet(struct input_packet *input_packet, frame802154_t *lb_frame) {

if (input_packet == NULL) {
return 0;
}
/* Without modifying the package we search FCF Frame Control Field
   * It is the 2nd byte of the payload: input_packet-> payload [1]
   * that the frame version is right
   * that is an beacon - input_packet->payload[0] & 7 == 0b0000
   * that does not have IEs: bit 1: & 2
   * If it is a beacon without IEs, it is an LB
   * */

if (((input_packet->payload[1] >> 4) & 0b11) != FRAME802154_IEEE802154E_2012){
PRINTF("MLBOT: Wrong frame version\n");
return 0;
}
if ((input_packet->payload[0] & 0b0111) != FRAME802154_BEACONFRAME) {
PRINTF("MLBOT: Is not a beacon\n");
return 0;
}
if (input_packet->payload[1] & 0b0010) {
PRINTF("MLBOT: Has IE, is EB\n");
return 0;
}
/* If is here, is a LB */
if (frame802154_parse ((uint8_t *)input_packet->payload, input_packet->len, lb_frame)){
return input_packet->len;
}
PRINTF ("MLBOT: No se pudo parsear\n");
return 0;
}


/*---------------------------------------------------------------------------*/
/* Here the LB sequence is prepared */
void prepare_lb_sequece ()
{
/* next_eb_schedule is in CLOCK_TICKs, turn into RTIMER_TICKs */
next_eb_scheduled = TSCH_CLOCK_TO_TICKS(next_eb_scheduled);
asn_until_next_eschedule_eb = (next_eb_scheduled / tsch_timing[tsch_ts_timeslot_length]) + 1;

/* The next EB ASN */
next_asn_eb = tsch_current_asn;
TSCH_ASN_INC(next_asn_eb, asn_until_next_eschedule_eb);

/* Init the LB struct */
mlbot_lb_init(&lb);

/* The next EB channel */
lb.payload.next_eb_channel = tsch_calculate_channel(&next_asn_eb, 0);

/* The join priority */
lb.payload.mac_join_metric = tsch_join_priority;

/* Start to send LB */
lb_sch = 1;

}

/*---------------------------------------------------------------------------*/
/* Update the LB */
void mlbot_lb_update(void)
{
/* Update how many asn should wait until the next eb */
asn_until_next_eschedule_eb = TSCH_ASN_DIFF(next_asn_eb, tsch_current_asn);

/* The next time until EB in ms */
next_time_to_eb = RTIMERTICKS_TO_US(tsch_timing[tsch_ts_timeslot_length]) * (asn_until_next_eschedule_eb - 1);
/* The next time until EB in ms, esta variable sera actualizada continuamente */
next_time_to_eb = next_time_to_eb - (2 * tsch_timing[tsch_ts_timeslot_length]);
next_time_to_eb = (next_time_to_eb / 1000);

lb.payload.time_until_next_eb.ls2b = (uint16_t)next_time_to_eb;
/* If 2 bytes are no enough */
if (next_time_to_eb > 0xFFFF) {
lb.payload.time_until_next_eb.ms1b = (uint8_t) 0x00FF & (next_time_to_eb >> 16);
}

/* Create a lb's frame to send */
lb_packet_buf_lengt = mlbot_packet_create_lb(&lb, lb_packet_buf);
if (asn_until_next_eschedule_eb < TSCH_SCHEDULE_DEFAULT_LENGTH){
lb_sch = 0;
}
}

/*---------------------------------------------------------------------------*/
/* Send the LB */
int mlbot_send_lb(void)
{

if (lb_packet_buf_lengt == 0) {
PRINTF ("No packet to tx\n");
return 0;
}

/* Hop channel */

NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset));

if (NETSTACK_RADIO.prepare((void *)lb_packet_buf, (uint8_t)lb_packet_buf_lengt) == 0){

NETSTACK_RADIO.on();
NETSTACK_RADIO.transmit(lb_packet_buf_lengt);
NETSTACK_RADIO.off();
} else {
PRINTF ("No lb tx\n");
}


return 1;

}

/*---------------------------------------------------------------------------*/
/* The main MLBOT process */
PROCESS_THREAD(mlbot_process, ev, data)
{
PROCESS_BEGIN();

PRINTF("MLBOT: Process started\n");

next_eb_scheduled = 0;
lb_sch = 0;

while (1){
PROCESS_YIELD_UNTIL(next_eb_scheduled);
/* If it has been programmed and sent an EB... */
if (next_eb_scheduled){

PRINTF("EB\n");

/* LB sequence is prepared */
prepare_lb_sequece();

/* This value has been transferred to next_time_to_eb in ms */
next_eb_scheduled = 0;
}

}
PROCESS_END();
}
65 changes: 65 additions & 0 deletions core/net/mac/tsch/mlbot/mlbot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

#include "net/mac/tsch/tsch-slot-operation.h"
#include "lib/random.h"

/***** External Variables *****/

extern long unsigned next_eb_scheduled;

extern uint16_t mlbot_lb_interval;

int lb_tx;
int lb_sch;

/* Macros y const */

#define LB_MAX_LEN 25

/* Every few TS we will send the LB
* if we do not define anything by default it will be the default length of a slotframe */
#ifdef MLBOT_CONF_DEFAULT_LB_SEND_INTERVAL
#define MLBOT_LB_DEFAULT_SEND_INTERVAL MLBOT_CONF_DEFAULT_LB_SEND_INTERVAL
#else
//#define MLBOT_LB_DEFAULT_SEND_INTERVAL TSCH_SCHEDULE_DEFAULT_LENGTH
#define MLBOT_LB_DEFAULT_SEND_INTERVAL 1

#endif

/* This constant should preferably be a power of 2 (1, 2, 4, 8 ...)
* this constant represents the inverse, if we define 2, the probability is 0.5
* if we define 4, it is 0.25 ... the higher the number, the lower the probability
* and less likely shipping frequency and less likely collisions
*/
#ifdef MLBOT_CONF_LB_PROBABILITY
#define MLBOT_LB_PROBABILITY MLBOT_CONF_LB_PROBABILITY
#else
/* The probability of sending an LB at 0.25 */
#define MLBOT_LB_PROBABILITY 4
#endif

/* Initializes MLBOT */
#ifdef TSCH_MLBOT_ON_OFF
#define TSCH_MLBOT_ON TSCH_MLBOT_ON_OFF
#else
#define TSCH_MLBOT_ON 1
#endif

/* Process */
/*---------------------------------------------------------------------------*/
/* This is the main process that orchestrates the sending of the LB.
* Must be invoked once the tsch_send_eb_process process begins
* to send EBs.
*/
PROCESS_NAME(mlbot_process);


/* funciones */

/* Function that sends the LB */
int mlbot_send_lb(void);

/* Function that updates the LB */
void mlbot_lb_update(void);

/* Check if the package received by radio is an LB */
int check_lb_packet (struct input_packet *packet, frame802154_t *lb_frame);
189 changes: 189 additions & 0 deletions core/net/mac/tsch/mlbot/mlbot.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/* Antes de nada, el nodo TSCH debe simcronizarse a la red */

/* Algoritmo desde el inicio del nodo:
TSCH define las funciones que reciben el paquete de radio.
Cuando el nodo depierta verifica si es coordinador,
si no, llama al protohilo de escaneo PT_THREAD(tsch_scan(struct pt *pt))
(tsch.c) que es quien contiene los algoritmo de scaneo del medio
(hay que modificar este protohilo)
el protohilo escanea hasta
if(is_packet_pending)
input_eb.len = NETSTACK_RADIO.read(input_eb.payload, TSCH_PACKET_MAX_LEN); // 651 - tsch.c
Se devuelve el largo del paquete y un puntero al payload;
en este caso se pasan a la estructura de input_eb, porque es lo unico que se espera
al modificar puede que sean dos cosas, o el EB o el LB, por lo que se deben cambiar
o el nombre de la variable o una compilación condicional al MLBOT....

NETSTACK_RADIO.get_object(RADIO_PARAM_LAST_PACKET_TIMESTAMP, &t0, sizeof(rtimer_clock_t)); //654 - tsch.c
Se obtiene el timestamp, si es una sonda, ???? ya veremos que hacer con el

tsch_associate(&input_eb, t0); //659 - tsch.c
Se llama directamente a la función para asociarse; se asume que cualquier paquete es potencialmente una sonda
Se le pasa la dirección del puntero al paquete recibido y el timestapm.
El timestamp es la base del sincronismo, porque si el paquete resulta ser un EB se recibio según la estructura de tiempo
contenida en el EB, cuya ventana de tx para el timeslot comienza en la marca recogida por el timestamp.
El timestamp es entonces crucial para mantener el sincronismo de la red TSCH
Recordamos que la estructura input_eb solo tiene lleno los campos len y payload

tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) // 432 - tsch.c

frame802154_t frame; //434 - tsch.c
struct ieee802154_ies ies; //435 -tsch.c
uint8_t hdrlen;
Esta función declara una estructura para el frame y otra para los IEs y un byte para el tamaño del header...

if(input_eb == NULL || tsch_packet_parse_eb(input_eb->payload, input_eb->len, &frame, &ies, &hdrlen, 0) == 0) //439 - tsch
return 0; //442 - tsch.c
Si el paquete está vacío o si parse falla se retorna 0.
De cualquier forma se intenta hacer el parseo a un probable EB; la propia función verifica luego de parcear que es o no un EB
Esto puede ser un desperdicio en tiempo de ejecución pero lo cierto es que ahora código en una memoria restringida
La función está implementada en el archivo tsch-packet.c

tsch_packet_parse_eb(const uint8_t *buf, int buf_size, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len, int frame_without_mic)

if((ret = frame802154_parse((uint8_t *)buf, buf_size, frame)) == 0) // 360 - tsch-packet.c
Se parsea todo el frame sin los IE; primero debe ser verificado si efectivamente es un EB;
esta función está en el archivo frame802154.c

frame802154_parse(uint8_t *data, int len, frame802154_t *pf)

frame802154_parse_fcf(p, &fcf); // 518 - frame802154.c
decodifica el Frame Control Field FCF.
Esta función está implementada en el mismo archivo justo arriba, verla para ver como está parceados los bits en uint8_t

decodifica en campos separados las distintas partes de paquete según el estandar..........

if(frame->fcf.frame_version < FRAME802154_IEEE802154E_2012 || frame->fcf.frame_type != FRAME802154_BEACONFRAME)
aqui es donde definitivamente se verifica si es un EB;
si la versión del frame no es la 2012, no es tsch o type no es un EB, bueno, no es un EB

Si todo indica que es un EB, y es un EB válido, se parcea el ASN y el JP (join priority)
estos son los dos campos de Synchronization IE (epígrafe 7.4.4.2) con 6 octetos, 5 ASN + 1 JP

tsch_current_asn = ies.ie_asn; // 445 - tsch.c
tsch_join_priority = ies.ie_join_priority + 1; // 446 - tsch.c

se sincroniza el timeslot según la estructura definida en el estandar;
basicamente es pasar en ticks los tamaños de cada parte del timeslot en la estructura tsch_timing que es del tipo rtimer_clock_t
y está definida como

rtimer_clock_t tsch_timing[tsch_ts_elements_count]; // 111 - tsch.c

que va a recibir o la por defecto en caso que el EB no especifique nada o la contenida en el TSCH timeslot IE según 7.4.4.4

ies.ie_tsch_timeslot[i]

este tipo define una estructura con todos los campos del timeslot, que es del largo de tsch_ts_elements_count
for(i = 0; i < tsch_ts_elements_count; i++) { // desde 486 - tsch.c
if (ies.ie_tsch_timeslot_id == 0)
tsch_timing[i] = US_TO_RTIMERTICKS(tsch_default_timing_us[i]);
} else {
tsch_timing[i] = US_TO_RTIMERTICKS(ies.ie_tsch_timeslot[i]);
}
}

Una vez establecido el timing, se establece la hopping sequence;
Channel hopping IE (epígrafe 7.4.4.31)

if(ies.ie_channel_hopping_sequence_id == 0) // 495 - tsch.c
Se utiliza el TSCH_DEFAULT_HOPPING_SEQUENCE
else
Se parcea el que viene en el ie utilizado dos elementos
ies.ie_hopping_sequence_len
ies.ie_hopping_sequence_list

memcpy(tsch_hopping_sequence, ies.ie_hopping_sequence_list, ies.ie_hopping_sequence_len);
Hasta aquí el resto de los elementos de Channel hopping IE son ignorados

Se inicializa el divisor ASN
TSCH_ASN_DIVISOR_INIT(tsch_hopping_sequence_length, (sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE) or ies.ie_hopping_sequence_len))
El divisor es la variable tsch_hopping_sequence_length, tipo asn_divisor_t, estructura compuesta por el valor (val) y el remainder de la operacion (0x100000000 / val)
El problema es que el ASN tiene 5 bytes, y solo podemos trabajar hasta con 32 bit (4 bytes),
esta macro inicializa l aestructuctura que nos permite operaciones correctas de MOD en el 5to byte cuando fuera el caso

Crear el planificador, el cual por defecto lo toma del EB
Para identificar y configurar el planificador se utiliza el IE TSCH Slotframe and link (epígrafe 7.4.4.3)

#if TSCH_INIT_SCHEDULE_FROM_EB // 520 - tsch.c
Esto es una compilación condicional, optimo para ahorrar memoria de programa

primero verifica que los ies tengan información de planificación en el ie
ies.ie_tsch_slotframe_and_link.num_slotframes

Si es 0 y está habilidado (compilado) minimal para este nodo
tsch_schedule_create_minimal(); // 525 - tsch.c

tsch_schedule_create_minimal() implementado en el archivo tsch-schedule.c linea 403.
Crea el planificador minimo para 6TiSCH rfc 8180

Limpia el posible planificador que exista
tsch_schedule_remove_all_slotframes(); // 407 - tsch-schedule.c

Crea un único slotframe utilizando el largo por defecto

sf_min = tsch_schedule_add_slotframe(0, TSCH_SCHEDULE_DEFAULT_LENGTH); // 410 - tsch-schedule.c
donde el primer parámetro es el handle y TSCH_SCHEDULE_DEFAULT_LENGTH == 7, pero en conf del proyecto de ejemplo estápuesto a 3.

Incorpora un único link Tx|Rx|Shared además como time keeping y para advertissing
que no es descrito en minimal 6TiSCH pero se necesita para enviar EB

tsch_schedule_add_link(sf_min,
LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING, // 415 - tsch-schedule.c
LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
0, 0);
El 1 parámetro es el slotframe (tipo estructurura tsch_slotframe, el puntero a la estructura es devuelta por tsch_schedule_add_slotframe()),
el 2 es las opciones (es una máscara declarada en tsch-schedule.h, línea 77++),
el 3 es el tipo (LINK_TYPE_ADVERTISING, declarada en tsch-schedule.h, línea 87),
el 5 es la dirección del nodo remoto (tipo linkaddr_t),
el 6 uint16_t timeslot,
el 7 uint16_t channel_offset

Si no, se limpia el planificador actual (por si había alguno activo)
tsch_schedule_remove_all_slotframes(); // 531 - tsch.c
y se parsea la estructura de links con el contrnido de ies.ie_tsch_slotframe_and_link
se utilizan
int num_links = ies.ie_tsch_slotframe_and_link.num_links; // 533 - tsch.c

se crea el/los slotframes
struct tsch_slotframe *sf = tsch_schedule_add_slotframe( // 536 - tsch.c
ies.ie_tsch_slotframe_and_link.slotframe_handle,
ies.ie_tsch_slotframe_and_link.slotframe_size);

se rellenan los link del slotframe
for(i = 0; i < num_links; i++) { // 539 - tsch.c
tsch_schedule_add_link(sf,
ies.ie_tsch_slotframe_and_link.links[i].link_options,
LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
ies.ie_tsch_slotframe_and_link.links[i].timeslot, ies.ie_tsch_slotframe_and_link.links[i].channel_offset);
}

Luego de haber configurado el TSCH a partir de la información de los IEs,
se pasa actualizar las variables globales y de sincronismo si el vecino es adecuado.
para aceptar como vecino al nodo del que se ha recibido el EB, se verifica que
(tsch_join_priority < TSCH_MAX_JOIN_PRIORITY)
Si se cumple crea un puntero tipo struct tsch_neighbor
struct tsch_neighbor *n;

Y se adiciona a la lista de vecinos
n = tsch_queue_add_nbr((linkaddr_t *)&frame.src_addr); // 556 - tsch.c

Se establece el ID de la PAN
frame802154_set_pan_id(frame.src_pid); // 562 - tsch.c

Se sincroniza en base al timestamp del EB
tsch_slot_operation_sync(timestamp - tsch_timing[tsch_ts_tx_offset], &tsch_current_asn); // 565 - tsch.c



*/



/* Todos los cambios que se introduzcan en el código para mlbot deberán ser compilaciones condicionales, o sea,

#if TAL_COSA
....
....
#endif

*/