1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/openwsn/patches/03b-IPv6_icmpv6rpl.c.patch
2014-05-14 15:06:50 +02:00

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;
}