mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
ba3088c4bd
into separate patch files
370 lines
13 KiB
Diff
370 lines
13 KiB
Diff
*** stock_iot-lab_M3/openwsn/03b-IPv6/icmpv6rpl.c Thu Apr 24 11:01:36 2014
|
|
--- riot-openwsn-wip/openwsn/03b-IPv6/icmpv6rpl.c Thu Apr 24 16:55:54 2014
|
|
***************
|
|
*** 11,56 ****
|
|
#include "opentimers.h"
|
|
#include "IEEE802154E.h"
|
|
|
|
! //=========================== variables =======================================
|
|
|
|
! typedef struct {
|
|
! // admin
|
|
! bool busySending; ///< currently sending DIO/DAO.
|
|
! uint8_t DODAGIDFlagSet; ///< is DODAGID set already?
|
|
! // DIO-related
|
|
! icmpv6rpl_dio_ht dio; ///< pre-populated DIO packet.
|
|
! open_addr_t dioDestination; ///< IPv6 destination address for DIOs.
|
|
! uint16_t periodDIO; ///< duration, in ms, of a timerIdDIO timeout.
|
|
! opentimer_id_t timerIdDIO; ///< ID of the timer used to send DIOs.
|
|
! uint8_t delayDIO; ///< number of timerIdDIO events before actually sending a DIO.
|
|
! // DAO-related
|
|
! icmpv6rpl_dao_ht dao; ///< pre-populated DAO packet.
|
|
! icmpv6rpl_dao_transit_ht dao_transit; ///< pre-populated DAO "Transit Info" option header.
|
|
! icmpv6rpl_dao_target_ht dao_target; ///< pre-populated DAO "Transit Info" option header.
|
|
! opentimer_id_t timerIdDAO; ///< ID of the timer used to send DAOs.
|
|
! uint16_t periodDAO; ///< duration, in ms, of a timerIdDAO timeout.
|
|
! uint8_t delayDAO; ///< number of timerIdDIO events before actually sending a DAO.
|
|
! } icmpv6rpl_vars_t;
|
|
|
|
icmpv6rpl_vars_t icmpv6rpl_vars;
|
|
|
|
//=========================== prototypes ======================================
|
|
|
|
// DIO-related
|
|
! void icmpv6rpl_timer_DIO_cb();
|
|
! void icmpv6rpl_timer_DIO_task();
|
|
! void sendDIO();
|
|
// DAO-related
|
|
! void icmpv6rpl_timer_DAO_cb();
|
|
! void icmpv6rpl_timer_DAO_task();
|
|
! void sendDAO();
|
|
|
|
//=========================== public ==========================================
|
|
|
|
/**
|
|
\brief Initialize this module.
|
|
*/
|
|
! void icmpv6rpl_init() {
|
|
|
|
//===== reset local variables
|
|
memset(&icmpv6rpl_vars,0,sizeof(icmpv6rpl_vars_t));
|
|
--- 11,41 ----
|
|
#include "opentimers.h"
|
|
#include "IEEE802154E.h"
|
|
|
|
! #include "thread.h"
|
|
|
|
! //=========================== variables =======================================
|
|
|
|
icmpv6rpl_vars_t icmpv6rpl_vars;
|
|
+ //static char openwsn_icmpv6rpl_DAO_stack[KERNEL_CONF_STACKSIZE_MAIN];
|
|
+ //static char openwsn_icmpv6rpl_DIO_stack[KERNEL_CONF_STACKSIZE_MAIN];
|
|
|
|
//=========================== prototypes ======================================
|
|
|
|
// DIO-related
|
|
! void icmpv6rpl_timer_DIO_cb(void);
|
|
! void icmpv6rpl_timer_DIO_task(void);
|
|
! void sendDIO(void);
|
|
// DAO-related
|
|
! void icmpv6rpl_timer_DAO_cb(void);
|
|
! void icmpv6rpl_timer_DAO_task(void);
|
|
! void sendDAO(void);
|
|
|
|
//=========================== public ==========================================
|
|
|
|
/**
|
|
\brief Initialize this module.
|
|
*/
|
|
! void icmpv6rpl_init(void) {
|
|
|
|
//===== reset local variables
|
|
memset(&icmpv6rpl_vars,0,sizeof(icmpv6rpl_vars_t));
|
|
***************
|
|
*** 101,107 ****
|
|
D_DAO |
|
|
K_DAO;
|
|
icmpv6rpl_vars.dao.reserved = 0x00;
|
|
! icmpv6rpl_vars.dao.DAOSequance = 0x00;
|
|
// DODAGID: to be populated upon receiving DIO
|
|
|
|
icmpv6rpl_vars.dao_transit.type = OPTION_TRANSIT_INFORMATION_TYPE;
|
|
--- 86,92 ----
|
|
D_DAO |
|
|
K_DAO;
|
|
icmpv6rpl_vars.dao.reserved = 0x00;
|
|
! icmpv6rpl_vars.dao.DAOSequence = 0x00;
|
|
// DODAGID: to be populated upon receiving DIO
|
|
|
|
icmpv6rpl_vars.dao_transit.type = OPTION_TRANSIT_INFORMATION_TYPE;
|
|
***************
|
|
*** 133,145 ****
|
|
|
|
}
|
|
|
|
/**
|
|
\brief Called when DIO/DAO was sent.
|
|
|
|
\param[in] msg Pointer to the message just sent.
|
|
\param[in] error Outcome of the sending.
|
|
*/
|
|
! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, error_t error) {
|
|
|
|
// take ownership over that packet
|
|
msg->owner = COMPONENT_ICMPv6RPL;
|
|
--- 118,134 ----
|
|
|
|
}
|
|
|
|
+ uint8_t icmpv6rpl_getRPLIntanceID(void){
|
|
+ return icmpv6rpl_vars.dao.rplinstanceId;
|
|
+ }
|
|
+
|
|
/**
|
|
\brief Called when DIO/DAO was sent.
|
|
|
|
\param[in] msg Pointer to the message just sent.
|
|
\param[in] error Outcome of the sending.
|
|
*/
|
|
! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, owerror_t error) {
|
|
|
|
// take ownership over that packet
|
|
msg->owner = COMPONENT_ICMPv6RPL;
|
|
***************
|
|
*** 244,251 ****
|
|
\note This function is executed in interrupt context, and should only push a
|
|
task.
|
|
*/
|
|
! void icmpv6rpl_timer_DIO_cb() {
|
|
scheduler_push_task(icmpv6rpl_timer_DIO_task,TASKPRIO_RPL);
|
|
}
|
|
|
|
/**
|
|
--- 233,243 ----
|
|
\note This function is executed in interrupt context, and should only push a
|
|
task.
|
|
*/
|
|
! void icmpv6rpl_timer_DIO_cb(void) {
|
|
scheduler_push_task(icmpv6rpl_timer_DIO_task,TASKPRIO_RPL);
|
|
+ /*thread_create(openwsn_icmpv6rpl_DIO_stack, KERNEL_CONF_STACKSIZE_MAIN,
|
|
+ PRIORITY_OPENWSN_ICMPV6RPL, CREATE_STACKTEST,
|
|
+ icmpv6rpl_timer_DIO_task, "icmpv6rpl_timer_DIO_task");*/
|
|
}
|
|
|
|
/**
|
|
***************
|
|
*** 253,259 ****
|
|
|
|
\note This function is executed in task context, called by the scheduler.
|
|
*/
|
|
! void icmpv6rpl_timer_DIO_task() {
|
|
|
|
// update the delayDIO
|
|
icmpv6rpl_vars.delayDIO = (icmpv6rpl_vars.delayDIO+1)%5;
|
|
--- 245,251 ----
|
|
|
|
\note This function is executed in task context, called by the scheduler.
|
|
*/
|
|
! void icmpv6rpl_timer_DIO_task(void) {
|
|
|
|
// update the delayDIO
|
|
icmpv6rpl_vars.delayDIO = (icmpv6rpl_vars.delayDIO+1)%5;
|
|
***************
|
|
*** 279,285 ****
|
|
/**
|
|
\brief Prepare and a send a RPL DIO.
|
|
*/
|
|
! void sendDIO() {
|
|
OpenQueueEntry_t* msg;
|
|
|
|
// stop if I'm not sync'ed
|
|
--- 271,277 ----
|
|
/**
|
|
\brief Prepare and a send a RPL DIO.
|
|
*/
|
|
! void sendDIO(void) {
|
|
OpenQueueEntry_t* msg;
|
|
|
|
// stop if I'm not sync'ed
|
|
***************
|
|
*** 370,377 ****
|
|
\note This function is executed in interrupt context, and should only push a
|
|
task.
|
|
*/
|
|
! void icmpv6rpl_timer_DAO_cb() {
|
|
! scheduler_push_task(icmpv6rpl_timer_DAO_task,TASKPRIO_RPL);
|
|
}
|
|
|
|
/**
|
|
--- 362,372 ----
|
|
\note This function is executed in interrupt context, and should only push a
|
|
task.
|
|
*/
|
|
! void icmpv6rpl_timer_DAO_cb(void) {
|
|
! scheduler_push_task(icmpv6rpl_timer_DAO_task,TASKPRIO_RPL);
|
|
! /*thread_create(openwsn_icmpv6rpl_DAO_stack, KERNEL_CONF_STACKSIZE_MAIN,
|
|
! PRIORITY_OPENWSN_ICMPV6RPL, CREATE_STACKTEST,
|
|
! icmpv6rpl_timer_DAO_task, "icmpv6rpl_timer_DAO_task");*/
|
|
}
|
|
|
|
/**
|
|
***************
|
|
*** 379,385 ****
|
|
|
|
\note This function is executed in task context, called by the scheduler.
|
|
*/
|
|
! void icmpv6rpl_timer_DAO_task() {
|
|
|
|
// update the delayDAO
|
|
icmpv6rpl_vars.delayDAO = (icmpv6rpl_vars.delayDAO+1)%5;
|
|
--- 374,380 ----
|
|
|
|
\note This function is executed in task context, called by the scheduler.
|
|
*/
|
|
! void icmpv6rpl_timer_DAO_task(void) {
|
|
|
|
// update the delayDAO
|
|
icmpv6rpl_vars.delayDAO = (icmpv6rpl_vars.delayDAO+1)%5;
|
|
***************
|
|
*** 405,415 ****
|
|
/**
|
|
\brief Prepare and a send a RPL DAO.
|
|
*/
|
|
! void sendDAO() {
|
|
OpenQueueEntry_t* msg; // pointer to DAO messages
|
|
uint8_t nbrIdx; // running neighbor index
|
|
uint8_t numTransitParents,numTargetParents; // the number of parents indicated in transit option
|
|
open_addr_t address;
|
|
|
|
if (ieee154e_isSynch()==FALSE) {
|
|
// I'm not sync'ed
|
|
--- 400,411 ----
|
|
/**
|
|
\brief Prepare and a send a RPL DAO.
|
|
*/
|
|
! void sendDAO(void) {
|
|
OpenQueueEntry_t* msg; // pointer to DAO messages
|
|
uint8_t nbrIdx; // running neighbor index
|
|
uint8_t numTransitParents,numTargetParents; // the number of parents indicated in transit option
|
|
open_addr_t address;
|
|
+ open_addr_t* prefix;
|
|
|
|
if (ieee154e_isSynch()==FALSE) {
|
|
// I'm not sync'ed
|
|
***************
|
|
*** 464,499 ****
|
|
|
|
//===== fill in packet
|
|
|
|
! //=== transit option -- from RFC 6550, page 55 - 1 transit information header per parent is required.
|
|
! numTransitParents = 0;
|
|
! for (nbrIdx=0;nbrIdx<MAXNUMNEIGHBORS;nbrIdx++) {
|
|
! if ((neighbors_isNeighborWithLowerDAGrank(nbrIdx))==TRUE) {
|
|
! // this neighbor is of lower DAGrank as I am
|
|
!
|
|
! // write it's address in DAO
|
|
! //packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b);
|
|
! neighbors_getNeighbor(&address,ADDR_64B,nbrIdx);
|
|
! packetfunctions_writeAddress(msg,&address,BIG_ENDIAN);
|
|
!
|
|
!
|
|
! // update transit info fields
|
|
! //size of the whole option in bytes.
|
|
! icmpv6rpl_vars.dao_transit.optionLength = LENGTH_ADDR64b + sizeof(icmpv6rpl_dao_transit_ht);
|
|
! icmpv6rpl_vars.dao_transit.PathControl=0; //todo. this is to set the preference of this parent.
|
|
! icmpv6rpl_vars.dao_transit.type=OPTION_TRANSIT_INFORMATION_TYPE;
|
|
|
|
! // write transit info in packet
|
|
! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_transit_ht));
|
|
! memcpy(
|
|
! ((icmpv6rpl_dao_transit_ht*)(msg->payload)),
|
|
! &(icmpv6rpl_vars.dao_transit),
|
|
! sizeof(icmpv6rpl_dao_transit_ht)
|
|
! );
|
|
!
|
|
! // remember I found it
|
|
! numTransitParents++;
|
|
! }
|
|
! }
|
|
|
|
//target information is required. RFC 6550 page 55.
|
|
/*
|
|
--- 460,490 ----
|
|
|
|
//===== fill in packet
|
|
|
|
! //NOTE: limit to preferrred parent only the number of DAO transit addresses to send
|
|
!
|
|
! //=== transit option -- from RFC 6550, page 55 - 1 transit information header per parent is required.
|
|
! //getting only preferred parent as transit
|
|
! numTransitParents=0;
|
|
! neighbors_getPreferredParentEui64(&address);
|
|
! packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN);
|
|
! prefix=idmanager_getMyID(ADDR_PREFIX);
|
|
! packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN);
|
|
! // update transit info fields
|
|
! // from rfc6550 p.55 -- Variable, depending on whether or not the DODAG ParentAddress subfield is present.
|
|
! // poipoi xv: it is not very clear if this includes all fields in the header. or as target info 2 bytes are removed.
|
|
! // using the same pattern as in target information.
|
|
! icmpv6rpl_vars.dao_transit.optionLength = LENGTH_ADDR128b + sizeof(icmpv6rpl_dao_transit_ht)-2;
|
|
! icmpv6rpl_vars.dao_transit.PathControl=0; //todo. this is to set the preference of this parent.
|
|
! icmpv6rpl_vars.dao_transit.type=OPTION_TRANSIT_INFORMATION_TYPE;
|
|
|
|
! // write transit info in packet
|
|
! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_transit_ht));
|
|
! memcpy(
|
|
! ((icmpv6rpl_dao_transit_ht*)(msg->payload)),
|
|
! &(icmpv6rpl_vars.dao_transit),
|
|
! sizeof(icmpv6rpl_dao_transit_ht)
|
|
! );
|
|
! numTransitParents++;
|
|
|
|
//target information is required. RFC 6550 page 55.
|
|
/*
|
|
***************
|
|
*** 506,519 ****
|
|
// this neighbor is of higher DAGrank as I am. so it is my child
|
|
|
|
// write it's address in DAO RFC6550 page 80 check point 1.
|
|
! neighbors_getNeighbor(&address,ADDR_64B,nbrIdx);
|
|
! packetfunctions_writeAddress(msg,&address,BIG_ENDIAN);
|
|
|
|
// update target info fields
|
|
! icmpv6rpl_vars.dao_target.optionLength = LENGTH_ADDR64b + sizeof(icmpv6rpl_dao_target_ht);
|
|
icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE;
|
|
icmpv6rpl_vars.dao_target.flags = 0; //must be 0
|
|
! icmpv6rpl_vars.dao_target.prefixLength = 0; //no prefix.
|
|
|
|
// write transit info in packet
|
|
packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_target_ht));
|
|
--- 497,514 ----
|
|
// this neighbor is of higher DAGrank as I am. so it is my child
|
|
|
|
// write it's address in DAO RFC6550 page 80 check point 1.
|
|
! neighbors_getNeighbor(&address,ADDR_64B,nbrIdx);
|
|
! packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN);
|
|
! prefix=idmanager_getMyID(ADDR_PREFIX);
|
|
! packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN);
|
|
|
|
// update target info fields
|
|
! // from rfc6550 p.55 -- Variable, length of the option in octets excluding the Type and Length fields.
|
|
! // poipoi xv: assuming that type and length fields refer to the 2 first bytes of the header
|
|
! icmpv6rpl_vars.dao_target.optionLength = LENGTH_ADDR128b +sizeof(icmpv6rpl_dao_target_ht) - 2; //no header type and length
|
|
icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE;
|
|
icmpv6rpl_vars.dao_target.flags = 0; //must be 0
|
|
! icmpv6rpl_vars.dao_target.prefixLength = 128; //128 leading bits -- full address.
|
|
|
|
// write transit info in packet
|
|
packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_target_ht));
|
|
***************
|
|
*** 526,531 ****
|
|
--- 521,530 ----
|
|
// remember I found it
|
|
numTargetParents++;
|
|
}
|
|
+ //limit to MAX_TARGET_PARENTS the number of DAO target addresses to send
|
|
+ //section 8.2.1 pag 67 RFC6550 -- using a subset
|
|
+ // poipoi TODO base selection on ETX rather than first X.
|
|
+ if (numTargetParents>=MAX_TARGET_PARENTS) break;
|
|
}
|