From c6de59cb286e177ae3344255e013ddd6acb7de68 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Wed, 15 Jan 2014 14:02:28 +0100 Subject: [PATCH 1/8] added possibilty to import openwsn stack as external module --- pkg/openwsn/Makefile | 44 + pkg/openwsn/Makefile.in | 9 + pkg/openwsn/patch.txt | 38412 +++++++++++++++++++++++++++++ pkg/openwsn/structure_changes.sh | 67 + 4 files changed, 38532 insertions(+) create mode 100644 pkg/openwsn/Makefile create mode 100644 pkg/openwsn/Makefile.in create mode 100644 pkg/openwsn/patch.txt create mode 100755 pkg/openwsn/structure_changes.sh diff --git a/pkg/openwsn/Makefile b/pkg/openwsn/Makefile new file mode 100644 index 000000000000..738e8069d2bc --- /dev/null +++ b/pkg/openwsn/Makefile @@ -0,0 +1,44 @@ +PKG_NAME=RB +PKG_URL=https://github.com/openwsn-berkeley/openwsn-fw/archive +PKG_VERSION=1.4 +PKG_EXT=zip + +FETCH=$(shell which wget &> /dev/null && echo "wget" || echo "curl") +#UNPACK=tar -xvf +UNPACK=unzip + +ifneq ($(RIOTBOARD),) +#include $(RIOTBOARD)/Makefile.base +include $(RIOTBOARD)/$(BOARD)/Makefile.include +endif + +.PHONY: all clean patch reset + +all: patch + make -C $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) + +patch: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile + # Dependancy might be changed accordingly though we think the Makefile + # will be the first thing you want to change + # + # Here might not happen anything besides dependancy checks + +$(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/ + # Here you apply your patch. + cd $< && sh ../structure_changes.sh + cd $< && patch -p0 -i ../patch.txt + +$(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) + $(UNPACK) $< -d $(PKG_NAME)-$(PKG_VERSION) + +$(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT): + # Get PKG_VERSION of package from PKG_URL + @$(FETCH) -O $@ $(PKG_URL)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) || true + +clean:: + # Reset package to checkout state. + rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) && \ + make $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile + +clean:: + rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) diff --git a/pkg/openwsn/Makefile.in b/pkg/openwsn/Makefile.in new file mode 100644 index 000000000000..3c983301a005 --- /dev/null +++ b/pkg/openwsn/Makefile.in @@ -0,0 +1,9 @@ +DIRS = +DIRS += openwsn + +all: $(BINDIR)$(MODULE) + @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; + +# remove compilation products +clean:: + @for i in $(DIRS) ; do "$(MAKE)" -C $$i clean ; done ; diff --git a/pkg/openwsn/patch.txt b/pkg/openwsn/patch.txt new file mode 100644 index 000000000000..f0a98980326b --- /dev/null +++ b/pkg/openwsn/patch.txt @@ -0,0 +1,38412 @@ +diff -crB openwsn/02a-MAClow/IEEE802154.c ../../../sys/net/openwsn/02a-MAClow/IEEE802154.c +*** openwsn/02a-MAClow/IEEE802154.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/IEEE802154.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,220 **** +! #include "openwsn.h" +! #include "IEEE802154.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "topology.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! /** +! \brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet. +! +! Note that we are writing the field from the end of the header to the beginning. +! +! \param msg [in,out] The message to append the header to. +! \param frameType [in] Type of IEEE802.15.4 frame. +! \param securityEnabled [in] Is security enabled on this frame? +! \param nextHop [in] Address of the next hop +! */ +! void ieee802154_prependHeader(OpenQueueEntry_t* msg, +! uint8_t frameType, +! bool securityEnabled, +! uint8_t sequenceNumber, +! open_addr_t* nextHop) { +! uint8_t temp_8b; +! +! // previousHop address (always 64-bit) +! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),LITTLE_ENDIAN); +! // nextHop address +! if (packetfunctions_isBroadcastMulticast(nextHop)) { +! //broadcast address is always 16-bit +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = 0xFF; +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = 0xFF; +! } else { +! switch (nextHop->type) { +! case ADDR_16B: +! case ADDR_64B: +! packetfunctions_writeAddress(msg,nextHop,LITTLE_ENDIAN); +! break; +! default: +! openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)nextHop->type, +! (errorparameter_t)1); +! } +! +! } +! // destpan +! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),LITTLE_ENDIAN); +! //dsn +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = sequenceNumber; +! //fcf (2nd byte) +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! temp_8b = 0; +! if (packetfunctions_isBroadcastMulticast(nextHop)) { +! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; +! } else { +! switch (nextHop->type) { +! case ADDR_16B: +! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; +! break; +! case ADDR_64B: +! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_DEST_ADDR_MODE; +! break; +! // no need for a default, since it would have been caught above. +! } +! } +! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_SRC_ADDR_MODE; +! *((uint8_t*)(msg->payload)) = temp_8b; +! //fcf (1st byte) +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! temp_8b = 0; +! temp_8b |= frameType << IEEE154_FCF_FRAME_TYPE; +! temp_8b |= securityEnabled << IEEE154_FCF_SECURITY_ENABLED; +! temp_8b |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING; +! if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) { +! temp_8b |= IEEE154_ACK_NO_ACK_REQ << IEEE154_FCF_ACK_REQ; +! } else { +! temp_8b |= IEEE154_ACK_YES_ACK_REQ << IEEE154_FCF_ACK_REQ; +! } +! temp_8b |= IEEE154_PANID_COMPRESSED << IEEE154_FCF_INTRAPAN; +! *((uint8_t*)(msg->payload)) = temp_8b; +! } +! +! /** +! \brief Retreieve the IEEE802.15.4 MAC header from a (just received) packet. +! +! Note We are writing the fields from the begnning of the header to the end. +! +! \param msg [in,out] The message just received. +! \param ieee802514_header [out] The internal header to write the data to. +! */ +! void ieee802154_retrieveHeader(OpenQueueEntry_t* msg, +! ieee802154_header_iht* ieee802514_header) { +! uint8_t temp_8b; +! +! // by default, let's assume the header is not valid, in case we leave this +! // function because the packet ends up being shorter than the header. +! ieee802514_header->valid=FALSE; +! +! ieee802514_header->headerLength = 0; +! // fcf, byte 1 +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); +! ieee802514_header->frameType = (temp_8b >> IEEE154_FCF_FRAME_TYPE ) & 0x07;//3b +! ieee802514_header->securityEnabled = (temp_8b >> IEEE154_FCF_SECURITY_ENABLED) & 0x01;//1b +! ieee802514_header->framePending = (temp_8b >> IEEE154_FCF_FRAME_PENDING ) & 0x01;//1b +! ieee802514_header->ackRequested = (temp_8b >> IEEE154_FCF_ACK_REQ ) & 0x01;//1b +! ieee802514_header->panIDCompression = (temp_8b >> IEEE154_FCF_INTRAPAN ) & 0x01;//1b +! ieee802514_header->headerLength += 1; +! // fcf, byte 2 +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); +! switch ( (temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03 ) { +! case IEEE154_ADDR_NONE: +! ieee802514_header->dest.type = ADDR_NONE; +! break; +! case IEEE154_ADDR_SHORT: +! ieee802514_header->dest.type = ADDR_16B; +! break; +! case IEEE154_ADDR_EXT: +! ieee802514_header->dest.type = ADDR_64B; +! break; +! default: +! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, +! (errorparameter_t)1, +! (errorparameter_t)(temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03); +! return; // this is an invalid packet, return +! } +! switch ( (temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03 ) { +! case IEEE154_ADDR_NONE: +! ieee802514_header->src.type = ADDR_NONE; +! break; +! case IEEE154_ADDR_SHORT: +! ieee802514_header->src.type = ADDR_16B; +! break; +! case IEEE154_ADDR_EXT: +! ieee802514_header->src.type = ADDR_64B; +! break; +! default: +! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, +! (errorparameter_t)2, +! (errorparameter_t)(temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03); +! return; // this is an invalid packet, return +! } +! ieee802514_header->headerLength += 1; +! // sequenceNumber +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! ieee802514_header->dsn = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); +! ieee802514_header->headerLength += 1; +! // panID +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_PANID, +! &ieee802514_header->panid, +! LITTLE_ENDIAN); +! ieee802514_header->headerLength += 2; +! // dest +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! switch (ieee802514_header->dest.type) { +! case ADDR_NONE: +! break; +! case ADDR_16B: +! packetfunctions_readAddress( +! ((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_16B, +! &ieee802514_header->dest, +! LITTLE_ENDIAN +! ); +! ieee802514_header->headerLength += 2; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! case ADDR_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_64B, +! &ieee802514_header->dest, +! LITTLE_ENDIAN); +! ieee802514_header->headerLength += 8; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! // no need for a default, since case would have been caught above +! } +! //src +! switch (ieee802514_header->src.type) { +! case ADDR_NONE: +! break; +! case ADDR_16B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_16B, +! &ieee802514_header->src, +! LITTLE_ENDIAN); +! ieee802514_header->headerLength += 2; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! case ADDR_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_64B, +! &ieee802514_header->src, +! LITTLE_ENDIAN); +! ieee802514_header->headerLength += 8; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! // no need for a default, since case would have been caught above +! } +! // apply topology filter +! if (topology_isAcceptablePacket(ieee802514_header)==FALSE) { +! // the topology filter does accept this packet, return +! return; +! } +! // if you reach this, the header is valid +! ieee802514_header->valid=TRUE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,244 ---- +! #include "openwsn.h" +! #include "IEEE802154.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "topology.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! /** +! \brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet. +! +! Note that we are writing the field from the end of the header to the beginning. +! +! \param[in,out] msg The message to append the header to. +! \param[in] frameType Type of IEEE802.15.4 frame. +! \param[in] ielistpresent Is the IE list present¿ +! \param[in] frameVersion IEEE802.15.4 frame version. +! \param[in] securityEnabled Is security enabled on this frame? +! \param[in] sequenceNumber Sequence number of this frame. +! \param[in] nextHop Address of the next hop +! */ +! void ieee802154_prependHeader(OpenQueueEntry_t* msg, +! uint8_t frameType, +! uint8_t ielistpresent, +! uint8_t frameversion, +! bool securityEnabled, +! uint8_t sequenceNumber, +! open_addr_t* nextHop) { +! uint8_t temp_8b; +! +! //General IEs here (those that are carried in all packets) -- None by now. +! +! // previousHop address (always 64-bit) +! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),OW_LITTLE_ENDIAN); +! // nextHop address +! if (packetfunctions_isBroadcastMulticast(nextHop)) { +! //broadcast address is always 16-bit +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = 0xFF; +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = 0xFF; +! } else { +! switch (nextHop->type) { +! case ADDR_16B: +! case ADDR_64B: +! packetfunctions_writeAddress(msg,nextHop,OW_LITTLE_ENDIAN); +! break; +! default: +! openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)nextHop->type, +! (errorparameter_t)1); +! } +! +! } +! // destpan +! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),OW_LITTLE_ENDIAN); +! //dsn +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = sequenceNumber; +! //fcf (2nd byte) +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! temp_8b = 0; +! if (packetfunctions_isBroadcastMulticast(nextHop)) { +! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; +! } else { +! switch (nextHop->type) { +! case ADDR_16B: +! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; +! break; +! case ADDR_64B: +! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_DEST_ADDR_MODE; +! break; +! // no need for a default, since it would have been caught above. +! } +! } +! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_SRC_ADDR_MODE; +! //poipoi xv IE list present +! temp_8b |= ielistpresent << IEEE154_FCF_IELIST_PRESENT; +! temp_8b |= frameversion << IEEE154_FCF_FRAME_VERSION; +! +! *((uint8_t*)(msg->payload)) = temp_8b; +! //fcf (1st byte) +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! temp_8b = 0; +! temp_8b |= frameType << IEEE154_FCF_FRAME_TYPE; +! temp_8b |= securityEnabled << IEEE154_FCF_SECURITY_ENABLED; +! temp_8b |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING; +! if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) { +! temp_8b |= IEEE154_ACK_NO_ACK_REQ << IEEE154_FCF_ACK_REQ; +! } else { +! temp_8b |= IEEE154_ACK_YES_ACK_REQ << IEEE154_FCF_ACK_REQ; +! } +! temp_8b |= IEEE154_PANID_COMPRESSED << IEEE154_FCF_INTRAPAN; +! *((uint8_t*)(msg->payload)) = temp_8b; +! } +! +! /** +! \brief Retreieve the IEEE802.15.4 MAC header from a (just received) packet. +! +! Note We are writing the fields from the begnning of the header to the end. +! +! \param[in,out] msg The message just received. +! \param[out] ieee802514_header The internal header to write the data to. +! */ +! void ieee802154_retrieveHeader(OpenQueueEntry_t* msg, +! ieee802154_header_iht* ieee802514_header) { +! uint8_t temp_8b; +! +! // by default, let's assume the header is not valid, in case we leave this +! // function because the packet ends up being shorter than the header. +! ieee802514_header->valid=FALSE; +! +! ieee802514_header->headerLength = 0; +! // fcf, byte 1 +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); +! ieee802514_header->frameType = (temp_8b >> IEEE154_FCF_FRAME_TYPE ) & 0x07;//3b +! ieee802514_header->securityEnabled = (temp_8b >> IEEE154_FCF_SECURITY_ENABLED) & 0x01;//1b +! ieee802514_header->framePending = (temp_8b >> IEEE154_FCF_FRAME_PENDING ) & 0x01;//1b +! ieee802514_header->ackRequested = (temp_8b >> IEEE154_FCF_ACK_REQ ) & 0x01;//1b +! ieee802514_header->panIDCompression = (temp_8b >> IEEE154_FCF_INTRAPAN ) & 0x01;//1b +! ieee802514_header->headerLength += 1; +! // fcf, byte 2 +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); +! //poipoi xv IE list present +! ieee802514_header->ieListPresent = (temp_8b >> IEEE154_FCF_IELIST_PRESENT ) & 0x01;//1b +! ieee802514_header->frameVersion = (temp_8b >> IEEE154_FCF_FRAME_VERSION ) & 0x03;//2b +! +! if (ieee802514_header->ieListPresent==TRUE && ieee802514_header->frameVersion!=IEEE154_FRAMEVERSION){ +! return; //invalid packet accordint to p.64 IEEE15.4e +! } +! +! switch ( (temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03 ) { +! case IEEE154_ADDR_NONE: +! ieee802514_header->dest.type = ADDR_NONE; +! break; +! case IEEE154_ADDR_SHORT: +! ieee802514_header->dest.type = ADDR_16B; +! break; +! case IEEE154_ADDR_EXT: +! ieee802514_header->dest.type = ADDR_64B; +! break; +! default: +! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, +! (errorparameter_t)1, +! (errorparameter_t)(temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03); +! return; // this is an invalid packet, return +! } +! switch ( (temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03 ) { +! case IEEE154_ADDR_NONE: +! ieee802514_header->src.type = ADDR_NONE; +! break; +! case IEEE154_ADDR_SHORT: +! ieee802514_header->src.type = ADDR_16B; +! break; +! case IEEE154_ADDR_EXT: +! ieee802514_header->src.type = ADDR_64B; +! break; +! default: +! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, +! (errorparameter_t)2, +! (errorparameter_t)(temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03); +! return; // this is an invalid packet, return +! } +! ieee802514_header->headerLength += 1; +! // sequenceNumber +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! ieee802514_header->dsn = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); +! ieee802514_header->headerLength += 1; +! // panID +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_PANID, +! &ieee802514_header->panid, +! OW_LITTLE_ENDIAN); +! ieee802514_header->headerLength += 2; +! // dest +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! switch (ieee802514_header->dest.type) { +! case ADDR_NONE: +! break; +! case ADDR_16B: +! packetfunctions_readAddress( +! ((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_16B, +! &ieee802514_header->dest, +! OW_LITTLE_ENDIAN +! ); +! ieee802514_header->headerLength += 2; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! case ADDR_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_64B, +! &ieee802514_header->dest, +! OW_LITTLE_ENDIAN); +! ieee802514_header->headerLength += 8; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! // no need for a default, since case would have been caught above +! } +! //src +! switch (ieee802514_header->src.type) { +! case ADDR_NONE: +! break; +! case ADDR_16B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_16B, +! &ieee802514_header->src, +! OW_LITTLE_ENDIAN); +! ieee802514_header->headerLength += 2; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! case ADDR_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), +! ADDR_64B, +! &ieee802514_header->src, +! OW_LITTLE_ENDIAN); +! ieee802514_header->headerLength += 8; +! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! +! break; +! // no need for a default, since case would have been caught above +! } +! +! if (ieee802514_header->ieListPresent==TRUE && ieee802514_header->frameVersion!=IEEE154_FRAMEVERSION){ +! return; //invalid packet accordint to p.64 IEEE15.4e +! } +! +! // apply topology filter +! if (topology_isAcceptablePacket(ieee802514_header)==FALSE) { +! // the topology filter does accept this packet, return +! return; +! } +! // if you reach this, the header is valid +! ieee802514_header->valid=TRUE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/02a-MAClow/IEEE802154.h ../../../sys/net/openwsn/02a-MAClow/IEEE802154.h +*** openwsn/02a-MAClow/IEEE802154.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/IEEE802154.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,94 **** +! #ifndef __IEEE802154_H +! #define __IEEE802154_H +! +! /** +! \addtogroup helpers +! \{ +! \addtogroup IEEE802154 +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! enum IEEE802154_fcf_enums { +! IEEE154_FCF_FRAME_TYPE = 0, +! IEEE154_FCF_SECURITY_ENABLED = 3, +! IEEE154_FCF_FRAME_PENDING = 4, +! IEEE154_FCF_ACK_REQ = 5, +! IEEE154_FCF_INTRAPAN = 6, +! IEEE154_FCF_DEST_ADDR_MODE = 2, +! IEEE154_FCF_SRC_ADDR_MODE = 6, +! }; +! +! enum IEEE802154_fcf_type_enums { +! IEEE154_TYPE_BEACON = 0, +! IEEE154_TYPE_DATA = 1, +! IEEE154_TYPE_ACK = 2, +! IEEE154_TYPE_CMD = 3, +! IEEE154_TYPE_UNDEFINED = 5, +! }; +! +! enum IEEE802154_fcf_sec_enums { +! IEEE154_SEC_NO_SECURITY = 0, +! IEEE154_SEC_YES_SECURITY = 1, +! }; +! +! enum IEEE802154_fcf_pending_enums { +! IEEE154_PENDING_NO_FRAMEPENDING = 0, +! IEEE154_PENDING_YES_FRAMEPENDING = 1, +! }; +! +! enum IEEE802154_fcf_ack_enums { +! IEEE154_ACK_NO_ACK_REQ = 0, +! IEEE154_ACK_YES_ACK_REQ = 1, +! }; +! +! enum IEEE802154_fcf_panid_enums { +! IEEE154_PANID_UNCOMPRESSED = 0, +! IEEE154_PANID_COMPRESSED = 1, +! }; +! +! enum IEEE802154_fcf_addr_mode_enums { +! IEEE154_ADDR_NONE = 0, +! IEEE154_ADDR_SHORT = 2, +! IEEE154_ADDR_EXT = 3, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! bool valid; +! uint8_t headerLength; //including the length field +! uint8_t frameType; +! bool securityEnabled; +! bool framePending; +! bool ackRequested; +! bool panIDCompression; +! uint8_t dsn; +! open_addr_t panid; +! open_addr_t dest; +! open_addr_t src; +! } ieee802154_header_iht; //iht for "internal header type" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== prototypes ====================================== +! +! void ieee802154_prependHeader (OpenQueueEntry_t* msg, +! uint8_t frameType, +! bool securityEnabled, +! uint8_t sequenceNumber, +! open_addr_t* nextHop); +! void ieee802154_retrieveHeader (OpenQueueEntry_t* msg, +! ieee802154_header_iht* ieee802514_header); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,113 ---- +! #ifndef __IEEE802154_H +! #define __IEEE802154_H +! +! /** +! \addtogroup MAClow +! \{ +! \addtogroup IEEE802154 +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! enum IEEE802154_fcf_enums { +! IEEE154_FCF_FRAME_TYPE = 0, +! IEEE154_FCF_SECURITY_ENABLED = 3, +! IEEE154_FCF_FRAME_PENDING = 4, +! IEEE154_FCF_ACK_REQ = 5, +! IEEE154_FCF_INTRAPAN = 6, +! IEEE154_FCF_IELIST_PRESENT = 1, +! IEEE154_FCF_DEST_ADDR_MODE = 2, +! IEEE154_FCF_FRAME_VERSION = 4, +! IEEE154_FCF_SRC_ADDR_MODE = 6, +! }; +! +! +! enum IEEE802154_fcf_frameversion_enums { +! IEEE154_FRAMEVERSION_2003 = 0, //ieee154-2003 +! IEEE154_FRAMEVERSION_2006 = 1, //ieee154-2006 +! IEEE154_FRAMEVERSION = 2, //ieee154 +! }; +! +! enum IEEE802154_fcf_type_enums { +! IEEE154_TYPE_BEACON = 0, +! IEEE154_TYPE_DATA = 1, +! IEEE154_TYPE_ACK = 2, +! IEEE154_TYPE_CMD = 3, +! IEEE154_TYPE_UNDEFINED = 5, +! }; +! +! enum IEEE802154_fcf_sec_enums { +! IEEE154_SEC_NO_SECURITY = 0, +! IEEE154_SEC_YES_SECURITY = 1, +! }; +! +! enum IEEE802154_fcf_ielist_enums { +! IEEE154_IELIST_NO = 0, +! IEEE154_IELIST_YES = 1, +! }; +! +! enum IEEE802154_fcf_pending_enums { +! IEEE154_PENDING_NO_FRAMEPENDING = 0, +! IEEE154_PENDING_YES_FRAMEPENDING = 1, +! }; +! +! enum IEEE802154_fcf_ack_enums { +! IEEE154_ACK_NO_ACK_REQ = 0, +! IEEE154_ACK_YES_ACK_REQ = 1, +! }; +! +! enum IEEE802154_fcf_panid_enums { +! IEEE154_PANID_UNCOMPRESSED = 0, +! IEEE154_PANID_COMPRESSED = 1, +! }; +! +! enum IEEE802154_fcf_addr_mode_enums { +! IEEE154_ADDR_NONE = 0, +! IEEE154_ADDR_SHORT = 2, +! IEEE154_ADDR_EXT = 3, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! bool valid; +! uint8_t headerLength; //including the length field +! uint8_t frameType; +! bool securityEnabled; +! bool framePending; +! bool ackRequested; +! bool panIDCompression; +! bool ieListPresent; +! uint8_t frameVersion; +! uint8_t dsn; +! open_addr_t panid; +! open_addr_t dest; +! open_addr_t src; +! } ieee802154_header_iht; //iht for "internal header type" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== prototypes ====================================== +! +! void ieee802154_prependHeader(OpenQueueEntry_t* msg, +! uint8_t frameType, +! uint8_t ielistpresent, +! uint8_t frameversion, +! bool securityEnabled, +! uint8_t sequenceNumber, +! open_addr_t* nextHop); +! +! void ieee802154_retrieveHeader (OpenQueueEntry_t* msg, +! ieee802154_header_iht* ieee802514_header); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/02a-MAClow/IEEE802154E.c ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.c +*** openwsn/02a-MAClow/IEEE802154E.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,1908 **** +! #include "openwsn.h" +! #include "IEEE802154E.h" +! #include "radio.h" +! #include "radiotimer.h" +! #include "IEEE802154.h" +! #include "openqueue.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "schedule.h" +! #include "packetfunctions.h" +! #include "scheduler.h" +! #include "leds.h" +! #include "neighbors.h" +! #include "debugpins.h" +! #include "res.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! // misc +! asn_t asn; // current absolute slot number +! slotOffset_t slotOffset; // current slot offset +! slotOffset_t nextActiveSlotOffset; // next active slot offset +! PORT_TIMER_WIDTH deSyncTimeout; // how many slots left before looses sync +! bool isSync; // TRUE iff mote is synchronized to network +! // as shown on the chronogram +! ieee154e_state_t state; // state of the FSM +! OpenQueueEntry_t* dataToSend; // pointer to the data to send +! OpenQueueEntry_t* dataReceived; // pointer to the data received +! OpenQueueEntry_t* ackToSend; // pointer to the ack to send +! OpenQueueEntry_t* ackReceived; // pointer to the ack received +! PORT_TIMER_WIDTH lastCapturedTime; // last captured time +! PORT_TIMER_WIDTH syncCapturedTime; // captured time used to sync +! //channel hopping +! uint8_t freq; // frequency of the current slot +! uint8_t asnOffset; // offset inside the frame +! } ieee154e_vars_t; +! +! ieee154e_vars_t ieee154e_vars; +! +! typedef struct { +! PORT_TIMER_WIDTH num_newSlot; +! PORT_TIMER_WIDTH num_timer; +! PORT_TIMER_WIDTH num_startOfFrame; +! PORT_TIMER_WIDTH num_endOfFrame; +! } ieee154e_dbg_t; +! +! ieee154e_dbg_t ieee154e_dbg; +! +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t numSyncPkt; // how many times synchronized on a non-ACK packet +! uint8_t numSyncAck; // how many times synchronized on an ACK +! PORT_SIGNED_INT_WIDTH minCorrection; // minimum time correction +! PORT_SIGNED_INT_WIDTH maxCorrection; // maximum time correction +! uint8_t numDeSync; // number of times a desync happened +! } ieee154e_stats_t; +! PRAGMA(pack()); +! +! ieee154e_stats_t ieee154e_stats; +! +! //=========================== prototypes ====================================== +! +! // SYNCHRONIZING +! void activity_synchronize_newSlot(); +! void activity_synchronize_startOfFrame(PORT_TIMER_WIDTH capturedTime); +! void activity_synchronize_endOfFrame(PORT_TIMER_WIDTH capturedTime); +! // TX +! void activity_ti1ORri1(); +! void activity_ti2(); +! void activity_tie1(); +! void activity_ti3(); +! void activity_tie2(); +! void activity_ti4(PORT_TIMER_WIDTH capturedTime); +! void activity_tie3(); +! void activity_ti5(PORT_TIMER_WIDTH capturedTime); +! void activity_ti6(); +! void activity_tie4(); +! void activity_ti7(); +! void activity_tie5(); +! void activity_ti8(PORT_TIMER_WIDTH capturedTime); +! void activity_tie6(); +! void activity_ti9(PORT_TIMER_WIDTH capturedTime); +! // RX +! void activity_ri2(); +! void activity_rie1(); +! void activity_ri3(); +! void activity_rie2(); +! void activity_ri4(PORT_TIMER_WIDTH capturedTime); +! void activity_rie3(); +! void activity_ri5(PORT_TIMER_WIDTH capturedTime); +! void activity_ri6(); +! void activity_rie4(); +! void activity_ri7(); +! void activity_rie5(); +! void activity_ri8(PORT_TIMER_WIDTH capturedTime); +! void activity_rie6(); +! void activity_ri9(PORT_TIMER_WIDTH capturedTime); +! // frame validity check +! bool isValidAdv(ieee802154_header_iht* ieee802514_header); +! bool isValidRxFrame(ieee802154_header_iht* ieee802514_header); +! bool isValidAck(ieee802154_header_iht* ieee802514_header, +! OpenQueueEntry_t* packetSent); +! // ASN handling +! void incrementAsnOffset(); +! void asnWriteToAdv(OpenQueueEntry_t* advFrame); +! void asnStoreFromAdv(OpenQueueEntry_t* advFrame); +! // synchronization +! void synchronizePacket(PORT_TIMER_WIDTH timeReceived); +! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection); +! void changeIsSync(bool newIsSync); +! // notifying upper layer +! void notif_sendDone(OpenQueueEntry_t* packetSent, error_t error); +! void notif_receive(OpenQueueEntry_t* packetReceived); +! // statistics +! void resetStats(); +! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); +! // misc +! uint8_t calculateFrequency(uint8_t channelOffset); +! void changeState(ieee154e_state_t newstate); +! void endSlot(); +! bool debugPrint_asn(); +! bool debugPrint_isSync(); +! +! //=========================== admin =========================================== +! +! /** +! \brief This function initializes this module. +! +! Call this function once before any other function in this module, possibly +! during boot-up. +! */ +! void ieee154e_init() { +! +! // initialize variables +! memset(&ieee154e_vars,0,sizeof(ieee154e_vars_t)); +! memset(&ieee154e_dbg,0,sizeof(ieee154e_dbg_t)); +! +! if (idmanager_getIsDAGroot()==TRUE) { +! changeIsSync(TRUE); +! } else { +! changeIsSync(FALSE); +! } +! +! resetStats(); +! ieee154e_stats.numDeSync = 0; +! +! // switch radio on +! radio_rfOn(); +! +! // set callback functions for the radio +! radio_setOverflowCb(isr_ieee154e_newSlot); +! radio_setCompareCb(isr_ieee154e_timer); +! radio_setStartFrameCb(ieee154e_startOfFrame); +! radio_setEndFrameCb(ieee154e_endOfFrame); +! // have the radio start its timer +! radio_startTimer(TsSlotDuration); +! } +! +! //=========================== public ========================================== +! +! /** +! /brief Difference between some older ASN and the current ASN. +! +! \param someASN [in] some ASN to compare to the current +! +! \returns The ASN difference, or 0xffff if more than 65535 different +! */ +! PORT_TIMER_WIDTH ieee154e_asnDiff(asn_t* someASN) { +! PORT_TIMER_WIDTH diff; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! if (ieee154e_vars.asn.byte4 != someASN->byte4) { +! ENABLE_INTERRUPTS(); +! return (PORT_TIMER_WIDTH)0xFFFFFFFF;; +! } +! +! diff = 0; +! if (ieee154e_vars.asn.bytes2and3 == someASN->bytes2and3) { +! ENABLE_INTERRUPTS(); +! return ieee154e_vars.asn.bytes0and1-someASN->bytes0and1; +! } else if (ieee154e_vars.asn.bytes2and3-someASN->bytes2and3==1) { +! diff = ieee154e_vars.asn.bytes0and1; +! diff += 0xffff-someASN->bytes0and1; +! diff += 1; +! } else { +! diff = (PORT_TIMER_WIDTH)0xFFFFFFFF;; +! } +! ENABLE_INTERRUPTS(); +! return diff; +! } +! +! //======= events +! +! /** +! \brief Indicates a new slot has just started. +! +! This function executes in ISR mode, when the new slot timer fires. +! */ +! void isr_ieee154e_newSlot() { +! radio_setTimerPeriod(TsSlotDuration); +! if (ieee154e_vars.isSync==FALSE) { +! activity_synchronize_newSlot(); +! } else { +! activity_ti1ORri1(); +! } +! ieee154e_dbg.num_newSlot++; +! } +! +! /** +! \brief Indicates the FSM timer has fired. +! +! This function executes in ISR mode, when the FSM timer fires. +! */ +! void isr_ieee154e_timer() { +! switch (ieee154e_vars.state) { +! case S_TXDATAOFFSET: +! activity_ti2(); +! break; +! case S_TXDATAPREPARE: +! activity_tie1(); +! break; +! case S_TXDATAREADY: +! activity_ti3(); +! break; +! case S_TXDATADELAY: +! activity_tie2(); +! break; +! case S_TXDATA: +! activity_tie3(); +! break; +! case S_RXACKOFFSET: +! activity_ti6(); +! break; +! case S_RXACKPREPARE: +! activity_tie4(); +! break; +! case S_RXACKREADY: +! activity_ti7(); +! break; +! case S_RXACKLISTEN: +! activity_tie5(); +! break; +! case S_RXACK: +! activity_tie6(); +! break; +! case S_RXDATAOFFSET: +! activity_ri2(); +! break; +! case S_RXDATAPREPARE: +! activity_rie1(); +! break; +! case S_RXDATAREADY: +! activity_ri3(); +! break; +! case S_RXDATALISTEN: +! activity_rie2(); +! break; +! case S_RXDATA: +! activity_rie3(); +! break; +! case S_TXACKOFFSET: +! activity_ri6(); +! break; +! case S_TXACKPREPARE: +! activity_rie4(); +! break; +! case S_TXACKREADY: +! activity_ri7(); +! break; +! case S_TXACKDELAY: +! activity_rie5(); +! break; +! case S_TXACK: +! activity_rie6(); +! break; +! default: +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_TIMERFIRES, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! break; +! } +! ieee154e_dbg.num_timer++; +! } +! +! /** +! \brief Indicates the radio just received the first byte of a packet. +! +! This function executes in ISR mode. +! */ +! void ieee154e_startOfFrame(PORT_TIMER_WIDTH capturedTime) { +! if (ieee154e_vars.isSync==FALSE) { +! activity_synchronize_startOfFrame(capturedTime); +! } else { +! switch (ieee154e_vars.state) { +! case S_TXDATADELAY: +! activity_ti4(capturedTime); +! break; +! case S_RXACKREADY: +! /* +! It is possible to receive in this state for radio where there is no +! way of differentiated between "ready to listen" and "listening" +! (e.g. CC2420). We must therefore expect to the start of a packet in +! this "ready" state. +! */ +! // no break! +! case S_RXACKLISTEN: +! activity_ti8(capturedTime); +! break; +! case S_RXDATAREADY: +! /* +! Similarly as above. +! */ +! // no break! +! case S_RXDATALISTEN: +! activity_ri4(capturedTime); +! break; +! case S_TXACKDELAY: +! activity_ri8(capturedTime); +! break; +! default: +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_NEWSLOT, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! break; +! } +! } +! ieee154e_dbg.num_startOfFrame++; +! } +! +! /** +! \brief Indicates the radio just received the last byte of a packet. +! +! This function executes in ISR mode. +! */ +! void ieee154e_endOfFrame(PORT_TIMER_WIDTH capturedTime) { +! if (ieee154e_vars.isSync==FALSE) { +! activity_synchronize_endOfFrame(capturedTime); +! } else { +! switch (ieee154e_vars.state) { +! case S_TXDATA: +! activity_ti5(capturedTime); +! break; +! case S_RXACK: +! activity_ti9(capturedTime); +! break; +! case S_RXDATA: +! activity_ri5(capturedTime); +! break; +! case S_TXACK: +! activity_ri9(capturedTime); +! break; +! default: +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDOFFRAME, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! break; +! } +! } +! ieee154e_dbg.num_endOfFrame++; +! } +! +! //======= misc +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_asn() { +! asn_t output; +! output.byte4 = ieee154e_vars.asn.byte4; +! output.bytes2and3 = ieee154e_vars.asn.bytes2and3; +! output.bytes0and1 = ieee154e_vars.asn.bytes0and1; +! openserial_printStatus(STATUS_ASN,(uint8_t*)&output,sizeof(output)); +! return TRUE; +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_isSync() { +! uint8_t output=0; +! output = ieee154e_vars.isSync; +! openserial_printStatus(STATUS_ISSYNC,(uint8_t*)&output,sizeof(uint8_t)); +! return TRUE; +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_macStats() { +! // send current stats over serial +! openserial_printStatus(STATUS_MACSTATS,(uint8_t*)&ieee154e_stats,sizeof(ieee154e_stats_t)); +! return TRUE; +! } +! +! //=========================== private ========================================= +! +! //======= SYNCHRONIZING +! +! port_INLINE void activity_synchronize_newSlot() { +! // I'm in the middle of receiving a packet +! if (ieee154e_vars.state==S_SYNCRX) { +! return; +! } +! +! // if this is the first time I call this function while not synchronized, +! // switch on the radio in Rx mode +! if (ieee154e_vars.state!=S_SYNCLISTEN) { +! // change state +! changeState(S_SYNCLISTEN); +! +! // turn off the radio (in case it wasn't yet) +! radio_rfOff(); +! +! // configure the radio to listen to the default synchronizing channel +! radio_setFrequency(SYNCHRONIZING_CHANNEL); +! +! // update record of current channel +! ieee154e_vars.freq = SYNCHRONIZING_CHANNEL; +! +! // switch on the radio in Rx mode. +! radio_rxEnable(); +! radio_rxNow(); +! } +! +! // increment ASN (used only to schedule serial activity) +! incrementAsnOffset(); +! +! // to be able to receive and transmist serial even when not synchronized +! // take turns every 8 slots sending and receiving +! if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0000) { +! openserial_stop(); +! openserial_startOutput(); +! } else if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0008) { +! openserial_stop(); +! openserial_startInput(); +! } +! } +! +! port_INLINE void activity_synchronize_startOfFrame(PORT_TIMER_WIDTH capturedTime) { +! +! // don't care about packet if I'm not listening +! if (ieee154e_vars.state!=S_SYNCLISTEN) { +! return; +! } +! +! // change state +! changeState(S_SYNCRX); +! +! // stop the serial +! openserial_stop(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // record the captured time (for sync) +! ieee154e_vars.syncCapturedTime = capturedTime; +! } +! +! port_INLINE void activity_synchronize_endOfFrame(PORT_TIMER_WIDTH capturedTime) { +! ieee802154_header_iht ieee802514_header; +! +! // check state +! if (ieee154e_vars.state!=S_SYNCRX) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDFRAME_SYNC, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)0); +! // abort +! endSlot(); +! } +! +! // change state +! changeState(S_SYNCPROC); +! +! // get a buffer to put the (received) frame in +! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.dataReceived==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; +! +! /* +! The do-while loop that follows is a little parsing trick. +! Because it contains a while(0) condition, it gets executed only once. +! The behavior is: +! - if a break occurs inside the do{} body, the error code below the loop +! gets executed. This indicates something is wrong with the packet being +! parsed. +! - if a return occurs inside the do{} body, the error code below the loop +! does not get executed. This indicates the received packet is correct. +! */ +! do { // this "loop" is only executed once +! +! // retrieve the received data frame from the radio's Rx buffer +! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); +! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, +! &ieee154e_vars.dataReceived->length, +! sizeof(ieee154e_vars.dataReceived->packet), +! &ieee154e_vars.dataReceived->l1_rssi, +! &ieee154e_vars.dataReceived->l1_lqi, +! &ieee154e_vars.dataReceived->l1_crc); +! +! // break if packet too short +! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX) { +! // break from the do-while loop and execute abort code below +! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, +! (errorparameter_t)0, +! ieee154e_vars.dataReceived->length); +! break; +! } +! +! // toss CRC (2 last bytes) +! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); +! +! // break if invalid CRC +! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { +! // break from the do-while loop and execute abort code below +! break; +! } +! +! // parse the IEEE802.15.4 header (synchronize, end of frame) +! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); +! +! // break if invalid IEEE802.15.4 header +! if (ieee802514_header.valid==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // store header details in packet buffer +! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; +! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; +! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); +! +! // toss the IEEE802.15.4 header +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); +! +! // break if invalid ADV +! if (isValidAdv(&ieee802514_header)==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // turn off the radio +! radio_rfOff(); +! +! // record the ASN from the ADV payload +! asnStoreFromAdv(ieee154e_vars.dataReceived); +! +! // toss the ADV payload +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ADV_PAYLOAD_LENGTH); +! +! // synchronize (for the first time) to the sender's ADV +! synchronizePacket(ieee154e_vars.syncCapturedTime); +! +! // declare synchronized +! changeIsSync(TRUE); +! +! // log the info +! openserial_printInfo(COMPONENT_IEEE802154E,ERR_SYNCHRONIZED, +! (errorparameter_t)ieee154e_vars.slotOffset, +! (errorparameter_t)0); +! +! // send received ADV up the stack so RES can update statistics (synchronizing) +! notif_receive(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // official end of synchronization +! endSlot(); +! +! // everything went well, return here not to execute the error code below +! return; +! +! } while (0); +! +! // free the (invalid) received data buffer so RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // return to listening state +! changeState(S_SYNCLISTEN); +! } +! +! //======= TX +! +! port_INLINE void activity_ti1ORri1() { +! cellType_t cellType; +! open_addr_t neighbor; +! uint8_t i; +! +! // increment ASN (do this first so debug pins are in sync) +! incrementAsnOffset(); +! +! // wiggle debug pins +! debugpins_slot_toggle(); +! if (ieee154e_vars.slotOffset==0) { +! debugpins_frame_toggle(); +! } +! +! // desynchronize if needed +! if (idmanager_getIsDAGroot()==FALSE) { +! ieee154e_vars.deSyncTimeout--; +! if (ieee154e_vars.deSyncTimeout==0) { +! // declare myself desynchronized +! changeIsSync(FALSE); +! +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_DESYNCHRONIZED, +! (errorparameter_t)ieee154e_vars.slotOffset, +! (errorparameter_t)0); +! +! // update the statistics +! ieee154e_stats.numDeSync++; +! +! // abort +! endSlot(); +! return; +! } +! } +! +! // if the previous slot took too long, we will not be in the right state +! if (ieee154e_vars.state!=S_SLEEP) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_STARTSLOT, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! return; +! } +! +! if (ieee154e_vars.slotOffset==ieee154e_vars.nextActiveSlotOffset) { +! // this is the next active slot +! +! // advance the schedule +! schedule_advanceSlot(); +! +! // find the next one +! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); +! } else { +! // this is NOT the next active slot, abort +! // stop using serial +! openserial_stop(); +! // abort the slot +! endSlot(); +! //start outputing serial +! openserial_startOutput(); +! return; +! } +! +! // check the schedule to see what type of slot this is +! cellType = schedule_getType(); +! switch (cellType) { +! case CELLTYPE_ADV: +! // stop using serial +! openserial_stop(); +! // look for an ADV packet in the queue +! ieee154e_vars.dataToSend = openqueue_macGetAdvPacket(); +! if (ieee154e_vars.dataToSend==NULL) { // I will be listening for an ADV +! // change state +! changeState(S_RXDATAOFFSET); +! // arm rt1 +! radiotimer_schedule(DURATION_rt1); +! } else { // I will be sending an ADV +! // change state +! changeState(S_TXDATAOFFSET); +! // change owner +! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; +! // fill in the ASN field of the ADV +! asnWriteToAdv(ieee154e_vars.dataToSend); +! // record that I attempt to transmit this packet +! ieee154e_vars.dataToSend->l2_numTxAttempts++; +! // arm tt1 +! radiotimer_schedule(DURATION_tt1); +! } +! break; +! case CELLTYPE_TXRX: +! case CELLTYPE_TX: +! // stop using serial +! openserial_stop(); +! // check whether we can send +! if (schedule_getOkToSend()) { +! schedule_getNeighbor(&neighbor); +! ieee154e_vars.dataToSend = openqueue_macGetDataPacket(&neighbor); +! } else { +! ieee154e_vars.dataToSend = NULL; +! } +! if (ieee154e_vars.dataToSend!=NULL) { // I have a packet to send +! // change state +! changeState(S_TXDATAOFFSET); +! // change owner +! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; +! // record that I attempt to transmit this packet +! ieee154e_vars.dataToSend->l2_numTxAttempts++; +! // arm tt1 +! radiotimer_schedule(DURATION_tt1); +! } else if (cellType==CELLTYPE_TX){ +! // abort +! endSlot(); +! } +! if (cellType==CELLTYPE_TX || +! (cellType==CELLTYPE_TXRX && ieee154e_vars.dataToSend!=NULL)) { +! break; +! } +! case CELLTYPE_RX: +! // stop using serial +! openserial_stop(); +! // change state +! changeState(S_RXDATAOFFSET); +! // arm rt1 +! radiotimer_schedule(DURATION_rt1); +! break; +! case CELLTYPE_SERIALRX: +! // stop using serial +! openserial_stop(); +! // abort the slot +! endSlot(); +! //start inputting serial data +! openserial_startInput(); +! //this is to emulate a set of serial input slots without having the slotted structure. +! radio_setTimerPeriod(TsSlotDuration*(NUMSERIALRX)); +! +! //increase ASN by NUMSERIALRX-1 slots as at this slot is already incremented by 1 +! for (i=0;ipayload, +! ieee154e_vars.dataToSend->length); +! +! // enable the radio in Tx mode. This does not send the packet. +! radio_txEnable(); +! +! // arm tt2 +! radiotimer_schedule(DURATION_tt2); +! +! // change state +! changeState(S_TXDATAREADY); +! } +! +! port_INLINE void activity_tie1() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXDATAPREPARE_OVERFLOW, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti3() { +! // change state +! changeState(S_TXDATADELAY); +! +! // arm tt3 +! radiotimer_schedule(DURATION_tt3); +! +! // give the 'go' to transmit +! radio_txNow(); +! } +! +! port_INLINE void activity_tie2() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIO_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti4(PORT_TIMER_WIDTH capturedTime) { +! // change state +! changeState(S_TXDATA); +! +! // cancel tt3 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // arm tt4 +! radiotimer_schedule(DURATION_tt4); +! } +! +! port_INLINE void activity_tie3() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti5(PORT_TIMER_WIDTH capturedTime) { +! bool listenForAck; +! +! // change state +! changeState(S_RXACKOFFSET); +! +! // cancel tt4 +! radiotimer_cancel(); +! +! // turn off the radio +! radio_rfOff(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // decides whether to listen for an ACK +! if (packetfunctions_isBroadcastMulticast(&ieee154e_vars.dataToSend->l2_nextORpreviousHop)==TRUE) { +! listenForAck = FALSE; +! } else { +! listenForAck = TRUE; +! } +! +! if (listenForAck==TRUE) { +! // arm tt5 +! radiotimer_schedule(DURATION_tt5); +! } else { +! // indicate succesful Tx to schedule to keep statistics +! schedule_indicateTx(&ieee154e_vars.asn,TRUE); +! // indicate to upper later the packet was sent successfully +! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); +! // reset local variable +! ieee154e_vars.dataToSend = NULL; +! // abort +! endSlot(); +! } +! } +! +! port_INLINE void activity_ti6() { +! // change state +! changeState(S_RXACKPREPARE); +! +! // calculate the frequency to transmit on +! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); +! +! // configure the radio for that frequency +! //radio_setFrequency(frequency); +! radio_setFrequency(ieee154e_vars.freq); +! +! // enable the radio in Rx mode. The radio is not actively listening yet. +! radio_rxEnable(); +! +! // arm tt6 +! radiotimer_schedule(DURATION_tt6); +! +! // change state +! changeState(S_RXACKREADY); +! } +! +! port_INLINE void activity_tie4() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXACKPREPARE_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti7() { +! // change state +! changeState(S_RXACKLISTEN); +! +! // start listening +! radio_rxNow(); +! +! // arm tt7 +! radiotimer_schedule(DURATION_tt7); +! } +! +! port_INLINE void activity_tie5() { +! // indicate transmit failed to schedule to keep stats +! schedule_indicateTx(&ieee154e_vars.asn,FALSE); +! +! // decrement transmits left counter +! ieee154e_vars.dataToSend->l2_retriesLeft--; +! +! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { +! // indicate tx fail if no more retries left +! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); +! } else { +! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component +! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; +! } +! +! // reset local variable +! ieee154e_vars.dataToSend = NULL; +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti8(PORT_TIMER_WIDTH capturedTime) { +! // change state +! changeState(S_RXACK); +! +! // cancel tt7 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // arm tt8 +! radiotimer_schedule(DURATION_tt8); +! } +! +! port_INLINE void activity_tie6() { +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti9(PORT_TIMER_WIDTH capturedTime) { +! ieee802154_header_iht ieee802514_header; +! volatile PORT_SIGNED_INT_WIDTH timeCorrection; +! uint8_t byte0; +! uint8_t byte1; +! +! // change state +! changeState(S_TXPROC); +! +! // cancel tt8 +! radiotimer_cancel(); +! +! // turn off the radio +! radio_rfOff(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // get a buffer to put the (received) ACK in +! ieee154e_vars.ackReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.ackReceived==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.ackReceived->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.ackReceived->owner = COMPONENT_IEEE802154E; +! +! /* +! The do-while loop that follows is a little parsing trick. +! Because it contains a while(0) condition, it gets executed only once. +! Below the do-while loop is some code to cleans up the ack variable. +! Anywhere in the do-while loop, a break statement can be called to jump to +! the clean up code early. If the loop ends without a break, the received +! packet was correct. If it got aborted early (through a break), the packet +! was faulty. +! */ +! do { // this "loop" is only executed once +! +! // retrieve the received ack frame from the radio's Rx buffer +! ieee154e_vars.ackReceived->payload = &(ieee154e_vars.ackReceived->packet[FIRST_FRAME_BYTE]); +! radio_getReceivedFrame( ieee154e_vars.ackReceived->payload, +! &ieee154e_vars.ackReceived->length, +! sizeof(ieee154e_vars.ackReceived->packet), +! &ieee154e_vars.ackReceived->l1_rssi, +! &ieee154e_vars.ackReceived->l1_lqi, +! &ieee154e_vars.ackReceived->l1_crc); +! +! // break if wrong length +! if (ieee154e_vars.ackReceived->lengthlength>LENGTH_IEEE154_MAX) { +! // break from the do-while loop and execute the clean-up code below +! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, +! (errorparameter_t)1, +! ieee154e_vars.ackReceived->length); +! +! break; +! } +! +! // toss CRC (2 last bytes) +! packetfunctions_tossFooter( ieee154e_vars.ackReceived, LENGTH_CRC); +! +! // break if invalid CRC +! if (ieee154e_vars.ackReceived->l1_crc==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // parse the IEEE802.15.4 header (RX ACK) +! ieee802154_retrieveHeader(ieee154e_vars.ackReceived,&ieee802514_header); +! +! // break if invalid IEEE802.15.4 header +! if (ieee802514_header.valid==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // store header details in packet buffer +! ieee154e_vars.ackReceived->l2_frameType = ieee802514_header.frameType; +! ieee154e_vars.ackReceived->l2_dsn = ieee802514_header.dsn; +! memcpy(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); +! +! // toss the IEEE802.15.4 header +! packetfunctions_tossHeader(ieee154e_vars.ackReceived,ieee802514_header.headerLength); +! +! // break if invalid ACK +! if (isValidAck(&ieee802514_header,ieee154e_vars.dataToSend)==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // resynchronize if I'm not a DAGroot and ACK from preferred parent +! if (idmanager_getIsDAGroot()==FALSE && +! neighbors_isPreferredParent(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop)) ) { +! byte0 = ieee154e_vars.ackReceived->payload[0]; +! byte1 = ieee154e_vars.ackReceived->payload[1]; +! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_TIMER_WIDTH)byte1<<8 | (PORT_TIMER_WIDTH)byte0); +! timeCorrection /= US_PER_TICK; +! timeCorrection = -timeCorrection; +! synchronizeAck(timeCorrection); +! } +! +! // inform schedule of successful transmission +! schedule_indicateTx(&ieee154e_vars.asn,TRUE); +! +! // inform upper layer +! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); +! ieee154e_vars.dataToSend = NULL; +! +! // in any case, execute the clean-up code below (processing of ACK done) +! } while (0); +! +! // free the received ack so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); +! +! // clear local variable +! ieee154e_vars.ackReceived = NULL; +! +! // official end of Tx slot +! endSlot(); +! } +! +! //======= RX +! +! port_INLINE void activity_ri2() { +! // change state +! changeState(S_RXDATAPREPARE); +! +! // calculate the frequency to transmit on +! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); +! +! // configure the radio for that frequency +! //radio_setFrequency(frequency); +! radio_setFrequency(ieee154e_vars.freq); +! +! // enable the radio in Rx mode. The radio does not actively listen yet. +! radio_rxEnable(); +! +! +! // arm rt2 +! radiotimer_schedule(DURATION_rt2); +! +! // change state +! changeState(S_RXDATAREADY); +! } +! +! port_INLINE void activity_rie1() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXDATAPREPARE_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri3() { +! // change state +! changeState(S_RXDATALISTEN); +! +! // give the 'go' to receive +! radio_rxNow(); +! +! // arm rt3 +! radiotimer_schedule(DURATION_rt3); +! } +! +! port_INLINE void activity_rie2() { +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri4(PORT_TIMER_WIDTH capturedTime) { +! // change state +! changeState(S_RXDATA); +! +! // cancel rt3 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // record the captured time to sync +! ieee154e_vars.syncCapturedTime = capturedTime; +! +! // arm rt4 +! radiotimer_schedule(DURATION_rt4); +! } +! +! port_INLINE void activity_rie3() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri5(PORT_TIMER_WIDTH capturedTime) { +! ieee802154_header_iht ieee802514_header; +! +! // change state +! changeState(S_TXACKOFFSET); +! +! // cancel rt4 +! radiotimer_cancel(); +! +! // turn off the radio +! radio_rfOff(); +! +! // get a buffer to put the (received) data in +! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.dataReceived==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; +! +! /* +! The do-while loop that follows is a little parsing trick. +! Because it contains a while(0) condition, it gets executed only once. +! The behavior is: +! - if a break occurs inside the do{} body, the error code below the loop +! gets executed. This indicates something is wrong with the packet being +! parsed. +! - if a return occurs inside the do{} body, the error code below the loop +! does not get executed. This indicates the received packet is correct. +! */ +! do { // this "loop" is only executed once +! +! // retrieve the received data frame from the radio's Rx buffer +! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); +! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, +! &ieee154e_vars.dataReceived->length, +! sizeof(ieee154e_vars.dataReceived->packet), +! &ieee154e_vars.dataReceived->l1_rssi, +! &ieee154e_vars.dataReceived->l1_lqi, +! &ieee154e_vars.dataReceived->l1_crc); +! +! // break if wrong length +! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX ) { +! // jump to the error code below this do-while loop +! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, +! (errorparameter_t)2, +! ieee154e_vars.dataReceived->length); +! break; +! } +! +! // toss CRC (2 last bytes) +! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); +! +! // if CRC doesn't check, stop +! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { +! // jump to the error code below this do-while loop +! break; +! } +! +! // parse the IEEE802.15.4 header (RX DATA) +! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); +! +! // break if invalid IEEE802.15.4 header +! if (ieee802514_header.valid==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // store header details in packet buffer +! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; +! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; +! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); +! +! // toss the IEEE802.15.4 header +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); +! +! // if I just received a valid ADV, record the ASN and toss the ADV payload +! if (isValidAdv(&ieee802514_header)==TRUE) { +! if (idmanager_getIsDAGroot()==FALSE) { +! asnStoreFromAdv(ieee154e_vars.dataReceived); +! } +! // toss the ADV payload +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ADV_PAYLOAD_LENGTH); +! } +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // if I just received an invalid frame, stop +! if (isValidRxFrame(&ieee802514_header)==FALSE) { +! // jump to the error code below this do-while loop +! break; +! } +! +! // check if ack requested +! if (ieee802514_header.ackRequested==1) { +! // arm rt5 +! radiotimer_schedule(DURATION_rt5); +! } else { +! // synchronize to the received packet iif I'm not a DAGroot and this is my preferred parent +! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { +! synchronizePacket(ieee154e_vars.syncCapturedTime); +! } +! // indicate reception to upper layer (no ACK asked) +! notif_receive(ieee154e_vars.dataReceived); +! // reset local variable +! ieee154e_vars.dataReceived = NULL; +! // abort +! endSlot(); +! } +! +! // everything went well, return here not to execute the error code below +! return; +! +! } while(0); +! +! // free the (invalid) received data so RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri6() { +! PORT_SIGNED_INT_WIDTH timeCorrection; +! +! // change state +! changeState(S_TXACKPREPARE); +! +! // get a buffer to put the ack to send in +! ieee154e_vars.ackToSend = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.ackToSend==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // indicate we received a packet anyway (we don't want to loose any) +! notif_receive(ieee154e_vars.dataReceived); +! // free local variable +! ieee154e_vars.dataReceived = NULL; +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.ackToSend->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.ackToSend->owner = COMPONENT_IEEE802154E; +! +! // calculate the time timeCorrection (this is the time when the packet arrive w.r.t the time it should be. +! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.syncCapturedTime-(PORT_SIGNED_INT_WIDTH)TsTxOffset); +! +! // add the payload to the ACK (i.e. the timeCorrection) +! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(IEEE802154E_ACK_ht)); +! timeCorrection = -timeCorrection; +! timeCorrection *= US_PER_TICK; +! ieee154e_vars.ackToSend->payload[0] = (uint8_t)((((PORT_TIMER_WIDTH)timeCorrection) ) & 0xff); +! ieee154e_vars.ackToSend->payload[1] = (uint8_t)((((PORT_TIMER_WIDTH)timeCorrection)>>8) & 0xff); +! +! // prepend the IEEE802.15.4 header to the ACK +! ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; +! ieee154e_vars.ackToSend->l2_dsn = ieee154e_vars.dataReceived->l2_dsn; +! ieee802154_prependHeader(ieee154e_vars.ackToSend, +! ieee154e_vars.ackToSend->l2_frameType, +! IEEE154_SEC_NO_SECURITY, +! ieee154e_vars.dataReceived->l2_dsn, +! &(ieee154e_vars.dataReceived->l2_nextORpreviousHop) +! ); +! +! // space for 2-byte CRC +! packetfunctions_reserveFooterSize(ieee154e_vars.ackToSend,2); +! +! // calculate the frequency to transmit on +! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); +! +! // configure the radio for that frequency +! //radio_setFrequency(frequency); +! radio_setFrequency(ieee154e_vars.freq); +! +! // load the packet in the radio's Tx buffer +! radio_loadPacket(ieee154e_vars.ackToSend->payload, +! ieee154e_vars.ackToSend->length); +! +! // enable the radio in Tx mode. This does not send that packet. +! radio_txEnable(); +! +! // arm rt6 +! radiotimer_schedule(DURATION_rt6); +! +! // change state +! changeState(S_TXACKREADY); +! } +! +! port_INLINE void activity_rie4() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXACKPREPARE_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri7() { +! // change state +! changeState(S_TXACKDELAY); +! +! // arm rt7 +! radiotimer_schedule(DURATION_rt7); +! +! // give the 'go' to transmit +! radio_txNow(); +! } +! +! port_INLINE void activity_rie5() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIOTX_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri8(PORT_TIMER_WIDTH capturedTime) { +! // change state +! changeState(S_TXACK); +! +! // cancel rt7 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // arm rt8 +! radiotimer_schedule(DURATION_rt8); +! } +! +! port_INLINE void activity_rie6() { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDACKDURATION_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri9(PORT_TIMER_WIDTH capturedTime) { +! // change state +! changeState(S_RXPROC); +! +! // cancel rt8 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // free the ack we just sent so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); +! +! // clear local variable +! ieee154e_vars.ackToSend = NULL; +! +! // synchronize to the received packet +! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { +! synchronizePacket(ieee154e_vars.syncCapturedTime); +! } +! +! // inform upper layer of reception (after ACK sent) +! notif_receive(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // official end of Rx slot +! endSlot(); +! } +! +! //======= frame validity check +! +! /** +! \brief Decides whether the packet I just received is a valid ADV +! +! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just +! received. +! +! A valid ADV frame satisfies the following conditions: +! - its IEEE802.15.4 header is well formatted +! - it's a BEACON frame +! - it's sent to the my PANid +! - its payload length is the expected ADV payload length +! +! \returns TRUE if packet is a valid ADV, FALSE otherwise +! */ +! port_INLINE bool isValidAdv(ieee802154_header_iht* ieee802514_header) { +! return ieee802514_header->valid==TRUE && \ +! ieee802514_header->frameType==IEEE154_TYPE_BEACON && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! ieee154e_vars.dataReceived->length==ADV_PAYLOAD_LENGTH; +! } +! +! /** +! \brief Decides whether the packet I just received is valid received frame. +! +! A valid Rx frame satisfies the following constraints: +! - its IEEE802.15.4 header is well formatted +! - it's a DATA of BEACON frame (i.e. not ACK and not COMMAND) +! - it's sent on the same PANid as mine +! - it's for me (unicast or broadcast) +! +! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just received +! +! \returns TRUE if packet is valid received frame, FALSE otherwise +! */ +! port_INLINE bool isValidRxFrame(ieee802154_header_iht* ieee802514_header) { +! return ieee802514_header->valid==TRUE && \ +! ( +! ieee802514_header->frameType==IEEE154_TYPE_DATA || +! ieee802514_header->frameType==IEEE154_TYPE_BEACON +! ) && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! ( +! idmanager_isMyAddress(&ieee802514_header->dest) || +! packetfunctions_isBroadcastMulticast(&ieee802514_header->dest) +! ); +! } +! +! /** +! \brief Decides whether the packet I just received is a valid ACK. +! +! A packet is a valid ACK if it satisfies the following conditions: +! - the IEEE802.15.4 header is valid +! - the frame type is 'ACK' +! - the sequence number in the ACK matches the sequence number of the packet sent +! - the ACK contains my PANid +! - the packet is unicast to me +! - the packet comes from the neighbor I sent the data to +! +! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just received +! \param [in] packetSent points to the packet I just sent +! +! \returns TRUE if packet is a valid ACK, FALSE otherwise. +! */ +! port_INLINE bool isValidAck(ieee802154_header_iht* ieee802514_header, OpenQueueEntry_t* packetSent) { +! /* +! return ieee802514_header->valid==TRUE && \ +! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ +! ieee802514_header->dsn==packetSent->l2_dsn && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! idmanager_isMyAddress(&ieee802514_header->dest) && \ +! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); +! */ +! // poipoi don't check for seq num +! return ieee802514_header->valid==TRUE && \ +! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! idmanager_isMyAddress(&ieee802514_header->dest) && \ +! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); +! } +! +! //======= ASN handling +! +! port_INLINE void incrementAsnOffset() { +! // increment the asn +! ieee154e_vars.asn.bytes0and1++; +! if (ieee154e_vars.asn.bytes0and1==0) { +! ieee154e_vars.asn.bytes2and3++; +! if (ieee154e_vars.asn.bytes2and3==0) { +! ieee154e_vars.asn.byte4++; +! } +! } +! // increment the offsets +! ieee154e_vars.slotOffset = (ieee154e_vars.slotOffset+1)%schedule_getFrameLength(); +! ieee154e_vars.asnOffset = (ieee154e_vars.asnOffset+1)%16; +! } +! +! port_INLINE void asnWriteToAdv(OpenQueueEntry_t* advFrame) { +! advFrame->l2_payload[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); +! advFrame->l2_payload[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); +! advFrame->l2_payload[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); +! advFrame->l2_payload[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); +! advFrame->l2_payload[4] = ieee154e_vars.asn.byte4; +! } +! +! //from upper layer that want to send the ASN to compute timming or latency +! void asnWriteToPkt(OpenQueueEntry_t* frame) { +! frame->payload[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); +! frame->payload[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); +! frame->payload[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); +! frame->payload[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); +! frame->payload[4] = ieee154e_vars.asn.byte4; +! } +! +! void asnWriteToSerial(uint8_t* array) { +! array[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); +! array[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); +! array[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); +! array[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); +! array[4] = ieee154e_vars.asn.byte4; +! } +! +! +! port_INLINE void asnStoreFromAdv(OpenQueueEntry_t* advFrame) { +! +! // store the ASN +! ieee154e_vars.asn.bytes0and1 = ieee154e_vars.dataReceived->payload[0]+ +! 256*ieee154e_vars.dataReceived->payload[1]; +! ieee154e_vars.asn.bytes2and3 = ieee154e_vars.dataReceived->payload[2]+ +! 256*ieee154e_vars.dataReceived->payload[3]; +! ieee154e_vars.asn.byte4 = ieee154e_vars.dataReceived->payload[4]; +! +! // determine the current slotOffset +! /* +! Note: this is a bit of a hack. Normally, slotOffset=ASN%slotlength. But since +! the ADV is exchanged in slot 0, we know that we're currently at slotOffset==0 +! */ +! ieee154e_vars.slotOffset = 0; +! schedule_syncSlotOffset(ieee154e_vars.slotOffset); +! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); +! +! /* +! infer the asnOffset based on the fact that +! ieee154e_vars.freq = 11 + (asnOffset + channelOffset)%16 +! */ +! ieee154e_vars.asnOffset = ieee154e_vars.freq - 11 - schedule_getChannelOffset(); +! } +! +! //======= synchronization +! +! void synchronizePacket(PORT_TIMER_WIDTH timeReceived) { +! PORT_SIGNED_INT_WIDTH timeCorrection; +! PORT_TIMER_WIDTH newPeriod; +! PORT_TIMER_WIDTH currentValue; +! PORT_TIMER_WIDTH currentPeriod; +! // record the current timer value and period +! currentValue = radio_getTimerValue(); +! currentPeriod = radio_getTimerPeriod(); +! // calculate new period +! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)timeReceived-(PORT_SIGNED_INT_WIDTH)TsTxOffset); +! newPeriod = TsSlotDuration; +! // detect whether I'm too close to the edge of the slot, in that case, +! // skip a slot and increase the temporary slot length to be 2 slots long +! if (currentValue LIMITLARGETIMECORRECTION +! ) +! ) { +! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, +! (errorparameter_t)timeCorrection, +! (errorparameter_t)0); +! } +! // update the stats +! ieee154e_stats.numSyncPkt++; +! updateStats(timeCorrection); +! } +! +! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection) { +! PORT_TIMER_WIDTH newPeriod; +! PORT_TIMER_WIDTH currentPeriod; +! // calculate new period +! currentPeriod = radio_getTimerPeriod(); +! newPeriod = (PORT_TIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)currentPeriod-timeCorrection); +! // resynchronize by applying the new period +! radio_setTimerPeriod(newPeriod); +! // reset the de-synchronization timeout +! ieee154e_vars.deSyncTimeout = DESYNCTIMEOUT; +! // log a large timeCorrection +! if ( +! ieee154e_vars.isSync==TRUE && +! ( +! timeCorrection<-LIMITLARGETIMECORRECTION || +! timeCorrection> LIMITLARGETIMECORRECTION +! ) +! ) { +! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, +! (errorparameter_t)timeCorrection, +! (errorparameter_t)1); +! } +! // update the stats +! ieee154e_stats.numSyncAck++; +! updateStats(timeCorrection); +! } +! +! void changeIsSync(bool newIsSync) { +! ieee154e_vars.isSync = newIsSync; +! +! if (ieee154e_vars.isSync==TRUE) { +! leds_sync_on(); +! resetStats(); +! } else { +! leds_sync_off(); +! schedule_resetBackoff(); +! } +! } +! +! //======= notifying upper layer +! +! void notif_sendDone(OpenQueueEntry_t* packetSent, error_t error) { +! // record the outcome of the trasmission attempt +! packetSent->l2_sendDoneError = error; +! // record the current ASN +! memcpy(&packetSent->l2_asn,&ieee154e_vars.asn,sizeof(asn_t)); +! // associate this packet with the virtual component +! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it +! packetSent->owner = COMPONENT_IEEE802154E_TO_RES; +! // post RES's sendDone task +! scheduler_push_task(task_resNotifSendDone,TASKPRIO_RESNOTIF_TXDONE); +! // wake up the scheduler +! SCHEDULER_WAKEUP(); +! } +! +! void notif_receive(OpenQueueEntry_t* packetReceived) { +! // record the current ASN +! memcpy(&packetReceived->l2_asn, &ieee154e_vars.asn, sizeof(asn_t)); +! // indicate reception to the schedule, to keep statistics +! schedule_indicateRx(&packetReceived->l2_asn); +! // associate this packet with the virtual component +! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it +! packetReceived->owner = COMPONENT_IEEE802154E_TO_RES; +! // post RES's Receive task +! scheduler_push_task(task_resNotifReceive,TASKPRIO_RESNOTIF_RX); +! // wake up the scheduler +! SCHEDULER_WAKEUP(); +! } +! +! //======= stats +! +! port_INLINE void resetStats() { +! ieee154e_stats.numSyncPkt = 0; +! ieee154e_stats.numSyncAck = 0; +! ieee154e_stats.minCorrection = 127; +! ieee154e_stats.maxCorrection = -127; +! // do not reset the number of de-synchronizations +! } +! +! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection) { +! // update minCorrection +! if (timeCorrectionieee154e_stats.maxCorrection) { +! ieee154e_stats.maxCorrection = timeCorrection; +! } +! } +! +! //======= misc +! +! /** +! \brief Calculates the frequency channel to transmit on, based on the +! absolute slot number and the channel offset of the requested slot. +! +! During normal operation, the frequency used is a function of the +! channelOffset indicating in the schedule, and of the ASN of the +! slot. This ensures channel hopping, consecutive packets sent in the same slot +! in the schedule are done on a difference frequency channel. +! +! During development, you can force single channel operation by having this +! function return a constant channel number (between 11 and 26). This allows you +! to use a single-channel sniffer; but you can not schedule two links on two +! different channel offsets in the same slot. +! +! \param [in] channelOffset channel offset for the current slot +! +! \returns The calculated frequency channel, an integer between 11 and 26. +! */ +! port_INLINE uint8_t calculateFrequency(uint8_t channelOffset) { +! // comment the following line out to disable channel hopping +! return SYNCHRONIZING_CHANNEL; // single channel +! //return 11+(ieee154e_vars.asnOffset+channelOffset)%16; //channel hopping +! } +! +! /** +! \brief Changes the state of the IEEE802.15.4e FSM. +! +! Besides simply updating the state global variable, +! this function toggles the FSM debug pin. +! +! \param [in] newstate The state the IEEE802.15.4e FSM is now in. +! */ +! void changeState(ieee154e_state_t newstate) { +! // update the state +! ieee154e_vars.state = newstate; +! // wiggle the FSM debug pin +! switch (ieee154e_vars.state) { +! case S_SYNCLISTEN: +! case S_TXDATAOFFSET: +! debugpins_fsm_set(); +! break; +! case S_SLEEP: +! case S_RXDATAOFFSET: +! debugpins_fsm_clr(); +! break; +! case S_SYNCRX: +! case S_SYNCPROC: +! case S_TXDATAPREPARE: +! case S_TXDATAREADY: +! case S_TXDATADELAY: +! case S_TXDATA: +! case S_RXACKOFFSET: +! case S_RXACKPREPARE: +! case S_RXACKREADY: +! case S_RXACKLISTEN: +! case S_RXACK: +! case S_TXPROC: +! case S_RXDATAPREPARE: +! case S_RXDATAREADY: +! case S_RXDATALISTEN: +! case S_RXDATA: +! case S_TXACKOFFSET: +! case S_TXACKPREPARE: +! case S_TXACKREADY: +! case S_TXACKDELAY: +! case S_TXACK: +! case S_RXPROC: +! debugpins_fsm_toggle(); +! break; +! } +! } +! +! /** +! \brief Housekeeping tasks to do at the end of each slot. +! +! This functions is called once in each slot, when there is nothing more +! to do. This might be when an error occured, or when everything went well. +! This function resets the state of the FSM so it is ready for the next slot. +! +! Note that by the time this function is called, any received packet should already +! have been sent to the upper layer. Similarly, in a Tx slot, the sendDone +! function should already have been done. If this is not the case, this function +! will do that for you, but assume that something went wrong. +! */ +! void endSlot() { +! // turn off the radio +! radio_rfOff(); +! +! // clear any pending timer +! radiotimer_cancel(); +! +! // reset capturedTimes +! ieee154e_vars.lastCapturedTime = 0; +! ieee154e_vars.syncCapturedTime = 0; +! +! // clean up dataToSend +! if (ieee154e_vars.dataToSend!=NULL) { +! // if everything went well, dataToSend was set to NULL in ti9 +! // getting here means transmit failed +! +! // indicate Tx fail to schedule to update stats +! schedule_indicateTx(&ieee154e_vars.asn,FALSE); +! +! //decrement transmits left counter +! ieee154e_vars.dataToSend->l2_retriesLeft--; +! +! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { +! // indicate tx fail if no more retries left +! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); +! } else { +! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component +! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; +! } +! +! // reset local variable +! ieee154e_vars.dataToSend = NULL; +! } +! +! // clean up dataReceived +! if (ieee154e_vars.dataReceived!=NULL) { +! // assume something went wrong. If everything went well, dataReceived +! // would have been set to NULL in ri9. +! // indicate "received packet" to upper layer since we don't want to loose packets +! notif_receive(ieee154e_vars.dataReceived); +! // reset local variable +! ieee154e_vars.dataReceived = NULL; +! } +! +! // clean up ackToSend +! if (ieee154e_vars.ackToSend!=NULL) { +! // free ackToSend so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); +! // reset local variable +! ieee154e_vars.ackToSend = NULL; +! } +! +! // clean up ackReceived +! if (ieee154e_vars.ackReceived!=NULL) { +! // free ackReceived so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); +! // reset local variable +! ieee154e_vars.ackReceived = NULL; +! } +! +! // change state +! changeState(S_SLEEP); +! } +! +! bool ieee154e_isSynch(){ +! return ieee154e_vars.isSync; +! } +\ No newline at end of file +--- 1,2061 ---- +! #include "openwsn.h" +! #include "IEEE802154E.h" +! #include "radio.h" +! #include "radiotimer.h" +! #include "IEEE802154.h" +! #include "openqueue.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "schedule.h" +! #include "packetfunctions.h" +! #include "scheduler.h" +! #include "leds.h" +! #include "neighbors.h" +! #include "debugpins.h" +! #include "res.h" +! +! #include "thread.h" +! +! //=========================== variables ======================================= +! +! ieee154e_vars_t ieee154e_vars; +! ieee154e_stats_t ieee154e_stats; +! ieee154e_dbg_t ieee154e_dbg; +! +! //static char openwsn_ieee802154e_rec_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! //static char openwsn_ieee802154e_send_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! +! //=========================== prototypes ====================================== +! void isr_ieee154e_newSlot(void); +! void isr_ieee154e_timer(void); +! // SYNCHRONIZING +! void activity_synchronize_newSlot(void); +! void activity_synchronize_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_synchronize_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); +! // TX +! void activity_ti1ORri1(void); +! void activity_ti2(void); +! void activity_tie1(void); +! void activity_ti3(void); +! void activity_tie2(void); +! void activity_ti4(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_tie3(void); +! void activity_ti5(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_ti6(void); +! void activity_tie4(void); +! void activity_ti7(void); +! void activity_tie5(void); +! void activity_ti8(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_tie6(void); +! void activity_ti9(PORT_RADIOTIMER_WIDTH capturedTime); +! // RX +! void activity_ri2(void); +! void activity_rie1(void); +! void activity_ri3(void); +! void activity_rie2(void); +! void activity_ri4(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_rie3(void); +! void activity_ri5(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_ri6(void); +! void activity_rie4(void); +! void activity_ri7(void); +! void activity_rie5(void); +! void activity_ri8(PORT_RADIOTIMER_WIDTH capturedTime); +! void activity_rie6(void); +! void activity_ri9(PORT_RADIOTIMER_WIDTH capturedTime); +! // frame validity check +! +! bool isValidRxFrame(ieee802154_header_iht* ieee802514_header); +! bool isValidAck(ieee802154_header_iht* ieee802514_header, +! OpenQueueEntry_t* packetSent); +! // IEs Handling +! bool ieee154e_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE);//xv poipoi +! void ieee154e_processSlotframeLinkIE(OpenQueueEntry_t* pkt,uint8_t * ptr);//xv poipoi +! // ASN handling +! void incrementAsnOffset(void); +! void asnStoreFromAdv(uint8_t* asn); +! void joinPriorityStoreFromAdv(uint8_t jp); +! // synchronization +! void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived); +! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection); +! void changeIsSync(bool newIsSync); +! // notifying upper layer +! void notif_sendDone(OpenQueueEntry_t* packetSent, owerror_t error); +! void notif_receive(OpenQueueEntry_t* packetReceived); +! // statistics +! void resetStats(void); +! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); +! // misc +! uint8_t calculateFrequency(uint8_t channelOffset); +! void changeState(ieee154e_state_t newstate); +! void endSlot(void); +! bool debugPrint_asn(void); +! bool debugPrint_isSync(void); +! +! //=========================== admin =========================================== +! +! /** +! \brief This function initializes this module. +! +! Call this function once before any other function in this module, possibly +! during boot-up. +! */ +! void ieee154e_init(void) { +! puts(__PRETTY_FUNCTION__); +! // initialize variables +! memset(&ieee154e_vars,0,sizeof(ieee154e_vars_t)); +! memset(&ieee154e_dbg,0,sizeof(ieee154e_dbg_t)); +! +! if (idmanager_getIsDAGroot()==TRUE) { +! changeIsSync(TRUE); +! } else { +! changeIsSync(FALSE); +! } +! +! resetStats(); +! ieee154e_stats.numDeSync = 0; +! +! // switch radio on +! radio_rfOn(); +! +! // set callback functions for the radio +! radio_setOverflowCb(isr_ieee154e_newSlot); +! radio_setCompareCb(isr_ieee154e_timer); +! radio_setStartFrameCb(ieee154e_startOfFrame); +! radio_setEndFrameCb(ieee154e_endOfFrame); +! // have the radio start its timer +! radio_startTimer(TsSlotDuration); +! } +! +! //=========================== public ========================================== +! +! /** +! /brief Difference between some older ASN and the current ASN. +! +! \param[in] someASN some ASN to compare to the current +! +! \returns The ASN difference, or 0xffff if more than 65535 different +! */ +! PORT_RADIOTIMER_WIDTH ieee154e_asnDiff(asn_t* someASN) { +! PORT_RADIOTIMER_WIDTH diff; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! if (ieee154e_vars.asn.byte4 != someASN->byte4) { +! ENABLE_INTERRUPTS(); +! return (PORT_RADIOTIMER_WIDTH)0xFFFFFFFF;; +! } +! +! diff = 0; +! if (ieee154e_vars.asn.bytes2and3 == someASN->bytes2and3) { +! ENABLE_INTERRUPTS(); +! return ieee154e_vars.asn.bytes0and1-someASN->bytes0and1; +! } else if (ieee154e_vars.asn.bytes2and3-someASN->bytes2and3==1) { +! diff = ieee154e_vars.asn.bytes0and1; +! diff += 0xffff-someASN->bytes0and1; +! diff += 1; +! } else { +! diff = (PORT_RADIOTIMER_WIDTH)0xFFFFFFFF;; +! } +! ENABLE_INTERRUPTS(); +! return diff; +! } +! +! //======= events +! +! /** +! \brief Indicates a new slot has just started. +! +! This function executes in ISR mode, when the new slot timer fires. +! */ +! void isr_ieee154e_newSlot(void) { +! radio_setTimerPeriod(TsSlotDuration); +! if (ieee154e_vars.isSync==FALSE) { +! if (idmanager_getIsDAGroot()==TRUE) { +! changeIsSync(TRUE); +! } else { +! activity_synchronize_newSlot(); +! } +! } else { +! activity_ti1ORri1(); +! } +! ieee154e_dbg.num_newSlot++; +! } +! +! /** +! \brief Indicates the FSM timer has fired. +! +! This function executes in ISR mode, when the FSM timer fires. +! */ +! void isr_ieee154e_timer(void) { +! switch (ieee154e_vars.state) { +! case S_TXDATAOFFSET: +! activity_ti2(); +! break; +! case S_TXDATAPREPARE: +! activity_tie1(); +! break; +! case S_TXDATAREADY: +! activity_ti3(); +! break; +! case S_TXDATADELAY: +! activity_tie2(); +! break; +! case S_TXDATA: +! activity_tie3(); +! break; +! case S_RXACKOFFSET: +! activity_ti6(); +! break; +! case S_RXACKPREPARE: +! activity_tie4(); +! break; +! case S_RXACKREADY: +! activity_ti7(); +! break; +! case S_RXACKLISTEN: +! activity_tie5(); +! break; +! case S_RXACK: +! activity_tie6(); +! break; +! case S_RXDATAOFFSET: +! activity_ri2(); +! break; +! case S_RXDATAPREPARE: +! activity_rie1(); +! break; +! case S_RXDATAREADY: +! activity_ri3(); +! break; +! case S_RXDATALISTEN: +! activity_rie2(); +! break; +! case S_RXDATA: +! activity_rie3(); +! break; +! case S_TXACKOFFSET: +! activity_ri6(); +! break; +! case S_TXACKPREPARE: +! activity_rie4(); +! break; +! case S_TXACKREADY: +! activity_ri7(); +! break; +! case S_TXACKDELAY: +! activity_rie5(); +! break; +! case S_TXACK: +! activity_rie6(); +! break; +! default: +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_TIMERFIRES, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! break; +! } +! ieee154e_dbg.num_timer++; +! } +! +! /** +! \brief Indicates the radio just received the first byte of a packet. +! +! This function executes in ISR mode. +! */ +! void ieee154e_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { +! if (ieee154e_vars.isSync==FALSE) { +! activity_synchronize_startOfFrame(capturedTime); +! } else { +! switch (ieee154e_vars.state) { +! case S_TXDATADELAY: +! activity_ti4(capturedTime); +! break; +! case S_RXACKREADY: +! /* +! It is possible to receive in this state for radio where there is no +! way of differentiated between "ready to listen" and "listening" +! (e.g. CC2420). We must therefore expect to the start of a packet in +! this "ready" state. +! */ +! // no break! +! case S_RXACKLISTEN: +! activity_ti8(capturedTime); +! break; +! case S_RXDATAREADY: +! /* +! Similarly as above. +! */ +! // no break! +! case S_RXDATALISTEN: +! activity_ri4(capturedTime); +! break; +! case S_TXACKDELAY: +! activity_ri8(capturedTime); +! break; +! default: +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_NEWSLOT, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! break; +! } +! } +! ieee154e_dbg.num_startOfFrame++; +! } +! +! /** +! \brief Indicates the radio just received the last byte of a packet. +! +! This function executes in ISR mode. +! */ +! void ieee154e_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { +! if (ieee154e_vars.isSync==FALSE) { +! activity_synchronize_endOfFrame(capturedTime); +! } else { +! switch (ieee154e_vars.state) { +! case S_TXDATA: +! activity_ti5(capturedTime); +! break; +! case S_RXACK: +! activity_ti9(capturedTime); +! break; +! case S_RXDATA: +! activity_ri5(capturedTime); +! break; +! case S_TXACK: +! activity_ri9(capturedTime); +! break; +! default: +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDOFFRAME, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! break; +! } +! } +! ieee154e_dbg.num_endOfFrame++; +! } +! +! //======= misc +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_asn(void) { +! asn_t output; +! output.byte4 = ieee154e_vars.asn.byte4; +! output.bytes2and3 = ieee154e_vars.asn.bytes2and3; +! output.bytes0and1 = ieee154e_vars.asn.bytes0and1; +! openserial_printStatus(STATUS_ASN,(uint8_t*)&output,sizeof(output)); +! return TRUE; +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_isSync(void) { +! uint8_t output=0; +! output = ieee154e_vars.isSync; +! openserial_printStatus(STATUS_ISSYNC,(uint8_t*)&output,sizeof(uint8_t)); +! return TRUE; +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_macStats(void) { +! // send current stats over serial +! ieee154e_stats.dutyCycle/=(float)SUPERFRAME_LENGTH; //avg on the all slots of a frame +! ieee154e_stats.dutyCycle/=STATUS_MAX;//because this is executed once every 10 times of debugprint +! ieee154e_stats.dutyCycle*=100.0;//as is a percentage +! openserial_printStatus(STATUS_MACSTATS,(uint8_t*)&ieee154e_stats,sizeof(ieee154e_stats_t)); +! ieee154e_stats.dutyCycle=0; //reset for the next superframe. +! +! return TRUE; +! } +! +! //=========================== private ========================================= +! +! //======= SYNCHRONIZING +! +! port_INLINE void activity_synchronize_newSlot(void) { +! // I'm in the middle of receiving a packet +! if (ieee154e_vars.state==S_SYNCRX) { +! return; +! } +! +! // if this is the first time I call this function while not synchronized, +! // switch on the radio in Rx mode +! if (ieee154e_vars.state!=S_SYNCLISTEN) { +! // change state +! changeState(S_SYNCLISTEN); +! +! // turn off the radio (in case it wasn't yet) +! radio_rfOff(); +! +! // configure the radio to listen to the default synchronizing channel +! radio_setFrequency(SYNCHRONIZING_CHANNEL); +! +! // update record of current channel +! ieee154e_vars.freq = SYNCHRONIZING_CHANNEL; +! +! // switch on the radio in Rx mode. +! radio_rxEnable(); +! ieee154e_vars.radioOnInit=radio_getTimerValue(); +! ieee154e_vars.radioOnThisSlot=TRUE; +! radio_rxNow(); +! } +! +! // increment ASN (used only to schedule serial activity) +! incrementAsnOffset(); +! +! // to be able to receive and transmist serial even when not synchronized +! // take turns every 8 slots sending and receiving +! if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0000) { +! openserial_stop(); +! openserial_startOutput(); +! } else if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0008) { +! openserial_stop(); +! openserial_startInput(); +! } +! } +! +! port_INLINE void activity_synchronize_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { +! +! // don't care about packet if I'm not listening +! if (ieee154e_vars.state!=S_SYNCLISTEN) { +! return; +! } +! +! // change state +! changeState(S_SYNCRX); +! +! // stop the serial +! openserial_stop(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // record the captured time (for sync) +! ieee154e_vars.syncCapturedTime = capturedTime; +! } +! +! port_INLINE void activity_synchronize_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { +! ieee802154_header_iht ieee802514_header; +! uint16_t lenIE=0;//len of IEs being received if any. +! +! // check state +! if (ieee154e_vars.state!=S_SYNCRX) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDFRAME_SYNC, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)0); +! // abort +! endSlot(); +! } +! +! // change state +! changeState(S_SYNCPROC); +! +! // get a buffer to put the (received) frame in +! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.dataReceived==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; +! +! /* +! The do-while loop that follows is a little parsing trick. +! Because it contains a while(0) condition, it gets executed only once. +! The behavior is: +! - if a break occurs inside the do{} body, the error code below the loop +! gets executed. This indicates something is wrong with the packet being +! parsed. +! - if a return occurs inside the do{} body, the error code below the loop +! does not get executed. This indicates the received packet is correct. +! */ +! do { // this "loop" is only executed once +! +! // retrieve the received data frame from the radio's Rx buffer +! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); +! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, +! &ieee154e_vars.dataReceived->length, +! sizeof(ieee154e_vars.dataReceived->packet), +! &ieee154e_vars.dataReceived->l1_rssi, +! &ieee154e_vars.dataReceived->l1_lqi, +! &ieee154e_vars.dataReceived->l1_crc); +! +! // break if packet too short +! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX) { +! // break from the do-while loop and execute abort code below +! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, +! (errorparameter_t)0, +! ieee154e_vars.dataReceived->length); +! break; +! } +! +! // toss CRC (2 last bytes) +! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); +! +! // break if invalid CRC +! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { +! // break from the do-while loop and execute abort code below +! break; +! } +! +! // parse the IEEE802.15.4 header (synchronize, end of frame) +! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); +! +! // break if invalid IEEE802.15.4 header +! if (ieee802514_header.valid==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // store header details in packet buffer +! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; +! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; +! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); +! +! // toss the IEEE802.15.4 header -- this does not include IEs as they are processed +! // next. +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); +! +! // handle IEs -- xv poipoi +! // break if invalid ADV +! if ((ieee802514_header.valid==TRUE && +! ieee802514_header.ieListPresent==TRUE && +! ieee802514_header.frameType==IEEE154_TYPE_BEACON && +! packetfunctions_sameAddress(&ieee802514_header.panid,idmanager_getMyID(ADDR_PANID)) && +! ieee154e_processIEs(ieee154e_vars.dataReceived,&lenIE))==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // turn off the radio +! radio_rfOff(); +! //compute radio duty cycle +! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); +! +! // toss the IEs including Synch +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,lenIE); +! +! // synchronize (for the first time) to the sender's ADV +! synchronizePacket(ieee154e_vars.syncCapturedTime); +! +! // declare synchronized +! changeIsSync(TRUE); +! +! // log the info +! openserial_printInfo(COMPONENT_IEEE802154E,ERR_SYNCHRONIZED, +! (errorparameter_t)ieee154e_vars.slotOffset, +! (errorparameter_t)0); +! +! // send received ADV up the stack so RES can update statistics (synchronizing) +! notif_receive(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // official end of synchronization +! endSlot(); +! +! // everything went well, return here not to execute the error code below +! return; +! +! } while (0); +! +! // free the (invalid) received data buffer so RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // return to listening state +! changeState(S_SYNCLISTEN); +! } +! +! //xv poipoi - IE Handling +! port_INLINE bool ieee154e_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE) +! { +! uint8_t ptr,byte0,byte1; +! uint8_t temp_8b,gr_elem_id,subid; +! uint16_t temp_16b,len,sublen; +! volatile PORT_SIGNED_INT_WIDTH timeCorrection; +! +! ptr=0; +! //candidate IE header if type ==0 header IE if type==1 payload IE +! temp_8b = *((uint8_t*)(pkt->payload)+ptr); +! ptr++; +! temp_16b = temp_8b + ((*((uint8_t*)(pkt->payload)+ptr))<< 8); +! ptr++; +! *lenIE = ptr; +! if ((temp_16b & IEEE802154E_DESC_TYPE_PAYLOAD_IE) == IEEE802154E_DESC_TYPE_PAYLOAD_IE){ +! //payload IE - last bit is 1 +! len=(temp_16b & IEEE802154E_DESC_LEN_PAYLOAD_IE_MASK)>>IEEE802154E_DESC_LEN_PAYLOAD_IE_SHIFT; +! gr_elem_id= (temp_16b & IEEE802154E_DESC_GROUPID_PAYLOAD_IE_MASK)>>IEEE802154E_DESC_GROUPID_PAYLOAD_IE_SHIFT; +! }else { +! //header IE - last bit is 0 +! len=(temp_16b & IEEE802154E_DESC_LEN_HEADER_IE_MASK)>>IEEE802154E_DESC_LEN_HEADER_IE_SHIFT; +! gr_elem_id = (temp_16b & IEEE802154E_DESC_ELEMENTID_HEADER_IE_MASK)>>IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT; +! } +! +! *lenIE += len; +! //now determine sub elements if any +! switch(gr_elem_id){ +! //this is the only groupID that we parse. See page 82. +! case IEEE802154E_MLME_IE_GROUPID: +! //IE content can be any of the sub-IEs. Parse and see which +! do{ +! //read sub IE header +! temp_8b = *((uint8_t*)(pkt->payload)+ptr); +! ptr = ptr + 1; +! temp_16b = temp_8b +(*((uint8_t*)(pkt->payload)+ptr) << 8); +! ptr = ptr + 1; +! len = len - 2; //remove header fields len +! if ((temp_16b & IEEE802154E_DESC_TYPE_LONG) == IEEE802154E_DESC_TYPE_LONG){ +! //long sub-IE - last bit is 1 +! sublen=(temp_16b & IEEE802154E_DESC_LEN_LONG_MLME_IE_MASK)>>IEEE802154E_DESC_LEN_LONG_MLME_IE_SHIFT; +! subid= (temp_16b & IEEE802154E_DESC_SUBID_LONG_MLME_IE_MASK)>>IEEE802154E_DESC_SUBID_LONG_MLME_IE_SHIFT; +! }else { +! //short IE - last bit is 0 +! sublen =(temp_16b & IEEE802154E_DESC_LEN_SHORT_MLME_IE_MASK)>>IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; +! subid = (temp_16b & IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK)>>IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT; +! } +! switch(subid){ +! case IEEE802154E_MLME_SYNC_IE_SUBID: +! //content is ASN and Join Priority +! if (idmanager_getIsDAGroot()==FALSE) { +! asnStoreFromAdv((uint8_t*)(pkt->payload)+ptr); +! ptr = ptr + 5; //add ASN len +! joinPriorityStoreFromAdv(*((uint8_t*)(pkt->payload)+ptr)); +! ptr = ptr + 1; +! } +! break; +! case IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID: +! ieee154e_processSlotframeLinkIE(pkt,&ptr); +! break; +! case IEEE802154E_MLME_TIMESLOT_IE_SUBID: +! //TODO +! break; +! default: +! return FALSE; +! break; +! } +! len = len - sublen; +! } while(len>0); +! +! break; +! //the rest are elementID +! case IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID: +! //IE content is time correction -- apply the time correction on ack received. +! if (idmanager_getIsDAGroot()==FALSE && +! neighbors_isPreferredParent(&(pkt->l2_nextORpreviousHop)) ) { +! byte0 = *((uint8_t*)(pkt->payload)+ptr); +! ptr++; +! byte1 = *((uint8_t*)(pkt->payload)+ptr); +! ptr++; +! +! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_RADIOTIMER_WIDTH)byte1<<8 | (PORT_RADIOTIMER_WIDTH)byte0); +! timeCorrection /= US_PER_TICK; +! timeCorrection = -timeCorrection; +! synchronizeAck(timeCorrection); +! } +! break; +! default: +! *lenIE = 0;//no header or not recognized. +! return FALSE; +! } +! if (*lenIE>127) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_HEADER_TOO_LONG, +! (errorparameter_t)*lenIE, +! (errorparameter_t)1); +! } +! return TRUE; +! } +! +! port_INLINE void ieee154e_processSlotframeLinkIE(OpenQueueEntry_t* pkt,uint8_t * ptr){ +! uint8_t numSlotFrames,i,j,localptr; +! slotframelink_IE_t sfInfo; +! linkInfo_subIE_t linkInfo; +! localptr=*ptr; +! // number of slot frames 1B +! numSlotFrames = *((uint8_t*)(pkt->payload)+localptr); +! localptr++; +! // for each slotframe +! i=0; +! while(i < numSlotFrames){ +! //1-slotftramehandle 1B +! sfInfo.slotframehandle=*((uint8_t*)(pkt->payload)+localptr); +! localptr++; +! //2-slotframe size 2B +! sfInfo.slotframesize = *((uint8_t*)(pkt->payload)+localptr); +! localptr++; +! sfInfo.slotframesize |= (*((uint8_t*)(pkt->payload)+localptr))<<8; +! localptr++;; +! //3-number of links 1B +! sfInfo.numlinks= *((uint8_t*)(pkt->payload)+localptr); +! localptr++; +! +! for (j=0;jpayload)+localptr); +! localptr++; +! linkInfo.tsNum |= (*((uint8_t*)(pkt->payload)+localptr))<<8; +! localptr++; +! //Ch.Offset 2B +! linkInfo.choffset = *((uint8_t*)(pkt->payload)+localptr); +! localptr++; +! linkInfo.choffset |= (*((uint8_t*)(pkt->payload)+localptr))<<8; +! localptr++; +! //LinkOption bitmap 1B +! linkInfo.linkoptions = *((uint8_t*)(pkt->payload)+localptr); +! localptr++; +! //xv poipoi +! //TODO - inform schedule of that link so it can update if needed. +! } +! i++; +! } +! *ptr=localptr; +! } +! +! //======= TX +! +! port_INLINE void activity_ti1ORri1(void) { +! cellType_t cellType; +! open_addr_t neighbor; +! uint8_t i; +! synch_IE_t syn_IE; +! +! // increment ASN (do this first so debug pins are in sync) +! incrementAsnOffset(); +! +! // wiggle debug pins +! debugpins_slot_toggle(); +! if (ieee154e_vars.slotOffset==0) { +! debugpins_frame_toggle(); +! } +! +! // desynchronize if needed +! if (idmanager_getIsDAGroot()==FALSE) { +! ieee154e_vars.deSyncTimeout--; +! if (ieee154e_vars.deSyncTimeout==0) { +! // declare myself desynchronized +! changeIsSync(FALSE); +! +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_DESYNCHRONIZED, +! (errorparameter_t)ieee154e_vars.slotOffset, +! (errorparameter_t)0); +! +! // update the statistics +! ieee154e_stats.numDeSync++; +! +! // abort +! endSlot(); +! return; +! } +! } +! +! // if the previous slot took too long, we will not be in the right state +! if (ieee154e_vars.state!=S_SLEEP) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_STARTSLOT, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! // abort +! endSlot(); +! return; +! } +! +! if (ieee154e_vars.slotOffset==ieee154e_vars.nextActiveSlotOffset) { +! // this is the next active slot +! +! // advance the schedule +! schedule_advanceSlot(); +! +! // find the next one +! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); +! } else { +! // this is NOT the next active slot, abort +! // stop using serial +! openserial_stop(); +! // abort the slot +! endSlot(); +! //start outputing serial +! openserial_startOutput(); +! return; +! } +! +! // check the schedule to see what type of slot this is +! cellType = schedule_getType(); +! switch (cellType) { +! case CELLTYPE_ADV: +! // stop using serial +! openserial_stop(); +! // look for an ADV packet in the queue +! ieee154e_vars.dataToSend = openqueue_macGetAdvPacket(); +! if (ieee154e_vars.dataToSend==NULL) { // I will be listening for an ADV +! // change state +! changeState(S_RXDATAOFFSET); +! // arm rt1 +! radiotimer_schedule(DURATION_rt1); +! } else { // I will be sending an ADV +! // change state +! changeState(S_TXDATAOFFSET); +! // change owner +! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; +! //copy synch IE -- should be Little endian??? +! // fill in the ASN field of the ADV +! ieee154e_getAsn(syn_IE.asn); +! syn_IE.join_priority = neighbors_getMyDAGrank()/(2*MINHOPRANKINCREASE); //poipoi -- use dagrank(rank) +! +! memcpy(ieee154e_vars.dataToSend->l2_ASNpayload,&syn_IE,sizeof(synch_IE_t)); +! +! // record that I attempt to transmit this packet +! ieee154e_vars.dataToSend->l2_numTxAttempts++; +! // arm tt1 +! radiotimer_schedule(DURATION_tt1); +! } +! break; +! case CELLTYPE_TXRX: +! case CELLTYPE_TX: +! // stop using serial +! openserial_stop(); +! // check whether we can send +! if (schedule_getOkToSend()) { +! schedule_getNeighbor(&neighbor); +! ieee154e_vars.dataToSend = openqueue_macGetDataPacket(&neighbor); +! } else { +! ieee154e_vars.dataToSend = NULL; +! } +! if (ieee154e_vars.dataToSend!=NULL) { // I have a packet to send +! // change state +! changeState(S_TXDATAOFFSET); +! // change owner +! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; +! // record that I attempt to transmit this packet +! ieee154e_vars.dataToSend->l2_numTxAttempts++; +! // arm tt1 +! radiotimer_schedule(DURATION_tt1); +! } else if (cellType==CELLTYPE_TX){ +! // abort +! endSlot(); +! } +! if (cellType==CELLTYPE_TX || +! (cellType==CELLTYPE_TXRX && ieee154e_vars.dataToSend!=NULL)) { +! break; +! } +! case CELLTYPE_RX: +! // stop using serial +! openserial_stop(); +! // change state +! changeState(S_RXDATAOFFSET); +! // arm rt1 +! radiotimer_schedule(DURATION_rt1); +! break; +! case CELLTYPE_SERIALRX: +! // stop using serial +! openserial_stop(); +! // abort the slot +! endSlot(); +! //start inputting serial data +! openserial_startInput(); +! //this is to emulate a set of serial input slots without having the slotted structure. +! +! radio_setTimerPeriod(TsSlotDuration*(NUMSERIALRX)); +! +! //increase ASN by NUMSERIALRX-1 slots as at this slot is already incremented by 1 +! for (i=0;ipayload, +! ieee154e_vars.dataToSend->length); +! +! // enable the radio in Tx mode. This does not send the packet. +! radio_txEnable(); +! ieee154e_vars.radioOnInit=radio_getTimerValue(); +! ieee154e_vars.radioOnThisSlot=TRUE; +! // arm tt2 +! radiotimer_schedule(DURATION_tt2); +! +! // change state +! changeState(S_TXDATAREADY); +! } +! +! port_INLINE void activity_tie1(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXDATAPREPARE_OVERFLOW, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti3(void) { +! // change state +! changeState(S_TXDATADELAY); +! +! // arm tt3 +! radiotimer_schedule(DURATION_tt3); +! +! // give the 'go' to transmit +! radio_txNow(); +! } +! +! port_INLINE void activity_tie2(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIO_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! //start of frame interrupt +! port_INLINE void activity_ti4(PORT_RADIOTIMER_WIDTH capturedTime) { +! // change state +! changeState(S_TXDATA); +! +! // cancel tt3 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // arm tt4 +! radiotimer_schedule(DURATION_tt4); +! } +! +! port_INLINE void activity_tie3(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti5(PORT_RADIOTIMER_WIDTH capturedTime) { +! bool listenForAck; +! +! // change state +! changeState(S_RXACKOFFSET); +! +! // cancel tt4 +! radiotimer_cancel(); +! +! // turn off the radio +! radio_rfOff(); +! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // decides whether to listen for an ACK +! if (packetfunctions_isBroadcastMulticast(&ieee154e_vars.dataToSend->l2_nextORpreviousHop)==TRUE) { +! listenForAck = FALSE; +! } else { +! listenForAck = TRUE; +! } +! +! if (listenForAck==TRUE) { +! // arm tt5 +! radiotimer_schedule(DURATION_tt5); +! } else { +! // indicate succesful Tx to schedule to keep statistics +! schedule_indicateTx(&ieee154e_vars.asn,TRUE); +! // indicate to upper later the packet was sent successfully +! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); +! // reset local variable +! ieee154e_vars.dataToSend = NULL; +! // abort +! endSlot(); +! } +! } +! +! port_INLINE void activity_ti6(void) { +! // change state +! changeState(S_RXACKPREPARE); +! +! // calculate the frequency to transmit on +! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); +! +! // configure the radio for that frequency +! radio_setFrequency(ieee154e_vars.freq); +! +! // enable the radio in Rx mode. The radio is not actively listening yet. +! radio_rxEnable(); +! //caputre init of radio for duty cycle calculation +! ieee154e_vars.radioOnInit=radio_getTimerValue(); +! ieee154e_vars.radioOnThisSlot=TRUE; +! // arm tt6 +! radiotimer_schedule(DURATION_tt6); +! +! // change state +! changeState(S_RXACKREADY); +! } +! +! port_INLINE void activity_tie4(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXACKPREPARE_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti7(void) { +! // change state +! changeState(S_RXACKLISTEN); +! +! // start listening +! radio_rxNow(); +! +! // arm tt7 +! radiotimer_schedule(DURATION_tt7); +! } +! +! port_INLINE void activity_tie5(void) { +! // indicate transmit failed to schedule to keep stats +! schedule_indicateTx(&ieee154e_vars.asn,FALSE); +! +! // decrement transmits left counter +! ieee154e_vars.dataToSend->l2_retriesLeft--; +! +! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { +! // indicate tx fail if no more retries left +! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); +! } else { +! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component +! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; +! } +! +! // reset local variable +! ieee154e_vars.dataToSend = NULL; +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti8(PORT_RADIOTIMER_WIDTH capturedTime) { +! // change state +! changeState(S_RXACK); +! +! // cancel tt7 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // arm tt8 +! radiotimer_schedule(DURATION_tt8); +! } +! +! port_INLINE void activity_tie6(void) { +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ti9(PORT_RADIOTIMER_WIDTH capturedTime) { +! ieee802154_header_iht ieee802514_header; +! volatile PORT_SIGNED_INT_WIDTH timeCorrection; +! uint16_t lenIE; +! +! // change state +! changeState(S_TXPROC); +! +! // cancel tt8 +! radiotimer_cancel(); +! +! // turn off the radio +! radio_rfOff(); +! //compute tics radio on. +! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // get a buffer to put the (received) ACK in +! ieee154e_vars.ackReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.ackReceived==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.ackReceived->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.ackReceived->owner = COMPONENT_IEEE802154E; +! +! /* +! The do-while loop that follows is a little parsing trick. +! Because it contains a while(0) condition, it gets executed only once. +! Below the do-while loop is some code to cleans up the ack variable. +! Anywhere in the do-while loop, a break statement can be called to jump to +! the clean up code early. If the loop ends without a break, the received +! packet was correct. If it got aborted early (through a break), the packet +! was faulty. +! */ +! do { // this "loop" is only executed once +! +! // retrieve the received ack frame from the radio's Rx buffer +! ieee154e_vars.ackReceived->payload = &(ieee154e_vars.ackReceived->packet[FIRST_FRAME_BYTE]); +! radio_getReceivedFrame( ieee154e_vars.ackReceived->payload, +! &ieee154e_vars.ackReceived->length, +! sizeof(ieee154e_vars.ackReceived->packet), +! &ieee154e_vars.ackReceived->l1_rssi, +! &ieee154e_vars.ackReceived->l1_lqi, +! &ieee154e_vars.ackReceived->l1_crc); +! +! // break if wrong length +! if (ieee154e_vars.ackReceived->lengthlength>LENGTH_IEEE154_MAX) { +! // break from the do-while loop and execute the clean-up code below +! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, +! (errorparameter_t)1, +! ieee154e_vars.ackReceived->length); +! +! break; +! } +! +! // toss CRC (2 last bytes) +! packetfunctions_tossFooter( ieee154e_vars.ackReceived, LENGTH_CRC); +! +! // break if invalid CRC +! if (ieee154e_vars.ackReceived->l1_crc==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // parse the IEEE802.15.4 header (RX ACK) +! ieee802154_retrieveHeader(ieee154e_vars.ackReceived,&ieee802514_header); +! +! // break if invalid IEEE802.15.4 header +! if (ieee802514_header.valid==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // store header details in packet buffer +! ieee154e_vars.ackReceived->l2_frameType = ieee802514_header.frameType; +! ieee154e_vars.ackReceived->l2_dsn = ieee802514_header.dsn; +! memcpy(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); +! +! // toss the IEEE802.15.4 header +! packetfunctions_tossHeader(ieee154e_vars.ackReceived,ieee802514_header.headerLength); +! +! // break if invalid ACK +! if (isValidAck(&ieee802514_header,ieee154e_vars.dataToSend)==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! //hanlde IEs --xv poipoi +! if (ieee802514_header.ieListPresent==FALSE){ +! break; //ack should contain IEs. +! } +! +! if (ieee154e_processIEs(ieee154e_vars.ackReceived,&lenIE)==FALSE){ +! //invalid IEs on ACK. +! break; +! } +! +! // toss the IEs including ACK -- xv poipoi +! packetfunctions_tossHeader(ieee154e_vars.ackReceived,lenIE); +! +! // inform schedule of successful transmission +! schedule_indicateTx(&ieee154e_vars.asn,TRUE); +! +! // inform upper layer +! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); +! ieee154e_vars.dataToSend = NULL; +! +! // in any case, execute the clean-up code below (processing of ACK done) +! } while (0); +! +! // free the received ack so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); +! +! // clear local variable +! ieee154e_vars.ackReceived = NULL; +! +! // official end of Tx slot +! endSlot(); +! } +! +! //======= RX +! +! port_INLINE void activity_ri2(void) { +! // change state +! changeState(S_RXDATAPREPARE); +! +! // calculate the frequency to transmit on +! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); +! +! // configure the radio for that frequency +! radio_setFrequency(ieee154e_vars.freq); +! +! // enable the radio in Rx mode. The radio does not actively listen yet. +! radio_rxEnable(); +! ieee154e_vars.radioOnInit=radio_getTimerValue(); +! ieee154e_vars.radioOnThisSlot=TRUE; +! +! // arm rt2 +! radiotimer_schedule(DURATION_rt2); +! +! // change state +! changeState(S_RXDATAREADY); +! } +! +! port_INLINE void activity_rie1(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXDATAPREPARE_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri3(void) { +! // change state +! changeState(S_RXDATALISTEN); +! +! // give the 'go' to receive +! radio_rxNow(); +! +! // arm rt3 +! radiotimer_schedule(DURATION_rt3); +! } +! +! port_INLINE void activity_rie2(void) { +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri4(PORT_RADIOTIMER_WIDTH capturedTime) { +! +! // change state +! changeState(S_RXDATA); +! +! // cancel rt3 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // record the captured time to sync +! ieee154e_vars.syncCapturedTime = capturedTime; +! +! radiotimer_schedule(DURATION_rt4); +! } +! +! port_INLINE void activity_rie3(void) { +! +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri5(PORT_RADIOTIMER_WIDTH capturedTime) { +! ieee802154_header_iht ieee802514_header; +! uint16_t lenIE=0; +! +! // change state +! changeState(S_TXACKOFFSET); +! +! // cancel rt4 +! radiotimer_cancel(); +! +! // turn off the radio +! //radio_rfOff(); +! ieee154e_vars.radioOnTics+=radio_getTimerValue()-ieee154e_vars.radioOnInit; +! // get a buffer to put the (received) data in +! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.dataReceived==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; +! +! /* +! The do-while loop that follows is a little parsing trick. +! Because it contains a while(0) condition, it gets executed only once. +! The behavior is: +! - if a break occurs inside the do{} body, the error code below the loop +! gets executed. This indicates something is wrong with the packet being +! parsed. +! - if a return occurs inside the do{} body, the error code below the loop +! does not get executed. This indicates the received packet is correct. +! */ +! do { // this "loop" is only executed once +! +! // retrieve the received data frame from the radio's Rx buffer +! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); +! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, +! &ieee154e_vars.dataReceived->length, +! sizeof(ieee154e_vars.dataReceived->packet), +! &ieee154e_vars.dataReceived->l1_rssi, +! &ieee154e_vars.dataReceived->l1_lqi, +! &ieee154e_vars.dataReceived->l1_crc); +! +! // break if wrong length +! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX ) { +! // jump to the error code below this do-while loop +! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, +! (errorparameter_t)2, +! ieee154e_vars.dataReceived->length); +! break; +! } +! +! // toss CRC (2 last bytes) +! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); +! +! // if CRC doesn't check, stop +! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { +! // jump to the error code below this do-while loop +! break; +! } +! +! // parse the IEEE802.15.4 header (RX DATA) +! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); +! +! // break if invalid IEEE802.15.4 header +! if (ieee802514_header.valid==FALSE) { +! // break from the do-while loop and execute the clean-up code below +! break; +! } +! +! // store header details in packet buffer +! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; +! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; +! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); +! +! // toss the IEEE802.15.4 header +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); +! +! // handle IEs xv poipoi +! //reset join priority +! +! if ((ieee802514_header.valid==TRUE && +! ieee802514_header.ieListPresent==TRUE && +! packetfunctions_sameAddress(&ieee802514_header.panid,idmanager_getMyID(ADDR_PANID)) && +! ieee154e_processIEs(ieee154e_vars.dataReceived,&lenIE))==FALSE) { +! //log that the packet is not carrying IEs +! } +! +! // toss the IEs including Synch +! packetfunctions_tossHeader(ieee154e_vars.dataReceived,lenIE); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // if I just received an invalid frame, stop +! if (isValidRxFrame(&ieee802514_header)==FALSE) { +! // jump to the error code below this do-while loop +! break; +! } +! +! // check if ack requested +! if (ieee802514_header.ackRequested==1) { +! // arm rt5 +! radiotimer_schedule(DURATION_rt5); +! } else { +! // synchronize to the received packet iif I'm not a DAGroot and this is my preferred parent +! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { +! synchronizePacket(ieee154e_vars.syncCapturedTime); +! } +! // indicate reception to upper layer (no ACK asked) +! notif_receive(ieee154e_vars.dataReceived); +! // reset local variable +! ieee154e_vars.dataReceived = NULL; +! // abort +! endSlot(); +! } +! +! // everything went well, return here not to execute the error code below +! return; +! +! } while(0); +! +! // free the (invalid) received data so RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri6(void) { +! PORT_SIGNED_INT_WIDTH timeCorrection; +! header_IE_descriptor_t header_desc; +! +! // change state +! changeState(S_TXACKPREPARE); +! +! // get a buffer to put the ack to send in +! ieee154e_vars.ackToSend = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); +! if (ieee154e_vars.ackToSend==NULL) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // indicate we received a packet anyway (we don't want to loose any) +! notif_receive(ieee154e_vars.dataReceived); +! // free local variable +! ieee154e_vars.dataReceived = NULL; +! // abort +! endSlot(); +! return; +! } +! +! // declare ownership over that packet +! ieee154e_vars.ackToSend->creator = COMPONENT_IEEE802154E; +! ieee154e_vars.ackToSend->owner = COMPONENT_IEEE802154E; +! +! // calculate the time timeCorrection (this is the time when the packet arrive w.r.t the time it should be. +! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.syncCapturedTime-(PORT_SIGNED_INT_WIDTH)TsTxOffset); +! +! // add the payload to the ACK (i.e. the timeCorrection) +! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(ack_timecorrection_IE_t)); +! timeCorrection = -timeCorrection; +! timeCorrection *= US_PER_TICK; +! ieee154e_vars.ackToSend->payload[0] = (uint8_t)((((PORT_RADIOTIMER_WIDTH)timeCorrection) ) & 0xff); +! ieee154e_vars.ackToSend->payload[1] = (uint8_t)((((PORT_RADIOTIMER_WIDTH)timeCorrection)>>8) & 0xff); +! +! // add header IE header -- xv poipoi -- pkt is filled in reverse order.. +! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(header_IE_descriptor_t)); +! //create the header for ack IE +! header_desc.length_elementid_type=(sizeof(ack_timecorrection_IE_t)<< IEEE802154E_DESC_LEN_HEADER_IE_SHIFT)| +! (IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID << IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT)| +! IEEE802154E_DESC_TYPE_SHORT; +! memcpy(ieee154e_vars.ackToSend->payload,&header_desc,sizeof(header_IE_descriptor_t)); +! +! // prepend the IEEE802.15.4 header to the ACK +! ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; +! ieee154e_vars.ackToSend->l2_dsn = ieee154e_vars.dataReceived->l2_dsn; +! ieee802154_prependHeader(ieee154e_vars.ackToSend, +! ieee154e_vars.ackToSend->l2_frameType, +! IEEE154_IELIST_YES,//ie in ack +! IEEE154_FRAMEVERSION,//enhanced ack +! IEEE154_SEC_NO_SECURITY, +! ieee154e_vars.dataReceived->l2_dsn, +! &(ieee154e_vars.dataReceived->l2_nextORpreviousHop) +! ); +! +! // space for 2-byte CRC +! packetfunctions_reserveFooterSize(ieee154e_vars.ackToSend,2); +! +! // calculate the frequency to transmit on +! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); +! +! // configure the radio for that frequency +! radio_setFrequency(ieee154e_vars.freq); +! +! // load the packet in the radio's Tx buffer +! radio_loadPacket(ieee154e_vars.ackToSend->payload, +! ieee154e_vars.ackToSend->length); +! +! // enable the radio in Tx mode. This does not send that packet. +! radio_txEnable(); +! ieee154e_vars.radioOnInit=radio_getTimerValue(); +! ieee154e_vars.radioOnThisSlot=TRUE; +! // arm rt6 +! radiotimer_schedule(DURATION_rt6); +! +! // change state +! changeState(S_TXACKREADY); +! } +! +! port_INLINE void activity_rie4(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXACKPREPARE_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri7(void) { +! // change state +! changeState(S_TXACKDELAY); +! +! // arm rt7 +! radiotimer_schedule(DURATION_rt7); +! +! // give the 'go' to transmit +! radio_txNow(); +! } +! +! port_INLINE void activity_rie5(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIOTX_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri8(PORT_RADIOTIMER_WIDTH capturedTime) { +! // change state +! changeState(S_TXACK); +! +! // cancel rt7 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // arm rt8 +! radiotimer_schedule(DURATION_rt8); +! } +! +! port_INLINE void activity_rie6(void) { +! // log the error +! openserial_printError(COMPONENT_IEEE802154E,ERR_WDACKDURATION_OVERFLOWS, +! (errorparameter_t)ieee154e_vars.state, +! (errorparameter_t)ieee154e_vars.slotOffset); +! +! // abort +! endSlot(); +! } +! +! port_INLINE void activity_ri9(PORT_RADIOTIMER_WIDTH capturedTime) { +! // change state +! changeState(S_RXPROC); +! +! // cancel rt8 +! radiotimer_cancel(); +! +! // record the captured time +! ieee154e_vars.lastCapturedTime = capturedTime; +! +! // free the ack we just sent so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); +! +! // clear local variable +! ieee154e_vars.ackToSend = NULL; +! +! // synchronize to the received packet +! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { +! synchronizePacket(ieee154e_vars.syncCapturedTime); +! } +! +! // inform upper layer of reception (after ACK sent) +! notif_receive(ieee154e_vars.dataReceived); +! +! // clear local variable +! ieee154e_vars.dataReceived = NULL; +! +! // official end of Rx slot +! endSlot(); +! } +! +! //======= frame validity check +! +! /** +! \brief Decides whether the packet I just received is valid received frame. +! +! A valid Rx frame satisfies the following constraints: +! - its IEEE802.15.4 header is well formatted +! - it's a DATA of BEACON frame (i.e. not ACK and not COMMAND) +! - it's sent on the same PANid as mine +! - it's for me (unicast or broadcast) +! +! \param[in] ieee802514_header IEEE802.15.4 header of the packet I just received +! +! \returns TRUE if packet is valid received frame, FALSE otherwise +! */ +! port_INLINE bool isValidRxFrame(ieee802154_header_iht* ieee802514_header) { +! return ieee802514_header->valid==TRUE && \ +! ( +! ieee802514_header->frameType==IEEE154_TYPE_DATA || +! ieee802514_header->frameType==IEEE154_TYPE_BEACON +! ) && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! ( +! idmanager_isMyAddress(&ieee802514_header->dest) || +! packetfunctions_isBroadcastMulticast(&ieee802514_header->dest) +! ); +! } +! +! /** +! \brief Decides whether the packet I just received is a valid ACK. +! +! A packet is a valid ACK if it satisfies the following conditions: +! - the IEEE802.15.4 header is valid +! - the frame type is 'ACK' +! - the sequence number in the ACK matches the sequence number of the packet sent +! - the ACK contains my PANid +! - the packet is unicast to me +! - the packet comes from the neighbor I sent the data to +! +! \param[in] ieee802514_header IEEE802.15.4 header of the packet I just received +! \param[in] packetSent points to the packet I just sent +! +! \returns TRUE if packet is a valid ACK, FALSE otherwise. +! */ +! port_INLINE bool isValidAck(ieee802154_header_iht* ieee802514_header, OpenQueueEntry_t* packetSent) { +! /* +! return ieee802514_header->valid==TRUE && \ +! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ +! ieee802514_header->dsn==packetSent->l2_dsn && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! idmanager_isMyAddress(&ieee802514_header->dest) && \ +! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); +! */ +! // poipoi don't check for seq num +! return ieee802514_header->valid==TRUE && \ +! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ +! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ +! idmanager_isMyAddress(&ieee802514_header->dest) && \ +! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); +! } +! +! //======= ASN handling +! +! port_INLINE void incrementAsnOffset(void) { +! // increment the asn +! ieee154e_vars.asn.bytes0and1++; +! if (ieee154e_vars.asn.bytes0and1==0) { +! ieee154e_vars.asn.bytes2and3++; +! if (ieee154e_vars.asn.bytes2and3==0) { +! ieee154e_vars.asn.byte4++; +! } +! } +! // increment the offsets +! ieee154e_vars.slotOffset = (ieee154e_vars.slotOffset+1)%schedule_getFrameLength(); +! ieee154e_vars.asnOffset = (ieee154e_vars.asnOffset+1)%16; +! } +! +! //from upper layer that want to send the ASN to compute timing or latency +! port_INLINE void ieee154e_getAsn(uint8_t* array) { +! array[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); +! array[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); +! array[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); +! array[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); +! array[4] = ieee154e_vars.asn.byte4; +! } +! +! port_INLINE void joinPriorityStoreFromAdv(uint8_t jp){ +! ieee154e_vars.dataReceived->l2_joinPriority = jp; +! ieee154e_vars.dataReceived->l2_joinPriorityPresent = TRUE; +! } +! +! +! port_INLINE void asnStoreFromAdv(uint8_t* asn) { +! +! // store the ASN +! ieee154e_vars.asn.bytes0and1 = asn[0]+ +! 256*asn[1]; +! ieee154e_vars.asn.bytes2and3 = asn[2]+ +! 256*asn[3]; +! ieee154e_vars.asn.byte4 = asn[4]; +! +! // determine the current slotOffset +! /* +! Note: this is a bit of a hack. Normally, slotOffset=ASN%slotlength. But since +! the ADV is exchanged in slot 0, we know that we're currently at slotOffset==0 +! */ +! ieee154e_vars.slotOffset = 0; +! schedule_syncSlotOffset(ieee154e_vars.slotOffset); +! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); +! +! /* +! infer the asnOffset based on the fact that +! ieee154e_vars.freq = 11 + (asnOffset + channelOffset)%16 +! */ +! ieee154e_vars.asnOffset = ieee154e_vars.freq - 11 - schedule_getChannelOffset(); +! } +! +! //======= synchronization +! +! void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived) { +! PORT_SIGNED_INT_WIDTH timeCorrection; +! PORT_RADIOTIMER_WIDTH newPeriod; +! PORT_RADIOTIMER_WIDTH currentValue; +! PORT_RADIOTIMER_WIDTH currentPeriod; +! // record the current timer value and period +! currentValue = radio_getTimerValue(); +! currentPeriod = radio_getTimerPeriod(); +! // calculate new period +! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)timeReceived-(PORT_SIGNED_INT_WIDTH)TsTxOffset); +! +! newPeriod = TsSlotDuration; +! // detect whether I'm too close to the edge of the slot, in that case, +! // skip a slot and increase the temporary slot length to be 2 slots long +! if (currentValue LIMITLARGETIMECORRECTION +! ) +! ) { +! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, +! (errorparameter_t)timeCorrection, +! (errorparameter_t)0); +! } +! // update the stats +! ieee154e_stats.numSyncPkt++; +! updateStats(timeCorrection); +! } +! +! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection) { +! PORT_RADIOTIMER_WIDTH newPeriod; +! PORT_RADIOTIMER_WIDTH currentPeriod; +! // calculate new period +! currentPeriod = radio_getTimerPeriod(); +! newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)currentPeriod-timeCorrection); +! +! // resynchronize by applying the new period +! radio_setTimerPeriod(newPeriod); +! // reset the de-synchronization timeout +! ieee154e_vars.deSyncTimeout = DESYNCTIMEOUT; +! // log a large timeCorrection +! if ( +! ieee154e_vars.isSync==TRUE && +! ( +! timeCorrection<-LIMITLARGETIMECORRECTION || +! timeCorrection> LIMITLARGETIMECORRECTION +! ) +! ) { +! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, +! (errorparameter_t)timeCorrection, +! (errorparameter_t)1); +! } +! // update the stats +! ieee154e_stats.numSyncAck++; +! updateStats(timeCorrection); +! } +! +! void changeIsSync(bool newIsSync) { +! ieee154e_vars.isSync = newIsSync; +! +! if (ieee154e_vars.isSync==TRUE) { +! leds_sync_on(); +! resetStats(); +! } else { +! leds_sync_off(); +! schedule_resetBackoff(); +! } +! } +! +! //======= notifying upper layer +! +! void notif_sendDone(OpenQueueEntry_t* packetSent, owerror_t error) { +! // record the outcome of the trasmission attempt +! packetSent->l2_sendDoneError = error; +! // record the current ASN +! memcpy(&packetSent->l2_asn,&ieee154e_vars.asn,sizeof(asn_t)); +! // associate this packet with the virtual component +! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it +! packetSent->owner = COMPONENT_IEEE802154E_TO_RES; +! // post RES's sendDone task +! scheduler_push_task(task_resNotifSendDone,TASKPRIO_RESNOTIF_TXDONE); +! /*thread_create(openwsn_ieee802154e_send_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_IEEE802154E, CREATE_STACKTEST, +! task_resNotifSendDone, "task resNotifSendDone");*/ +! // wake up the scheduler +! SCHEDULER_WAKEUP(); +! } +! +! void notif_receive(OpenQueueEntry_t* packetReceived) { +! // record the current ASN +! memcpy(&packetReceived->l2_asn, &ieee154e_vars.asn, sizeof(asn_t)); +! // indicate reception to the schedule, to keep statistics +! schedule_indicateRx(&packetReceived->l2_asn); +! // associate this packet with the virtual component +! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it +! packetReceived->owner = COMPONENT_IEEE802154E_TO_RES; +! +! // post RES's Receive task +! scheduler_push_task(task_resNotifReceive,TASKPRIO_RESNOTIF_RX); +! /*thread_create(openwsn_ieee802154e_rec_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_IEEE802154E, CREATE_STACKTEST, +! task_resNotifSendDone, "task resNotifSendDone");*/ +! // wake up the scheduler +! SCHEDULER_WAKEUP(); +! } +! +! //======= stats +! +! port_INLINE void resetStats(void) { +! ieee154e_stats.numSyncPkt = 0; +! ieee154e_stats.numSyncAck = 0; +! ieee154e_stats.minCorrection = 127; +! ieee154e_stats.maxCorrection = -127; +! ieee154e_stats.dutyCycle = 0; +! // do not reset the number of de-synchronizations +! } +! +! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection) { +! // update minCorrection +! if (timeCorrectionieee154e_stats.maxCorrection) { +! ieee154e_stats.maxCorrection = timeCorrection; +! } +! } +! +! //======= misc +! +! /** +! \brief Calculates the frequency channel to transmit on, based on the +! absolute slot number and the channel offset of the requested slot. +! +! During normal operation, the frequency used is a function of the +! channelOffset indicating in the schedule, and of the ASN of the +! slot. This ensures channel hopping, consecutive packets sent in the same slot +! in the schedule are done on a difference frequency channel. +! +! During development, you can force single channel operation by having this +! function return a constant channel number (between 11 and 26). This allows you +! to use a single-channel sniffer; but you can not schedule two links on two +! different channel offsets in the same slot. +! +! \param[in] channelOffset channel offset for the current slot +! +! \returns The calculated frequency channel, an integer between 11 and 26. +! */ +! port_INLINE uint8_t calculateFrequency(uint8_t channelOffset) { +! // comment the following line out to disable channel hopping +! return SYNCHRONIZING_CHANNEL; // single channel +! //return 11+(ieee154e_vars.asnOffset+channelOffset)%16; //channel hopping +! } +! +! /** +! \brief Changes the state of the IEEE802.15.4e FSM. +! +! Besides simply updating the state global variable, +! this function toggles the FSM debug pin. +! +! \param[in] newstate The state the IEEE802.15.4e FSM is now in. +! */ +! void changeState(ieee154e_state_t newstate) { +! // update the state +! ieee154e_vars.state = newstate; +! // wiggle the FSM debug pin +! switch (ieee154e_vars.state) { +! case S_SYNCLISTEN: +! case S_TXDATAOFFSET: +! debugpins_fsm_set(); +! break; +! case S_SLEEP: +! case S_RXDATAOFFSET: +! debugpins_fsm_clr(); +! break; +! case S_SYNCRX: +! case S_SYNCPROC: +! case S_TXDATAPREPARE: +! case S_TXDATAREADY: +! case S_TXDATADELAY: +! case S_TXDATA: +! case S_RXACKOFFSET: +! case S_RXACKPREPARE: +! case S_RXACKREADY: +! case S_RXACKLISTEN: +! case S_RXACK: +! case S_TXPROC: +! case S_RXDATAPREPARE: +! case S_RXDATAREADY: +! case S_RXDATALISTEN: +! case S_RXDATA: +! case S_TXACKOFFSET: +! case S_TXACKPREPARE: +! case S_TXACKREADY: +! case S_TXACKDELAY: +! case S_TXACK: +! case S_RXPROC: +! debugpins_fsm_toggle(); +! break; +! } +! } +! +! /** +! \brief Housekeeping tasks to do at the end of each slot. +! +! This functions is called once in each slot, when there is nothing more +! to do. This might be when an error occured, or when everything went well. +! This function resets the state of the FSM so it is ready for the next slot. +! +! Note that by the time this function is called, any received packet should already +! have been sent to the upper layer. Similarly, in a Tx slot, the sendDone +! function should already have been done. If this is not the case, this function +! will do that for you, but assume that something went wrong. +! */ +! void endSlot(void) { +! +! float aux; //duty cycle helper. +! // turn off the radio +! radio_rfOff(); +! // compute the duty cycle if radio has been turned on +! if (ieee154e_vars.radioOnThisSlot==TRUE){ +! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); +! } +! // clear any pending timer +! radiotimer_cancel(); +! +! // reset capturedTimes +! ieee154e_vars.lastCapturedTime = 0; +! ieee154e_vars.syncCapturedTime = 0; +! +! //instant duty cycle.. average is computed at debugprint_macstats. +! aux=(float)ieee154e_vars.radioOnTics/(float)radio_getTimerPeriod(); +! ieee154e_stats.dutyCycle+=aux;//accumulate and avg will be done on serial print +! //clear vars for duty cycle on this slot +! ieee154e_vars.radioOnTics=0; +! ieee154e_vars.radioOnThisSlot=FALSE; +! +! // clean up dataToSend +! if (ieee154e_vars.dataToSend!=NULL) { +! // if everything went well, dataToSend was set to NULL in ti9 +! // getting here means transmit failed +! +! // indicate Tx fail to schedule to update stats +! schedule_indicateTx(&ieee154e_vars.asn,FALSE); +! +! //decrement transmits left counter +! ieee154e_vars.dataToSend->l2_retriesLeft--; +! +! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { +! // indicate tx fail if no more retries left +! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); +! } else { +! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component +! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; +! } +! +! // reset local variable +! ieee154e_vars.dataToSend = NULL; +! } +! +! // clean up dataReceived +! if (ieee154e_vars.dataReceived!=NULL) { +! // assume something went wrong. If everything went well, dataReceived +! // would have been set to NULL in ri9. +! // indicate "received packet" to upper layer since we don't want to loose packets +! notif_receive(ieee154e_vars.dataReceived); +! // reset local variable +! ieee154e_vars.dataReceived = NULL; +! } +! +! // clean up ackToSend +! if (ieee154e_vars.ackToSend!=NULL) { +! // free ackToSend so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); +! // reset local variable +! ieee154e_vars.ackToSend = NULL; +! } +! +! // clean up ackReceived +! if (ieee154e_vars.ackReceived!=NULL) { +! // free ackReceived so corresponding RAM memory can be recycled +! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); +! // reset local variable +! ieee154e_vars.ackReceived = NULL; +! } +! +! +! // change state +! changeState(S_SLEEP); +! } +! +! bool ieee154e_isSynch(void){ +! return ieee154e_vars.isSync; +! } +diff -crB openwsn/02a-MAClow/IEEE802154E.h ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.h +*** openwsn/02a-MAClow/IEEE802154E.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,154 **** +! #ifndef __IEEE802154E_H +! #define __IEEE802154E_H +! +! /** +! \addtogroup MAClow +! \{ +! \addtogroup IEEE802154E +! \{ +! */ +! +! #include "openwsn.h" +! #include "board_info.h" +! +! //=========================== debug define ==================================== +! +! //=========================== define ========================================== +! +! #define SYNCHRONIZING_CHANNEL 20 // channel the mote listens on to synchronize +! #define TXRETRIES 3 // number of MAC retries before declaring failed +! #define TX_POWER 31 // 1=-25dBm, 31=0dBm (max value) +! #define RESYNCHRONIZATIONGUARD 5 // in 32kHz ticks. min distance to the end of the slot to succesfully synchronize +! #define US_PER_TICK 30 // number of us per 32kHz clock tick +! #define KATIMEOUT 66 // in slots: @15ms per slot -> ~1 seconds +! #define DESYNCTIMEOUT 333 // in slots: @15ms per slot -> ~5 seconds +! #define LIMITLARGETIMECORRECTION 5 // threshold number of ticks to declare a timeCorrection "large" +! #define LENGTH_IEEE154_MAX 128 // max length of a valid radio packet +! +! /** +! When a packet is received, it is written inside the OpenQueueEntry_t->packet +! buffer, starting at the byte defined below. When a packet is relayed, it +! traverses the stack in which the MAC and IPHC headers are parsed and stripped +! off, then put on again. During that process, the IPv6 hop limit field is +! decremented. Depending on the new value of the hop limit, the IPHC header +! compression algorithm might not be able to compress it, and hence has to carry +! it inline, adding a byte to the header. To avoid having to move bytes around +! inside OpenQueueEntry_t->packet buffer, we start writing the received packet a +! bit after the start of the packet. +! */ +! #define FIRST_FRAME_BYTE 1 +! +! // the different states of the IEEE802.15.4e state machine +! typedef enum { +! S_SLEEP = 0x00, // ready for next slot +! // synchronizing +! S_SYNCLISTEN = 0x01, // listened for packet to synchronize to network +! S_SYNCRX = 0x02, // receiving packet to synchronize to network +! S_SYNCPROC = 0x03, // processing packet just received +! // TX +! S_TXDATAOFFSET = 0x04, // waiting to prepare for Tx data +! S_TXDATAPREPARE = 0x05, // preparing for Tx data +! S_TXDATAREADY = 0x06, // ready to Tx data, waiting for 'go' +! S_TXDATADELAY = 0x07, // 'go' signal given, waiting for SFD Tx data +! S_TXDATA = 0x08, // Tx data SFD received, sending bytes +! S_RXACKOFFSET = 0x09, // Tx data done, waiting to prepare for Rx ACK +! S_RXACKPREPARE = 0x0a, // preparing for Rx ACK +! S_RXACKREADY = 0x0b, // ready to Rx ACK, waiting for 'go' +! S_RXACKLISTEN = 0x0c, // idle listening for ACK +! S_RXACK = 0x0d, // Rx ACK SFD received, receiving bytes +! S_TXPROC = 0x0e, // processing sent data +! // RX +! S_RXDATAOFFSET = 0x0f, // waiting to prepare for Rx data +! S_RXDATAPREPARE = 0x10, // preparing for Rx data +! S_RXDATAREADY = 0x11, // ready to Rx data, waiting for 'go' +! S_RXDATALISTEN = 0x12, // idle listening for data +! S_RXDATA = 0x13, // data SFD received, receiving more bytes +! S_TXACKOFFSET = 0x14, // waiting to prepare for Tx ACK +! S_TXACKPREPARE = 0x15, // preparing for Tx ACK +! S_TXACKREADY = 0x16, // Tx ACK ready, waiting for 'go' +! S_TXACKDELAY = 0x17, // 'go' signal given, waiting for SFD Tx ACK +! S_TXACK = 0x18, // Tx ACK SFD received, sending bytes +! S_RXPROC = 0x19, // processing received data +! } ieee154e_state_t; +! +! // Atomic durations +! // expressed in 32kHz ticks: +! // - ticks = duration_in_seconds * 32768 +! // - duration_in_seconds = ticks / 32768 +! enum ieee154e_atomicdurations_enum { +! // time-slot related +! TsTxOffset = 131, // 4000us +! TsLongGT = 43, // 1300us +! TsTxAckDelay = 151, // 4606us +! TsShortGT = 16, // 500us +! TsSlotDuration = PORT_TsSlotDuration, // 15000us +! // execution speed related +! maxTxDataPrepare = PORT_maxTxDataPrepare, +! maxRxAckPrepare = PORT_maxRxAckPrepare, +! maxRxDataPrepare = PORT_maxRxDataPrepare, +! maxTxAckPrepare = PORT_maxTxAckPrepare, +! // radio speed related +! delayTx = PORT_delayTx, // between GO signal and SFD +! delayRx = PORT_delayRx, // between GO signal and start listening +! // radio watchdog +! wdRadioTx = 33, // 1000us (needs to be >delayTx) +! wdDataDuration = 164, // 5000us (measured 4280us with max payload) +! wdAckDuration = 98, // 3000us (measured 1000us) +! }; +! +! +! +! // FSM timer durations (combinations of atomic durations) +! // TX +! #define DURATION_tt1 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx-maxTxDataPrepare +! #define DURATION_tt2 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx +! #define DURATION_tt3 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx+wdRadioTx +! #define DURATION_tt4 ieee154e_vars.lastCapturedTime+wdDataDuration +! #define DURATION_tt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx-maxRxAckPrepare +! #define DURATION_tt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx +! #define DURATION_tt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay+TsShortGT +! #define DURATION_tt8 ieee154e_vars.lastCapturedTime+wdAckDuration +! // RX +! #define DURATION_rt1 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx-maxRxDataPrepare +! #define DURATION_rt2 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx +! #define DURATION_rt3 ieee154e_vars.lastCapturedTime+TsTxOffset+TsLongGT +! #define DURATION_rt4 ieee154e_vars.lastCapturedTime+wdDataDuration +! #define DURATION_rt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx-maxTxAckPrepare +! #define DURATION_rt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx +! #define DURATION_rt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx+wdRadioTx +! #define DURATION_rt8 ieee154e_vars.lastCapturedTime+wdAckDuration +! +! //=========================== typedef ========================================= +! +! //IEEE802.15.4E acknowledgement (ACK) +! typedef struct { +! PORT_SIGNED_INT_WIDTH timeCorrection; +! } IEEE802154E_ACK_ht; +! +! #define ADV_PAYLOAD_LENGTH 5 +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void ieee154e_init(); +! // public +! PORT_TIMER_WIDTH ieee154e_asnDiff(asn_t* someASN); +! bool ieee154e_isSynch(); +! void asnWriteToPkt(OpenQueueEntry_t* frame); +! void asnWriteToSerial(uint8_t* array); +! // events +! void ieee154e_startOfFrame(PORT_TIMER_WIDTH capturedTime); +! void ieee154e_endOfFrame(PORT_TIMER_WIDTH capturedTime); +! // misc +! bool debugPrint_asn(); +! bool debugPrint_isSync(); +! bool debugPrint_macStats(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,308 ---- +! #ifndef __IEEE802154E_H +! #define __IEEE802154E_H +! +! /** +! \addtogroup MAClow +! \{ +! \addtogroup IEEE802154E +! \{ +! */ +! +! #include "openwsn.h" +! #include "board_info.h" +! #include "schedule.h" +! +! //=========================== debug define ==================================== +! +! //=========================== define ========================================== +! +! #define SYNCHRONIZING_CHANNEL 20 // channel the mote listens on to synchronize +! #define TXRETRIES 3 // number of MAC retries before declaring failed +! #define TX_POWER 31 // 1=-25dBm, 31=0dBm (max value) +! #define RESYNCHRONIZATIONGUARD 5 // in 32kHz ticks. min distance to the end of the slot to succesfully synchronize +! #define US_PER_TICK 30 // number of us per 32kHz clock tick +! #define KATIMEOUT 66 // in slots: @15ms per slot -> ~1 seconds +! #define DESYNCTIMEOUT 333 // in slots: @15ms per slot -> ~5 seconds +! #define LIMITLARGETIMECORRECTION 5 // threshold number of ticks to declare a timeCorrection "large" +! #define LENGTH_IEEE154_MAX 128 // max length of a valid radio packet +! +! //15.4e information elements related +! #define IEEE802154E_PAYLOAD_DESC_LEN_SHIFT 0x04 +! #define IEEE802154E_PAYLOAD_DESC_GROUP_ID_MLME (0x01 << 1) //includes shift 1 +! #define IEEE802154E_DESC_TYPE_LONG 0x01 +! #define IEEE802154E_DESC_TYPE_SHORT 0x00 +! +! #define IEEE802154E_DESC_TYPE_HEADER_IE 0x00 +! #define IEEE802154E_DESC_TYPE_PAYLOAD_IE 0x01 +! //len field on PAYLOAD/HEADER DESC +! #define IEEE802154E_DESC_LEN_HEADER_IE_MASK 0xFE00 +! #define IEEE802154E_DESC_LEN_PAYLOAD_IE_MASK 0xFFE0 +! +! #define IEEE802154E_DESC_LEN_HEADER_IE_SHIFT 9 +! #define IEEE802154E_DESC_LEN_PAYLOAD_IE_SHIFT 5 +! +! //groupID/elementID field on PAYLOAD/HEADER DESC +! #define IEEE802154E_DESC_ELEMENTID_HEADER_IE_MASK 0x01FE +! #define IEEE802154E_DESC_GROUPID_PAYLOAD_IE_MASK 0x001E +! +! #define IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT 1 +! #define IEEE802154E_DESC_GROUPID_PAYLOAD_IE_SHIFT 1 +! +! //MLME Sub IE LONG page 83 +! #define IEEE802154E_DESC_LEN_LONG_MLME_IE_MASK 0xFFE0 +! #define IEEE802154E_DESC_SUBID_LONG_MLME_IE_MASK 0x001E +! +! #define IEEE802154E_DESC_LEN_LONG_MLME_IE_SHIFT 5 +! #define IEEE802154E_DESC_SUBID_LONG_MLME_IE_SHIFT 1 +! +! //MLME Sub IE SHORT page 82 +! #define IEEE802154E_DESC_LEN_SHORT_MLME_IE_MASK 0xFF00 +! #define IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK 0x00FE +! +! #define IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT 8 +! #define IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT 1 +! +! +! #define IEEE802154E_MLME_SYNC_IE_SUBID 0x1A +! #define IEEE802154E_MLME_SYNC_IE_SUBID_SHIFT 1 +! #define IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID 0x1B +! #define IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID_SHIFT 1 +! #define IEEE802154E_MLME_TIMESLOT_IE_SUBID 0x1c +! #define IEEE802154E_MLME_TIMESLOT_IE_SUBID_SHIFT 1 +! +! #define IEEE802154E_MLME_IE_GROUPID 0x01 +! #define IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID 0x1E +! +! #define IEEE802154E_ +! /** +! When a packet is received, it is written inside the OpenQueueEntry_t->packet +! buffer, starting at the byte defined below. When a packet is relayed, it +! traverses the stack in which the MAC and IPHC headers are parsed and stripped +! off, then put on again. During that process, the IPv6 hop limit field is +! decremented. Depending on the new value of the hop limit, the IPHC header +! compression algorithm might not be able to compress it, and hence has to carry +! it inline, adding a byte to the header. To avoid having to move bytes around +! inside OpenQueueEntry_t->packet buffer, we start writing the received packet a +! bit after the start of the packet. +! */ +! #define FIRST_FRAME_BYTE 1 +! +! // the different states of the IEEE802.15.4e state machine +! typedef enum { +! S_SLEEP = 0x00, // ready for next slot +! // synchronizing +! S_SYNCLISTEN = 0x01, // listened for packet to synchronize to network +! S_SYNCRX = 0x02, // receiving packet to synchronize to network +! S_SYNCPROC = 0x03, // processing packet just received +! // TX +! S_TXDATAOFFSET = 0x04, // waiting to prepare for Tx data +! S_TXDATAPREPARE = 0x05, // preparing for Tx data +! S_TXDATAREADY = 0x06, // ready to Tx data, waiting for 'go' +! S_TXDATADELAY = 0x07, // 'go' signal given, waiting for SFD Tx data +! S_TXDATA = 0x08, // Tx data SFD received, sending bytes +! S_RXACKOFFSET = 0x09, // Tx data done, waiting to prepare for Rx ACK +! S_RXACKPREPARE = 0x0a, // preparing for Rx ACK +! S_RXACKREADY = 0x0b, // ready to Rx ACK, waiting for 'go' +! S_RXACKLISTEN = 0x0c, // idle listening for ACK +! S_RXACK = 0x0d, // Rx ACK SFD received, receiving bytes +! S_TXPROC = 0x0e, // processing sent data +! // RX +! S_RXDATAOFFSET = 0x0f, // waiting to prepare for Rx data +! S_RXDATAPREPARE = 0x10, // preparing for Rx data +! S_RXDATAREADY = 0x11, // ready to Rx data, waiting for 'go' +! S_RXDATALISTEN = 0x12, // idle listening for data +! S_RXDATA = 0x13, // data SFD received, receiving more bytes +! S_TXACKOFFSET = 0x14, // waiting to prepare for Tx ACK +! S_TXACKPREPARE = 0x15, // preparing for Tx ACK +! S_TXACKREADY = 0x16, // Tx ACK ready, waiting for 'go' +! S_TXACKDELAY = 0x17, // 'go' signal given, waiting for SFD Tx ACK +! S_TXACK = 0x18, // Tx ACK SFD received, sending bytes +! S_RXPROC = 0x19, // processing received data +! } ieee154e_state_t; +! +! // Atomic durations +! // expressed in 32kHz ticks: +! // - ticks = duration_in_seconds * 32768 +! // - duration_in_seconds = ticks / 32768 +! enum ieee154e_atomicdurations_enum { +! // time-slot related +! TsTxOffset = 131, // 4000us +! TsLongGT = 43, // 1300us +! TsTxAckDelay = 151, // 4606us +! TsShortGT = 16, // 500us +! // TsShortGT = 30, // 900us, stm32 can work well with this value +! TsSlotDuration = PORT_TsSlotDuration, // 15000us +! // execution speed related +! maxTxDataPrepare = PORT_maxTxDataPrepare, +! maxRxAckPrepare = PORT_maxRxAckPrepare, +! maxRxDataPrepare = PORT_maxRxDataPrepare, +! maxTxAckPrepare = PORT_maxTxAckPrepare, +! // radio speed related +! delayTx = PORT_delayTx, // between GO signal and SFD +! delayRx = PORT_delayRx, // between GO signal and start listening +! // radio watchdog +! wdRadioTx = 33, // 1000us (needs to be >delayTx) +! wdDataDuration = 164, // 5000us (measured 4280us with max payload) +! wdAckDuration = 98, // 3000us (measured 1000us) +! }; +! +! +! //shift of bytes in the linkOption bitmap +! enum ieee154e_linkOption_enum { +! FLAG_TX_S = 7, +! FLAG_RX_S = 6, +! FLAG_SHARED_S = 5, +! FLAG_TIMEKEEPING_S = 4, +! }; +! +! // FSM timer durations (combinations of atomic durations) +! // TX +! #define DURATION_tt1 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx-maxTxDataPrepare +! #define DURATION_tt2 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx +! #define DURATION_tt3 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx+wdRadioTx +! #define DURATION_tt4 ieee154e_vars.lastCapturedTime+wdDataDuration +! #define DURATION_tt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx-maxRxAckPrepare +! #define DURATION_tt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx +! #define DURATION_tt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay+TsShortGT +! #define DURATION_tt8 ieee154e_vars.lastCapturedTime+wdAckDuration +! // RX +! #define DURATION_rt1 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx-maxRxDataPrepare +! #define DURATION_rt2 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx +! #define DURATION_rt3 ieee154e_vars.lastCapturedTime+TsTxOffset+TsLongGT +! #define DURATION_rt4 ieee154e_vars.lastCapturedTime+wdDataDuration +! #define DURATION_rt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx-maxTxAckPrepare +! #define DURATION_rt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx +! #define DURATION_rt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx+wdRadioTx +! #define DURATION_rt8 ieee154e_vars.lastCapturedTime+wdAckDuration +! +! //=========================== typedef ========================================= +! +! //IEEE802.15.4E acknowledgement (ACK) +! typedef struct { +! PORT_SIGNED_INT_WIDTH timeCorrection; +! } IEEE802154E_ACK_ht; +! +! //includes payload header IE short + MLME short Header + Sync IE +! #define ADV_PAYLOAD_LENGTH sizeof(payload_IE_descriptor_t) + \ +! sizeof(MLME_IE_subHeader_t) + \ +! sizeof(synch_IE_t) +! +! +! +! +! //=========================== module variables ================================ +! +! typedef struct { +! // misc +! asn_t asn; // current absolute slot number +! slotOffset_t slotOffset; // current slot offset +! slotOffset_t nextActiveSlotOffset; // next active slot offset +! PORT_RADIOTIMER_WIDTH deSyncTimeout; // how many slots left before looses sync +! bool isSync; // TRUE iff mote is synchronized to network +! // as shown on the chronogram +! ieee154e_state_t state; // state of the FSM +! OpenQueueEntry_t* dataToSend; // pointer to the data to send +! OpenQueueEntry_t* dataReceived; // pointer to the data received +! OpenQueueEntry_t* ackToSend; // pointer to the ack to send +! OpenQueueEntry_t* ackReceived; // pointer to the ack received +! PORT_RADIOTIMER_WIDTH lastCapturedTime; // last captured time +! PORT_RADIOTIMER_WIDTH syncCapturedTime; // captured time used to sync +! //channel hopping +! uint8_t freq; // frequency of the current slot +! uint8_t asnOffset; // offset inside the frame +! +! PORT_RADIOTIMER_WIDTH radioOnInit; //when within the slot the radio turns on +! PORT_RADIOTIMER_WIDTH radioOnTics;//how many tics within the slot the radio is on +! bool radioOnThisSlot; //to control if the radio has been turned on in a slot. +! } ieee154e_vars_t; +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t numSyncPkt; // how many times synchronized on a non-ACK packet +! uint8_t numSyncAck; // how many times synchronized on an ACK +! PORT_SIGNED_INT_WIDTH minCorrection; // minimum time correction +! PORT_SIGNED_INT_WIDTH maxCorrection; // maximum time correction +! uint8_t numDeSync; // number of times a desync happened +! float dutyCycle; // mac dutyCycle at each superframe +! } ieee154e_stats_t; +! //PRAGMA(pack()); +! +! typedef struct { +! PORT_RADIOTIMER_WIDTH num_newSlot; +! PORT_RADIOTIMER_WIDTH num_timer; +! PORT_RADIOTIMER_WIDTH num_startOfFrame; +! PORT_RADIOTIMER_WIDTH num_endOfFrame; +! } ieee154e_dbg_t; +! +! +! //=========================== IEs ============================================= +! //the header for all header IEs +! typedef struct{ +! uint16_t length_elementid_type; +! }header_IE_descriptor_t; +! //header descriptor. elementid will be 0 as described in 15.4e pag. 81 +! //type is 0 as described on p. 80 +! +! +! //the content for ack ie -- it is a header IE with values - element id =0x1e len=2 type=0 +! //PRAGMA(pack(1)); +! typedef struct { +! int16_t timesync_info; +! }ack_timecorrection_IE_t; +! //PRAGMA(pack()); +! //the header for all payload IEs +! +! +! typedef struct{//11b len 4b gid 1b type +! uint16_t length_groupid_type; //bytes on the IE content- that is the embedded MLME or Header IE. +! //groupid == 0x01 MLME | type long = 1 +! }payload_IE_descriptor_t; // payload descriptor. groupid will be 1 as described in 15.4e pag. 81 +! +! //MLME sub id header appended to payload descriptor. we use group id=1 type=1 +! typedef struct{ +! uint16_t length_subID_type; +! }MLME_IE_subHeader_t; +! +! //the Synchronization IE. it is a payload IE with values - subid=0x1a type=0 (short) len=6 +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t asn[5]; +! uint8_t join_priority; +! }synch_IE_t; +! //PRAGMA(pack()); +! +! //the Slotframe and Link IE +! typedef struct { +! uint8_t slotframehandle; +! uint16_t slotframesize; +! uint8_t numlinks; +! }slotframelink_IE_t; +! +! typedef struct { +! uint16_t tsNum; +! uint16_t choffset; +! uint8_t linkoptions; +! }linkInfo_subIE_t; +! +! //=========================== prototypes ====================================== +! +! // admin +! void ieee154e_init(void); +! // public +! PORT_RADIOTIMER_WIDTH ieee154e_asnDiff(asn_t* someASN); +! bool ieee154e_isSynch(void); +! void ieee154e_getAsn(uint8_t* array); +! // events +! void ieee154e_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); +! void ieee154e_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); +! // misc +! bool debugPrint_asn(void); +! bool debugPrint_isSync(void); +! bool debugPrint_macStats(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/02a-MAClow/Makefile ../../../sys/net/openwsn/02a-MAClow/Makefile +*** openwsn/02a-MAClow/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/02a-MAClow/Makefile Wed Jan 15 13:48:26 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBMOD) ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/02a-MAClow/stupidmac/Makefile ../../../sys/net/openwsn/02a-MAClow/stupidmac/Makefile +*** openwsn/02a-MAClow/stupidmac/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/02a-MAClow/stupidmac/Makefile Wed Jan 15 13:48:26 2014 +*************** +*** 0 **** +--- 1,4 ---- ++ MODULE:=$(shell basename $(CURDIR)) ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ ++ include $(RIOTBASE)/Makefile.base +\ No newline at end of file +diff -crB openwsn/02a-MAClow/stupidmac/stupidmac.c ../../../sys/net/openwsn/02a-MAClow/stupidmac/stupidmac.c +*** openwsn/02a-MAClow/stupidmac/stupidmac.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/stupidmac/stupidmac.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,354 **** +! /** +! \brief Implementation of stupidMAC +! +! \author Thomas Watteyne , August 2010 +! */ +! +! #include "openwsn.h" +! #include "stupidmac.h" +! #include "IEEE802154.h" +! #include "radio.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "timers.h" +! #include "packetfunctions.h" +! #include "neighbors.h" +! #include "nores.h" +! +! //=========================== variables ======================================= +! +! OpenQueueEntry_t* stupidmac_dataFrameToSend; // NULL at beginning and end of slot +! OpenQueueEntry_t* stupidmac_packetACK; // NULL at beginning and end, free at end of slot +! OpenQueueEntry_t* stupidmac_dataFrameReceived; // !NULL between data received, and sent to upper layer +! uint8_t stupidmac_dsn; +! uint8_t stupidmac_state; +! #ifndef SERIALINSCHEDULER +! bool stupidmac_serialInOutputMode; +! #endif +! +! //=========================== prototypes ====================================== +! +! #include "IEEE802154_common.c" +! void packetReceived(); +! void armRandomBackoffTimer(); +! void change_state(uint8_t newstate); +! +! //======= from upper layer +! +! //in stupidMAC, the radio is always on, listening +! void stupidmac_init() { +! radio_rxOn(openwsn_frequency_channel); +! change_state(S_IDLE_LISTENING); +! stupidmac_dataFrameToSend = NULL; +! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); +! } +! +! //a packet sent from the upper layer is simply stored into the OpenQueue buffer. +! //The timerBackoff is armed to service the packet later on. +! error_t stupidmac_send(OpenQueueEntry_t* msg) { +! //metadata +! msg->owner = COMPONENT_MAC; +! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { +! msg->l2_retriesLeft = 1; +! } else { +! msg->l2_retriesLeft = TXRETRIES; +! } +! msg->l1_txPower = TX_POWER; +! msg->l1_channel = openwsn_frequency_channel; +! //IEEE802.15.4 header +! prependIEEE802154header(msg, +! msg->l2_frameType, +! IEEE154_SEC_NO_SECURITY, +! stupidmac_dsn++, +! &(msg->l2_nextORpreviousHop) +! ); +! // space for 2-byte CRC +! packetfunctions_reserveFooterSize(msg,2); +! //simulate timer backoff fires so that packet gets sent immediately +! timer_mac_backoff_fired(); +! return E_SUCCESS; +! } +! +! //======= from lower layer +! +! void stupidmac_sendDone(OpenQueueEntry_t* pkt, error_t error) { +! switch (stupidmac_state) { +! case S_TX_TXDATA: //[sendNowDone] transmitter +! if (error!=E_SUCCESS) { +! nores_sendDone(pkt,E_FAIL); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer();//arm timer to retransmission (?) +! change_state(S_IDLE_LISTENING); +! openserial_printError(COMPONENT_MAC,ERR_SENDNOWDONE_FAILED, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! return; +! } else { +! timer_startOneShot(TIMER_MAC_WATCHDOG,ACK_WAIT_TIME); +! change_state(S_TX_RXACK); +! } +! break; +! case S_RX_TXACK: //[sendNowDone] receiver +! //I'm a receiver, finished sending ACK (end of RX sequence) +! openqueue_freePacketBuffer(stupidmac_packetACK); +! packetReceived(); +! change_state(S_IDLE_LISTENING); +! break; +! default: +! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_SUBSEND_SENDDONE, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! change_state(S_IDLE_LISTENING); +! break; +! } +! } +! +! void radio_packet_received(OpenQueueEntry_t* msg) { +! ieee802154_header_iht received_ieee154_header; +! ieee802154_header_iht transmitted_ieee154_header; +! +! openserial_stop(); +! //ensure debug fires only after packet fully received +! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); +! +! msg->owner = COMPONENT_MAC; +! +! if (stupidmac_state!=S_TX_RXACK && stupidmac_state!=S_IDLE_LISTENING) { +! //not expecting this packet, throw away +! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was +! openqueue_freePacketBuffer(msg); +! return; +! } +! +! received_ieee154_header = retrieveIEEE802154header(msg); +! packetfunctions_tossHeader(msg,received_ieee154_header.headerLength); +! packetfunctions_tossFooter(msg,2); +! +! msg->l2_frameType = received_ieee154_header.frameType; +! memcpy(&(msg->l2_nextORpreviousHop),&(received_ieee154_header.src),sizeof(open_addr_t)); +! if ( received_ieee154_header.frameType==IEEE154_TYPE_DATA && +! !(idmanager_isMyAddress(&received_ieee154_header.panid))) { +! openserial_printError(COMPONENT_MAC,ERR_WRONG_PANID, +! (errorparameter_t)received_ieee154_header.panid.panid[0]*256+received_ieee154_header.panid.panid[1], +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! +! switch (stupidmac_state) { +! +! /*------------------- TX sequence ------------------------*/ +! case S_TX_RXACK: //[receive] transmitter +! transmitted_ieee154_header = retrieveIEEE802154header(stupidmac_dataFrameToSend); +! if (received_ieee154_header.dsn == transmitted_ieee154_header.dsn) { +! //I'm a transmitter, just received ACK (end of TX sequence) +! timer_stop(TIMER_MAC_WATCHDOG); +! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_ACKED); +! nores_sendDone(stupidmac_dataFrameToSend,E_SUCCESS); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer();//arm timer for next transmission +! change_state(S_IDLE_LISTENING); +! } +! openqueue_freePacketBuffer(msg);//free packet I received +! break; +! +! /*------------------- RX sequence ------------------------*/ +! case S_IDLE_LISTENING: //[receive] receiver +! //I'm a receiver, just received a packet +! if (received_ieee154_header.frameType==IEEE154_TYPE_DATA || received_ieee154_header.frameType==IEEE154_TYPE_CMD) { +! neighbors_indicateRx(&(msg->l2_nextORpreviousHop),msg->l1_rssi); +! if (idmanager_isMyAddress(&received_ieee154_header.dest)) { +! //this packet is unicast to me +! if (stupidmac_dataFrameReceived==NULL) { +! stupidmac_dataFrameReceived = msg; +! } else { +! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! //the sender requests an ACK +! if (received_ieee154_header.ackRequested) { +! change_state(S_RX_TXACKPREPARE); +! stupidmac_packetACK = openqueue_getFreePacketBuffer(); +! if (stupidmac_packetACK!=NULL) { +! //send ACK +! stupidmac_packetACK->creator = COMPONENT_MAC; +! stupidmac_packetACK->owner = COMPONENT_MAC; +! stupidmac_packetACK->l1_txPower = TX_POWER; +! stupidmac_packetACK->l1_channel = openwsn_frequency_channel; +! stupidmac_packetACK->l2_retriesLeft = 1; +! prependIEEE802154header(stupidmac_packetACK, +! IEEE154_TYPE_ACK, +! IEEE154_SEC_NO_SECURITY, +! received_ieee154_header.dsn, +! NULL); +! packetfunctions_reserveFooterSize(stupidmac_packetACK,2); +! change_state(S_RX_TXACKREADY); +! change_state(S_RX_TXACK); +! if (radio_send(stupidmac_packetACK)!=E_SUCCESS) { +! //abort +! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, +! (errorparameter_t)0,(errorparameter_t)2); +! openqueue_freePacketBuffer(stupidmac_packetACK); +! change_state(S_IDLE_LISTENING); +! } +! } else { +! openserial_printError(COMPONENT_MAC,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0,(errorparameter_t)0); +! change_state(S_IDLE_LISTENING); +! void packetReceived(); +! return; +! } +! } else { +! packetReceived(); +! } +! } else if (packetfunctions_isBroadcastMulticast(&received_ieee154_header.dest)==TRUE) { +! //this packet is broadcast +! if (stupidmac_dataFrameReceived==NULL) { +! stupidmac_dataFrameReceived = msg; +! } else { +! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, +! (errorparameter_t)1, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! packetReceived(); +! } else { +! openqueue_freePacketBuffer(msg); +! } +! } else { +! //not data. I could be an ACK but I'm not in S_TX_RXACK stupidmac_state, so I discard +! openqueue_freePacketBuffer(msg); +! } +! break; +! +! default: +! //this should never happen as error was caught above +! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was +! openqueue_freePacketBuffer(msg); +! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_RECEIVE, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! break; +! } +! } +! +! //=========================== private ========================================= +! +! void packetReceived() { +! if (stupidmac_dataFrameReceived->length>0) { +! //packet contains payload destined to an upper layer +! nores_receive(stupidmac_dataFrameReceived); +! } else { +! //packet contains no payload (KA) +! openqueue_freePacketBuffer(stupidmac_dataFrameReceived); +! } +! stupidmac_dataFrameReceived = NULL; +! } +! +! void armRandomBackoffTimer() { +! timer_startOneShot(TIMER_MAC_BACKOFF,MINBACKOFF); //TODO randomize +! } +! +! void change_state(uint8_t newstate) { +! stupidmac_state = newstate; +! switch (newstate) { +! case S_TX_TXDATAPREPARE: +! case S_TX_TXDATA: +! case S_RX_TXACKPREPARE: +! case S_RX_TXACK: +! //atomic P3OUT |= 0x20; +! break; +! case S_TX_TXDATAREADY: +! case S_TX_RXACK: +! case S_RX_TXACKREADY: +! case S_IDLE_LISTENING: +! //atomic P3OUT &= ~0x20; +! break; +! } +! } +! +! bool stupidmac_debugPrint() { +! return FALSE; +! } +! +! //======= timers firing +! +! //periodic timer used to transmit, and to trigger serial input/output +! void timer_mac_periodic_fired() { +! #ifndef SERIALINSCHEDULER +! openserial_stop(); +! #endif +! //trigger transmit +! armRandomBackoffTimer(); +! #ifndef SERIALINSCHEDULER +! //trigger serial input/output +! stupidmac_serialInOutputMode = !stupidmac_serialInOutputMode; +! if (stupidmac_serialInOutputMode) { +! openserial_startOutput(); +! } else { +! openserial_startInput(); +! } +! #endif +! } +! +! //this function is the one which really initiates the transmission of a packet. +! //It only does so if the MAC layer is in S_IDLE_LISTENING stupidmac_state, otherwise it defers +! void timer_mac_backoff_fired() { +! if (stupidmac_state==S_IDLE_LISTENING) { +! if (stupidmac_dataFrameToSend!=NULL) { +! openserial_printError(COMPONENT_MAC,ERR_DATAFRAMETOSEND_ERROR, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! stupidmac_dataFrameToSend = openqueue_inQueue(IS_NOT_ADV); +! if (stupidmac_dataFrameToSend==NULL) { +! stupidmac_dataFrameToSend = openqueue_inQueue(IS_ADV); +! } +! if (stupidmac_dataFrameToSend!=NULL) { +! change_state(S_TX_TXDATA); +! if (radio_send(stupidmac_dataFrameToSend)!=E_SUCCESS) { +! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer();//arm to retry later +! change_state(S_IDLE_LISTENING); +! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! } +! } else { +! //retry later on +! armRandomBackoffTimer(); +! } +! } +! +! void timer_mac_watchdog_fired() { +! switch (stupidmac_state) { +! case S_TX_RXACK: +! //I'm a transmitter, didn't receive ACK (end of TX sequence). +! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_NOT_ACKED); +! stupidmac_dataFrameToSend->l2_retriesLeft--; +! if (stupidmac_dataFrameToSend->l2_retriesLeft==0) { +! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer(); +! change_state(S_IDLE_LISTENING); +! break; +! } +! //retransmit later on +! armRandomBackoffTimer(); +! stupidmac_dataFrameToSend = NULL; +! change_state(S_IDLE_LISTENING); +! break; +! default: +! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_FASTTIMER_FIRED, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! change_state(S_IDLE_LISTENING); +! break; +! } + } +\ No newline at end of file +--- 1,354 ---- +! /** +! \brief Implementation of stupidMAC +! +! \author Thomas Watteyne , August 2010 +! */ +! +! #include "openwsn.h" +! #include "stupidmac.h" +! #include "IEEE802154.h" +! #include "radio.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "timers.h" +! #include "packetfunctions.h" +! #include "neighbors.h" +! #include "nores.h" +! +! //=========================== variables ======================================= +! +! OpenQueueEntry_t* stupidmac_dataFrameToSend; // NULL at beginning and end of slot +! OpenQueueEntry_t* stupidmac_packetACK; // NULL at beginning and end, free at end of slot +! OpenQueueEntry_t* stupidmac_dataFrameReceived; // !NULL between data received, and sent to upper layer +! uint8_t stupidmac_dsn; +! uint8_t stupidmac_state; +! #ifndef SERIALINSCHEDULER +! bool stupidmac_serialInOutputMode; +! #endif +! +! //=========================== prototypes ====================================== +! +! #include "IEEE802154_common.c" +! void packetReceived(void); +! void armRandomBackoffTimer(void); +! void change_state(uint8_t newstate); +! +! //======= from upper layer +! +! //in stupidMAC, the radio is always on, listening +! void stupidmac_init(void) { +! radio_rxOn(openwsn_frequency_channel); +! change_state(S_IDLE_LISTENING); +! stupidmac_dataFrameToSend = NULL; +! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); +! } +! +! //a packet sent from the upper layer is simply stored into the OpenQueue buffer. +! //The timerBackoff is armed to service the packet later on. +! error_t stupidmac_send(OpenQueueEntry_t* msg) { +! //metadata +! msg->owner = COMPONENT_MAC; +! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { +! msg->l2_retriesLeft = 1; +! } else { +! msg->l2_retriesLeft = TXRETRIES; +! } +! msg->l1_txPower = TX_POWER; +! msg->l1_channel = openwsn_frequency_channel; +! //IEEE802.15.4 header +! prependIEEE802154header(msg, +! msg->l2_frameType, +! IEEE154_SEC_NO_SECURITY, +! stupidmac_dsn++, +! &(msg->l2_nextORpreviousHop) +! ); +! // space for 2-byte CRC +! packetfunctions_reserveFooterSize(msg,2); +! //simulate timer backoff fires so that packet gets sent immediately +! timer_mac_backoff_fired(); +! return E_SUCCESS; +! } +! +! //======= from lower layer +! +! void stupidmac_sendDone(OpenQueueEntry_t* pkt, error_t error) { +! switch (stupidmac_state) { +! case S_TX_TXDATA: //[sendNowDone] transmitter +! if (error!=E_SUCCESS) { +! nores_sendDone(pkt,E_FAIL); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer();//arm timer to retransmission (?) +! change_state(S_IDLE_LISTENING); +! openserial_printError(COMPONENT_MAC,ERR_SENDNOWDONE_FAILED, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! return; +! } else { +! timer_startOneShot(TIMER_MAC_WATCHDOG,ACK_WAIT_TIME); +! change_state(S_TX_RXACK); +! } +! break; +! case S_RX_TXACK: //[sendNowDone] receiver +! //I'm a receiver, finished sending ACK (end of RX sequence) +! openqueue_freePacketBuffer(stupidmac_packetACK); +! packetReceived(); +! change_state(S_IDLE_LISTENING); +! break; +! default: +! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_SUBSEND_SENDDONE, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! change_state(S_IDLE_LISTENING); +! break; +! } +! } +! +! void radio_packet_received(OpenQueueEntry_t* msg) { +! ieee802154_header_iht received_ieee154_header; +! ieee802154_header_iht transmitted_ieee154_header; +! +! openserial_stop(); +! //ensure debug fires only after packet fully received +! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); +! +! msg->owner = COMPONENT_MAC; +! +! if (stupidmac_state!=S_TX_RXACK && stupidmac_state!=S_IDLE_LISTENING) { +! //not expecting this packet, throw away +! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was +! openqueue_freePacketBuffer(msg); +! return; +! } +! +! received_ieee154_header = retrieveIEEE802154header(msg); +! packetfunctions_tossHeader(msg,received_ieee154_header.headerLength); +! packetfunctions_tossFooter(msg,2); +! +! msg->l2_frameType = received_ieee154_header.frameType; +! memcpy(&(msg->l2_nextORpreviousHop),&(received_ieee154_header.src),sizeof(open_addr_t)); +! if ( received_ieee154_header.frameType==IEEE154_TYPE_DATA && +! !(idmanager_isMyAddress(&received_ieee154_header.panid))) { +! openserial_printError(COMPONENT_MAC,ERR_WRONG_PANID, +! (errorparameter_t)received_ieee154_header.panid.panid[0]*256+received_ieee154_header.panid.panid[1], +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! +! switch (stupidmac_state) { +! +! /*------------------- TX sequence ------------------------*/ +! case S_TX_RXACK: //[receive] transmitter +! transmitted_ieee154_header = retrieveIEEE802154header(stupidmac_dataFrameToSend); +! if (received_ieee154_header.dsn == transmitted_ieee154_header.dsn) { +! //I'm a transmitter, just received ACK (end of TX sequence) +! timer_stop(TIMER_MAC_WATCHDOG); +! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_ACKED); +! nores_sendDone(stupidmac_dataFrameToSend,E_SUCCESS); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer();//arm timer for next transmission +! change_state(S_IDLE_LISTENING); +! } +! openqueue_freePacketBuffer(msg);//free packet I received +! break; +! +! /*------------------- RX sequence ------------------------*/ +! case S_IDLE_LISTENING: //[receive] receiver +! //I'm a receiver, just received a packet +! if (received_ieee154_header.frameType==IEEE154_TYPE_DATA || received_ieee154_header.frameType==IEEE154_TYPE_CMD) { +! neighbors_indicateRx(&(msg->l2_nextORpreviousHop),msg->l1_rssi); +! if (idmanager_isMyAddress(&received_ieee154_header.dest)) { +! //this packet is unicast to me +! if (stupidmac_dataFrameReceived==NULL) { +! stupidmac_dataFrameReceived = msg; +! } else { +! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! //the sender requests an ACK +! if (received_ieee154_header.ackRequested) { +! change_state(S_RX_TXACKPREPARE); +! stupidmac_packetACK = openqueue_getFreePacketBuffer(); +! if (stupidmac_packetACK!=NULL) { +! //send ACK +! stupidmac_packetACK->creator = COMPONENT_MAC; +! stupidmac_packetACK->owner = COMPONENT_MAC; +! stupidmac_packetACK->l1_txPower = TX_POWER; +! stupidmac_packetACK->l1_channel = openwsn_frequency_channel; +! stupidmac_packetACK->l2_retriesLeft = 1; +! prependIEEE802154header(stupidmac_packetACK, +! IEEE154_TYPE_ACK, +! IEEE154_SEC_NO_SECURITY, +! received_ieee154_header.dsn, +! NULL); +! packetfunctions_reserveFooterSize(stupidmac_packetACK,2); +! change_state(S_RX_TXACKREADY); +! change_state(S_RX_TXACK); +! if (radio_send(stupidmac_packetACK)!=E_SUCCESS) { +! //abort +! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, +! (errorparameter_t)0,(errorparameter_t)2); +! openqueue_freePacketBuffer(stupidmac_packetACK); +! change_state(S_IDLE_LISTENING); +! } +! } else { +! openserial_printError(COMPONENT_MAC,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0,(errorparameter_t)0); +! change_state(S_IDLE_LISTENING); +! void packetReceived(); +! return; +! } +! } else { +! packetReceived(); +! } +! } else if (packetfunctions_isBroadcastMulticast(&received_ieee154_header.dest)==TRUE) { +! //this packet is broadcast +! if (stupidmac_dataFrameReceived==NULL) { +! stupidmac_dataFrameReceived = msg; +! } else { +! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, +! (errorparameter_t)1, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! packetReceived(); +! } else { +! openqueue_freePacketBuffer(msg); +! } +! } else { +! //not data. I could be an ACK but I'm not in S_TX_RXACK stupidmac_state, so I discard +! openqueue_freePacketBuffer(msg); +! } +! break; +! +! default: +! //this should never happen as error was caught above +! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was +! openqueue_freePacketBuffer(msg); +! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_RECEIVE, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! break; +! } +! } +! +! //=========================== private ========================================= +! +! void packetReceived(void) { +! if (stupidmac_dataFrameReceived->length>0) { +! //packet contains payload destined to an upper layer +! nores_receive(stupidmac_dataFrameReceived); +! } else { +! //packet contains no payload (KA) +! openqueue_freePacketBuffer(stupidmac_dataFrameReceived); +! } +! stupidmac_dataFrameReceived = NULL; +! } +! +! void armRandomBackoffTimer(void) { +! timer_startOneShot(TIMER_MAC_BACKOFF,MINBACKOFF); //TODO randomize +! } +! +! void change_state(uint8_t newstate) { +! stupidmac_state = newstate; +! switch (newstate) { +! case S_TX_TXDATAPREPARE: +! case S_TX_TXDATA: +! case S_RX_TXACKPREPARE: +! case S_RX_TXACK: +! //atomic P3OUT |= 0x20; +! break; +! case S_TX_TXDATAREADY: +! case S_TX_RXACK: +! case S_RX_TXACKREADY: +! case S_IDLE_LISTENING: +! //atomic P3OUT &= ~0x20; +! break; +! } +! } +! +! bool stupidmac_debugPrint(void) { +! return FALSE; +! } +! +! //======= timers firing +! +! //periodic timer used to transmit, and to trigger serial input/output +! void timer_mac_periodic_fired(void) { +! #ifndef SERIALINSCHEDULER +! openserial_stop(); +! #endif +! //trigger transmit +! armRandomBackoffTimer(); +! #ifndef SERIALINSCHEDULER +! //trigger serial input/output +! stupidmac_serialInOutputMode = !stupidmac_serialInOutputMode; +! if (stupidmac_serialInOutputMode) { +! openserial_startOutput(); +! } else { +! openserial_startInput(); +! } +! #endif +! } +! +! //this function is the one which really initiates the transmission of a packet. +! //It only does so if the MAC layer is in S_IDLE_LISTENING stupidmac_state, otherwise it defers +! void timer_mac_backoff_fired(void) { +! if (stupidmac_state==S_IDLE_LISTENING) { +! if (stupidmac_dataFrameToSend!=NULL) { +! openserial_printError(COMPONENT_MAC,ERR_DATAFRAMETOSEND_ERROR, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! stupidmac_dataFrameToSend = openqueue_inQueue(IS_NOT_ADV); +! if (stupidmac_dataFrameToSend==NULL) { +! stupidmac_dataFrameToSend = openqueue_inQueue(IS_ADV); +! } +! if (stupidmac_dataFrameToSend!=NULL) { +! change_state(S_TX_TXDATA); +! if (radio_send(stupidmac_dataFrameToSend)!=E_SUCCESS) { +! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer();//arm to retry later +! change_state(S_IDLE_LISTENING); +! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! } +! } else { +! //retry later on +! armRandomBackoffTimer(); +! } +! } +! +! void timer_mac_watchdog_fired(void) { +! switch (stupidmac_state) { +! case S_TX_RXACK: +! //I'm a transmitter, didn't receive ACK (end of TX sequence). +! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_NOT_ACKED); +! stupidmac_dataFrameToSend->l2_retriesLeft--; +! if (stupidmac_dataFrameToSend->l2_retriesLeft==0) { +! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); +! stupidmac_dataFrameToSend = NULL; +! armRandomBackoffTimer(); +! change_state(S_IDLE_LISTENING); +! break; +! } +! //retransmit later on +! armRandomBackoffTimer(); +! stupidmac_dataFrameToSend = NULL; +! change_state(S_IDLE_LISTENING); +! break; +! default: +! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_FASTTIMER_FIRED, +! (errorparameter_t)stupidmac_state, +! (errorparameter_t)0); +! change_state(S_IDLE_LISTENING); +! break; +! } + } +\ No newline at end of file +diff -crB openwsn/02a-MAClow/stupidmac/stupidmac.h ../../../sys/net/openwsn/02a-MAClow/stupidmac/stupidmac.h +*** openwsn/02a-MAClow/stupidmac/stupidmac.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/stupidmac/stupidmac.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,60 **** +! /** +! \brief Implementation of stupidMAC +! +! \author Thomas Watteyne , August 2010 +! */ +! +! #ifndef __STUPIDMAC_H +! #define __STUPIDMAC_H +! +! #include "openwsn.h" +! +! enum { +! //default +! S_IDLE_LISTENING = 0, +! //transmitter +! S_TX_TXDATAPREPARE = 1, +! S_TX_TXDATAREADY = 2, +! S_TX_TXDATA = 3, +! S_TX_RXACK = 4, +! //receiver +! S_RX_TXACKPREPARE = 5, +! S_RX_TXACKREADY = 6, +! S_RX_TXACK = 7, +! }; +! +! enum { +! IMMEDIATELY = 1, //used as timer value which is very small +! WATCHDOG_PREPARESEND = 16000, //500ms +! }; +! +! enum { +! WAS_ACKED = TRUE, +! WAS_NOT_ACKED = FALSE, +! }; +! +! //timer wait times (in 1/32768 seconds), slow version +! /*enum { +! PERIODICTIMERPERIOD = 9828, // 300ms +! MINBACKOFF = 6552, // 200ms +! ACK_WAIT_TIME = 3276, // 100ms +! };*/ +! +! //timer wait times (in 1/32768 seconds), fast version +! enum { +! PERIODICTIMERPERIOD = 982, // 30ms +! MINBACKOFF = 655, // 20ms +! ACK_WAIT_TIME = 327, // 10ms +! }; +! +! void stupidmac_init(); +! error_t stupidmac_send(OpenQueueEntry_t* msg); +! void stupidmac_sendDone(OpenQueueEntry_t* msg, error_t error); +! void stupidmac_packet_received(OpenQueueEntry_t* pkt); +! void stupidmac_sendDone(OpenQueueEntry_t* packetReceived, error_t error); +! void timer_mac_backoff_fired(); +! void timer_mac_watchdog_fired(); +! void timer_mac_periodic_fired(); +! bool stupidmac_debugPrint(); +! +! #endif +--- 1,60 ---- +! /** +! \brief Implementation of stupidMAC +! +! \author Thomas Watteyne , August 2010 +! */ +! +! #ifndef __STUPIDMAC_H +! #define __STUPIDMAC_H +! +! #include "openwsn.h" +! +! enum { +! //default +! S_IDLE_LISTENING = 0, +! //transmitter +! S_TX_TXDATAPREPARE = 1, +! S_TX_TXDATAREADY = 2, +! S_TX_TXDATA = 3, +! S_TX_RXACK = 4, +! //receiver +! S_RX_TXACKPREPARE = 5, +! S_RX_TXACKREADY = 6, +! S_RX_TXACK = 7, +! }; +! +! enum { +! IMMEDIATELY = 1, //used as timer value which is very small +! WATCHDOG_PREPARESEND = 16000, //500ms +! }; +! +! enum { +! WAS_ACKED = TRUE, +! WAS_NOT_ACKED = FALSE, +! }; +! +! //timer wait times (in 1/32768 seconds), slow version +! /*enum { +! PERIODICTIMERPERIOD = 9828, // 300ms +! MINBACKOFF = 6552, // 200ms +! ACK_WAIT_TIME = 3276, // 100ms +! };*/ +! +! //timer wait times (in 1/32768 seconds), fast version +! enum { +! PERIODICTIMERPERIOD = 982, // 30ms +! MINBACKOFF = 655, // 20ms +! ACK_WAIT_TIME = 327, // 10ms +! }; +! +! void stupidmac_init(void); +! owerror_t stupidmac_send(OpenQueueEntry_t* msg); +! void stupidmac_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void stupidmac_packet_received(OpenQueueEntry_t* pkt); +! void stupidmac_sendDone(OpenQueueEntry_t* packetReceived, owerror_t error); +! void timer_mac_backoff_fired(void); +! void timer_mac_watchdog_fired(void); +! void timer_mac_periodic_fired(void); +! bool stupidmac_debugPrint(void); +! +! #endif +diff -crB openwsn/02a-MAClow/topology.c ../../../sys/net/openwsn/02a-MAClow/topology.c +*** openwsn/02a-MAClow/topology.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/topology.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,48 **** +! #include "openwsn.h" +! #include "topology.h" +! #include "idmanager.h" +! +! //=========================== defines ========================================= +! +! #define TOPOLOGY_MOTE1 0x6f +! #define TOPOLOGY_MOTE2 0xb9 +! #define TOPOLOGY_MOTE3 0x3b +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) { +! bool returnVal; +! switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) { +! case TOPOLOGY_MOTE1: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! case TOPOLOGY_MOTE2: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE1 || +! ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! case TOPOLOGY_MOTE3: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! default: +! returnVal=TRUE; +! } +! return returnVal; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,56 ---- +! #include "openwsn.h" +! #include "topology.h" +! #include "idmanager.h" +! +! //=========================== defines ========================================= +! +! #define TOPOLOGY_MOTE1 0x01 +! #define TOPOLOGY_MOTE2 0x02 +! #define TOPOLOGY_MOTE3 0x03 +! #define TOPOLOGY_MOTE4 0x04 +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) { +! bool returnVal; +! switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) { +! case TOPOLOGY_MOTE1: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! case TOPOLOGY_MOTE2: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE1 || +! ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! case TOPOLOGY_MOTE3: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2 || +! ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE4) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! case TOPOLOGY_MOTE4: +! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) { +! returnVal=TRUE; +! } else { +! returnVal=FALSE; +! } +! break; +! default: +! returnVal=TRUE; +! } +! return returnVal; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/02a-MAClow/topology.h ../../../sys/net/openwsn/02a-MAClow/topology.h +*** openwsn/02a-MAClow/topology.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02a-MAClow/topology.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,31 **** +! #ifndef __TOPOLOGY_H +! #define __TOPOLOGY_H +! +! /** +! \addtogroup MAClow +! \{ +! \addtogroup topology +! \{ +! */ +! +! #include "openwsn.h" +! #include "IEEE802154.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== prototypes ====================================== +! +! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,31 ---- +! #ifndef __TOPOLOGY_H +! #define __TOPOLOGY_H +! +! /** +! \addtogroup MAClow +! \{ +! \addtogroup topology +! \{ +! */ +! +! #include "openwsn.h" +! #include "IEEE802154.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== prototypes ====================================== +! +! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/02b-MAChigh/Makefile ../../../sys/net/openwsn/02b-MAChigh/Makefile +*** openwsn/02b-MAChigh/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/02b-MAChigh/Makefile Wed Jan 15 13:48:26 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBMOD) ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/02b-MAChigh/neighbors.c ../../../sys/net/openwsn/02b-MAChigh/neighbors.c +*** openwsn/02b-MAChigh/neighbors.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02b-MAChigh/neighbors.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,682 **** +! #include "openwsn.h" +! #include "neighbors.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "IEEE802154E.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! neighborRow_t neighbors[MAXNUMNEIGHBORS]; +! dagrank_t myDAGrank; +! uint8_t debugRow; +! icmpv6rpl_dio_ht* dio; //keep it global to be able to debug correctly. +! } neighbors_vars_t; +! +! neighbors_vars_t neighbors_vars; +! +! //=========================== prototypes ====================================== +! +! void registerNewNeighbor( +! open_addr_t* neighborID, +! int8_t rssi, +! asn_t* asnTimestamp +! ); +! bool isNeighbor(open_addr_t* neighbor); +! void removeNeighbor(uint8_t neighborIndex); +! bool isThisRowMatching( +! open_addr_t* address, +! uint8_t rowNumber +! ); +! +! //=========================== public ========================================== +! +! /** +! \brief Initializes this module. +! */ +! void neighbors_init() { +! +! // clear module variables +! memset(&neighbors_vars,0,sizeof(neighbors_vars_t)); +! +! // set myDAGrank +! if (idmanager_getIsDAGroot()==TRUE) { +! neighbors_vars.myDAGrank=0; +! } else { +! neighbors_vars.myDAGrank=DEFAULTDAGRANK; +! } +! } +! +! //===== getters +! +! /** +! \brief Retrieve this mote's current DAG rank. +! +! \returns This mote's current DAG rank. +! */ +! dagrank_t neighbors_getMyDAGrank() { +! return neighbors_vars.myDAGrank; +! } +! +! /** +! \brief Retrieve the number of neighbors this mote's currently knows of. +! +! \returns The number of neighbors this mote's currently knows of. +! */ +! uint8_t neighbors_getNumNeighbors() { +! uint8_t i; +! uint8_t returnVal; +! +! returnVal=0; +! for (i=0;itype = ADDR_NONE; +! +! foundPreferred = FALSE; +! numNeighbors = 0; +! minRankVal = MAXDAGRANK; +! minRankIdx = MAXNUMNEIGHBORS+1; +! +! //===== step 1. Try to find preferred parent +! for (i=0; itype=ADDR_64B; +! foundPreferred=TRUE; +! } +! // identify neighbor with lowest rank +! if (neighbors_vars.neighbors[i].DAGrank < minRankVal) { +! minRankVal=neighbors_vars.neighbors[i].DAGrank; +! minRankIdx=i; +! } +! numNeighbors++; +! } +! } +! +! //===== step 2. (backup) Promote neighbor with min rank to preferred parent +! if (foundPreferred==FALSE && numNeighbors > 0){ +! // promote neighbor +! neighbors_vars.neighbors[minRankIdx].parentPreference = MAXPREFERENCE; +! neighbors_vars.neighbors[minRankIdx].stableNeighbor = TRUE; +! neighbors_vars.neighbors[minRankIdx].switchStabilityCounter = 0; +! // return its address +! memcpy(addressToWrite,&(neighbors_vars.neighbors[minRankIdx].addr_64b),sizeof(open_addr_t)); +! addressToWrite->type=ADDR_64B; +! foundPreferred=TRUE; +! } +! +! return foundPreferred; +! } +! +! /** +! \brief Find neighbor to which to send KA. +! +! This function iterates through the neighbor table and identifies the neighbor +! we need to send a KA to, if any. This neighbor satisfies the following +! conditions: +! - it is one of our preferred parents +! - we haven't heard it for over KATIMEOUT +! +! \returns A pointer to the neighbor's address, or NULL if no KA is needed. +! */ +! open_addr_t* neighbors_getKANeighbor() { +! uint8_t i; +! uint16_t timeSinceHeard; +! open_addr_t* addrPreferred; +! open_addr_t* addrOther; +! +! // initialize +! addrPreferred = NULL; +! addrOther = NULL; +! +! // scan through the neighbor table, and populate addrPreferred and addrOther +! for (i=0;iKATIMEOUT) { +! // this neighbor needs to be KA'ed to +! if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) { +! // its a preferred parent +! addrPreferred = &(neighbors_vars.neighbors[i].addr_64b); +! } else { +! // its not a preferred parent +! // Note: commented out since policy is not to KA to non-preferred parents +! // addrOther = &(neighbors_vars.neighbors[i].addr_64b); +! } +! } +! } +! } +! +! // return the addr of the most urgent KA to send: +! // - if available, preferred parent +! // - if not, non preferred parent +! if (addrPreferred!=NULL) { +! return addrPreferred; +! } else if (addrOther!=NULL) { +! return addrOther; +! } else { +! return NULL; +! } +! } +! +! //===== interrogators +! +! /** +! \brief Indicate whether some neighbor is a stable neighbor +! +! \param address [in] The address of the neighbor, a full 128-bit IPv6 addres. +! +! \returns TRUE if that neighbor is stable, FALSE otherwise. +! */ +! bool neighbors_isStableNeighbor(open_addr_t* address) { +! uint8_t i; +! open_addr_t temp_addr_64b; +! open_addr_t temp_prefix; +! bool returnVal; +! +! // by default, not stable +! returnVal = FALSE; +! +! // but neighbor's IPv6 address in prefix and EUI64 +! switch (address->type) { +! case ADDR_128B: +! packetfunctions_ip128bToMac64b(address,&temp_prefix,&temp_addr_64b); +! break; +! default: +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)0); +! return returnVal; +! } +! +! // iterate through neighbor table +! for (i=0;i= neighbors_getMyDAGrank()) { +! returnVal = TRUE; +! } else { +! returnVal = FALSE; +! } +! +! return returnVal; +! } +! +! //===== updating neighbor information +! +! /** +! \brief Indicate some (non-ACK) packet was received from a neighbor. +! +! This function should be called for each received (non-ACK) packet so neighbor +! statistics in the neighbor table can be updated. +! +! The fields which are updated are: +! - numRx +! - rssi +! - asn +! - stableNeighbor +! - switchStabilityCounter +! +! \param l2_src [in] MAC source address of the packet, i.e. the neighbor who sent +! the packet just received. +! \param rssi [in] RSSI with which this packet was received. +! \param asnTs [in] ASN at which this packet was received. +! */ +! void neighbors_indicateRx(open_addr_t* l2_src, +! int8_t rssi, +! asn_t* asnTs) { +! uint8_t i; +! bool newNeighbor; +! +! // update existing neighbor +! newNeighbor = TRUE; +! for (i=0;iBADNEIGHBORMAXRSSI) { +! neighbors_vars.neighbors[i].switchStabilityCounter++; +! if (neighbors_vars.neighbors[i].switchStabilityCounter>=SWITCHSTABILITYTHRESHOLD) { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! neighbors_vars.neighbors[i].stableNeighbor=TRUE; +! } +! } else { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! } +! } else if (neighbors_vars.neighbors[i].stableNeighbor==TRUE) { +! if (neighbors_vars.neighbors[i].rssi=SWITCHSTABILITYTHRESHOLD) { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! neighbors_vars.neighbors[i].stableNeighbor=FALSE; +! } +! } else { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! } +! } +! +! // stop looping +! break; +! } +! } +! +! // register new neighbor +! if (newNeighbor==TRUE) { +! registerNewNeighbor(l2_src, rssi, asnTs); +! } +! } +! +! /** +! \brief Indicate some packet was sent to some neighbor. +! +! This function should be called for each transmitted (non-ACK) packet so +! neighbor statistics in the neighbor table can be updated. +! +! The fields which are updated are: +! - numTx +! - numTxACK +! - asn +! +! \param l2_dest [in] MAC destination address of the packet, i.e. the neighbor +! who I just sent the packet to. +! \param numTxAttempts [in] Number of transmission attempts to this neighbor. +! \param was_finally_acked [in] TRUE iff the packet was ACK'ed by the neighbor +! on final transmission attempt. +! \param asnTs [in] ASN of the last transmission attempt. +! */ +! void neighbors_indicateTx(open_addr_t* l2_dest, +! uint8_t numTxAttempts, +! bool was_finally_acked, +! asn_t* asnTs) { +! uint8_t i; +! // don't run through this function if packet was sent to broadcast address +! if (packetfunctions_isBroadcastMulticast(l2_dest)==TRUE) { +! return; +! } +! +! // loop through neighbor table +! for (i=0;i(0xff-numTxAttempts)) { +! neighbors_vars.neighbors[i].numWraps++; //counting the number of times that tx wraps. +! neighbors_vars.neighbors[i].numTx/=2; +! neighbors_vars.neighbors[i].numTxACK/=2; +! } +! // update statistics +! neighbors_vars.neighbors[i].numTx += numTxAttempts; +! +! if (was_finally_acked==TRUE) { +! neighbors_vars.neighbors[i].numTxACK++; +! memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t)); +! } +! break; +! } +! } +! } +! +! /** +! \brief Indicate I just received a RPL DIO from a neighbor. +! +! This function should be called for each received a DIO is received so neighbor +! routing information in the neighbor table can be updated. +! +! The fields which are updated are: +! - DAGrank +! +! \param msg [in] The received message with msg->payload pointing to the DIO +! header. +! */ +! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg) { +! uint8_t i; +! +! // take ownership over the packet +! msg->owner = COMPONENT_NEIGHBORS; +! +! // update rank of that neighbor in table +! neighbors_vars.dio = (icmpv6rpl_dio_ht*)(msg->payload); +! if (isNeighbor(&(msg->l2_nextORpreviousHop))==TRUE) { +! for (i=0;il2_nextORpreviousHop),i)) { +! if ( +! neighbors_vars.dio->rank>neighbors_vars.neighbors[i].DAGrank && +! neighbors_vars.dio->rank - neighbors_vars.neighbors[i].DAGrank>DEFAULTLINKCOST +! ) { +! // the new DAGrank looks suspiciously high, only increment a bit +! neighbors_vars.neighbors[i].DAGrank += DEFAULTLINKCOST; +! openserial_printError(COMPONENT_NEIGHBORS,ERR_LARGE_DAGRANK, +! (errorparameter_t)neighbors_vars.dio->rank, +! (errorparameter_t)neighbors_vars.neighbors[i].DAGrank); +! } else { +! neighbors_vars.neighbors[i].DAGrank = neighbors_vars.dio->rank; +! } +! break; +! } +! } +! } +! // update my routing information +! neighbors_updateMyDAGrankAndNeighborPreference(); +! } +! +! //===== write addresses +! +! /** +! \brief Write the 64-bit address of some neighbor to some location. +! +! */ +! +! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index){ +! switch(addr_type) { +! case ADDR_64B: +! memcpy(&(address->addr_64b),&(neighbors_vars.neighbors[index].addr_64b.addr_64b),LENGTH_ADDR64b); +! address->type=ADDR_64B; +! break; +! default: +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)addr_type, +! (errorparameter_t)1); +! break; +! } +! } +! +! +! //===== managing routing info +! +! /** +! \brief Update my DAG rank and neighbor preference. +! +! Call this function whenever some data is changed that could cause this mote's +! routing decisions to change. Examples are: +! - I received a DIO which updated by neighbor table. If this DIO indicated a +! very low DAGrank, I may want to change by routing parent. +! - I became a DAGroot, so my DAGrank should be 0. +! */ +! void neighbors_updateMyDAGrankAndNeighborPreference() { +! uint8_t i; +! uint8_t linkCost; +! uint32_t tentativeDAGrank; // 32-bit since is used to sum +! uint8_t prefParentIdx; +! bool prefParentFound; +! +! // if I'm a DAGroot, my DAGrank is always 0 +! if ((idmanager_getIsDAGroot())==TRUE) { +! neighbors_vars.myDAGrank=0; +! return; +! } +! +! // reset my DAG rank to max value. May be lowered below. +! neighbors_vars.myDAGrank = MAXDAGRANK; +! +! // by default, I haven't found a preferred parent +! prefParentFound = FALSE; +! prefParentIdx = 0; +! +! // loop through neighbor table, update myDAGrank +! for (i=0;itype!=ADDR_64B) { +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)2); +! return; +! } +! // add this neighbor +! if (isNeighbor(address)==FALSE) { +! i=0; +! while(itype) { +! case ADDR_64B: +! return neighbors_vars.neighbors[rowNumber].used && +! packetfunctions_sameAddress(address,&neighbors_vars.neighbors[rowNumber].addr_64b); +! default: +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)3); +! return FALSE; +! } +! } +--- 1,693 ---- +! #include "openwsn.h" +! #include "neighbors.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "IEEE802154E.h" +! +! //=========================== variables ======================================= +! +! neighbors_vars_t neighbors_vars; +! +! //=========================== prototypes ====================================== +! +! void registerNewNeighbor( +! open_addr_t* neighborID, +! int8_t rssi, +! asn_t* asnTimestamp, +! bool joinPrioPresent, +! uint8_t joinPrio +! ); +! bool isNeighbor(open_addr_t* neighbor); +! void removeNeighbor(uint8_t neighborIndex); +! bool isThisRowMatching( +! open_addr_t* address, +! uint8_t rowNumber +! ); +! +! //=========================== public ========================================== +! +! /** +! \brief Initializes this module. +! */ +! void neighbors_init(void) { +! +! // clear module variables +! memset(&neighbors_vars,0,sizeof(neighbors_vars_t)); +! +! // set myDAGrank +! if (idmanager_getIsDAGroot()==TRUE) { +! neighbors_vars.myDAGrank=0; +! } else { +! neighbors_vars.myDAGrank=DEFAULTDAGRANK; +! } +! } +! +! //===== getters +! +! /** +! \brief Retrieve this mote's current DAG rank. +! +! \returns This mote's current DAG rank. +! */ +! dagrank_t neighbors_getMyDAGrank(void) { +! return neighbors_vars.myDAGrank; +! } +! +! /** +! \brief Retrieve the number of neighbors this mote's currently knows of. +! +! \returns The number of neighbors this mote's currently knows of. +! */ +! uint8_t neighbors_getNumNeighbors(void) { +! uint8_t i; +! uint8_t returnVal; +! +! returnVal=0; +! for (i=0;itype = ADDR_NONE; +! +! foundPreferred = FALSE; +! numNeighbors = 0; +! minRankVal = MAXDAGRANK; +! minRankIdx = MAXNUMNEIGHBORS+1; +! +! //===== step 1. Try to find preferred parent +! for (i=0; itype=ADDR_64B; +! foundPreferred=TRUE; +! } +! // identify neighbor with lowest rank +! if (neighbors_vars.neighbors[i].DAGrank < minRankVal) { +! minRankVal=neighbors_vars.neighbors[i].DAGrank; +! minRankIdx=i; +! } +! numNeighbors++; +! } +! } +! +! //===== step 2. (backup) Promote neighbor with min rank to preferred parent +! if (foundPreferred==FALSE && numNeighbors > 0){ +! // promote neighbor +! neighbors_vars.neighbors[minRankIdx].parentPreference = MAXPREFERENCE; +! neighbors_vars.neighbors[minRankIdx].stableNeighbor = TRUE; +! neighbors_vars.neighbors[minRankIdx].switchStabilityCounter = 0; +! // return its address +! memcpy(addressToWrite,&(neighbors_vars.neighbors[minRankIdx].addr_64b),sizeof(open_addr_t)); +! addressToWrite->type=ADDR_64B; +! foundPreferred=TRUE; +! } +! +! return foundPreferred; +! } +! +! /** +! \brief Find neighbor to which to send KA. +! +! This function iterates through the neighbor table and identifies the neighbor +! we need to send a KA to, if any. This neighbor satisfies the following +! conditions: +! - it is one of our preferred parents +! - we haven't heard it for over KATIMEOUT +! +! \returns A pointer to the neighbor's address, or NULL if no KA is needed. +! */ +! open_addr_t* neighbors_getKANeighbor(void) { +! uint8_t i; +! uint16_t timeSinceHeard; +! open_addr_t* addrPreferred; +! open_addr_t* addrOther; +! +! // initialize +! addrPreferred = NULL; +! addrOther = NULL; +! +! // scan through the neighbor table, and populate addrPreferred and addrOther +! for (i=0;iKATIMEOUT) { +! // this neighbor needs to be KA'ed to +! if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) { +! // its a preferred parent +! addrPreferred = &(neighbors_vars.neighbors[i].addr_64b); +! } else { +! // its not a preferred parent +! // Note: commented out since policy is not to KA to non-preferred parents +! // addrOther = &(neighbors_vars.neighbors[i].addr_64b); +! } +! } +! } +! } +! +! // return the addr of the most urgent KA to send: +! // - if available, preferred parent +! // - if not, non preferred parent +! if (addrPreferred!=NULL) { +! return addrPreferred; +! } else if (addrOther!=NULL) { +! return addrOther; +! } else { +! return NULL; +! } +! } +! +! +! //===== interrogators +! +! /** +! \brief Indicate whether some neighbor is a stable neighbor +! +! \param[in] address The address of the neighbor, a full 128-bit IPv6 addres. +! +! \returns TRUE if that neighbor is stable, FALSE otherwise. +! */ +! bool neighbors_isStableNeighbor(open_addr_t* address) { +! uint8_t i; +! open_addr_t temp_addr_64b; +! open_addr_t temp_prefix; +! bool returnVal; +! +! // by default, not stable +! returnVal = FALSE; +! +! // but neighbor's IPv6 address in prefix and EUI64 +! switch (address->type) { +! case ADDR_128B: +! packetfunctions_ip128bToMac64b(address,&temp_prefix,&temp_addr_64b); +! break; +! default: +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)0); +! return returnVal; +! } +! +! // iterate through neighbor table +! for (i=0;i= neighbors_getMyDAGrank()) { +! returnVal = TRUE; +! } else { +! returnVal = FALSE; +! } +! +! return returnVal; +! } +! +! //===== updating neighbor information +! +! /** +! \brief Indicate some (non-ACK) packet was received from a neighbor. +! +! This function should be called for each received (non-ACK) packet so neighbor +! statistics in the neighbor table can be updated. +! +! The fields which are updated are: +! - numRx +! - rssi +! - asn +! - stableNeighbor +! - switchStabilityCounter +! +! \param[in] l2_src MAC source address of the packet, i.e. the neighbor who sent +! the packet just received. +! \param[in] rssi RSSI with which this packet was received. +! \param[in] asnTs ASN at which this packet was received. +! */ +! void neighbors_indicateRx(open_addr_t* l2_src, +! int8_t rssi, +! asn_t* asnTs, +! bool joinPrioPresent, +! uint8_t joinPrio) { +! uint8_t i; +! bool newNeighbor; +! +! // update existing neighbor +! newNeighbor = TRUE; +! for (i=0;iBADNEIGHBORMAXRSSI) { +! neighbors_vars.neighbors[i].switchStabilityCounter++; +! if (neighbors_vars.neighbors[i].switchStabilityCounter>=SWITCHSTABILITYTHRESHOLD) { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! neighbors_vars.neighbors[i].stableNeighbor=TRUE; +! } +! } else { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! } +! } else if (neighbors_vars.neighbors[i].stableNeighbor==TRUE) { +! if (neighbors_vars.neighbors[i].rssi=SWITCHSTABILITYTHRESHOLD) { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! neighbors_vars.neighbors[i].stableNeighbor=FALSE; +! } +! } else { +! neighbors_vars.neighbors[i].switchStabilityCounter=0; +! } +! } +! +! // stop looping +! break; +! } +! } +! +! // register new neighbor +! if (newNeighbor==TRUE) { +! registerNewNeighbor(l2_src, rssi, asnTs, joinPrioPresent,joinPrio); +! } +! } +! +! /** +! \brief Indicate some packet was sent to some neighbor. +! +! This function should be called for each transmitted (non-ACK) packet so +! neighbor statistics in the neighbor table can be updated. +! +! The fields which are updated are: +! - numTx +! - numTxACK +! - asn +! +! \param[in] l2_dest MAC destination address of the packet, i.e. the neighbor +! who I just sent the packet to. +! \param[in] numTxAttempts Number of transmission attempts to this neighbor. +! \param[in] was_finally_acked TRUE iff the packet was ACK'ed by the neighbor +! on final transmission attempt. +! \param[in] asnTs ASN of the last transmission attempt. +! */ +! void neighbors_indicateTx(open_addr_t* l2_dest, +! uint8_t numTxAttempts, +! bool was_finally_acked, +! asn_t* asnTs) { +! uint8_t i; +! // don't run through this function if packet was sent to broadcast address +! if (packetfunctions_isBroadcastMulticast(l2_dest)==TRUE) { +! return; +! } +! +! // loop through neighbor table +! for (i=0;i(0xff-numTxAttempts)) { +! neighbors_vars.neighbors[i].numWraps++; //counting the number of times that tx wraps. +! neighbors_vars.neighbors[i].numTx/=2; +! neighbors_vars.neighbors[i].numTxACK/=2; +! } +! // update statistics +! neighbors_vars.neighbors[i].numTx += numTxAttempts; +! +! if (was_finally_acked==TRUE) { +! neighbors_vars.neighbors[i].numTxACK++; +! memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t)); +! } +! break; +! } +! } +! } +! +! /** +! \brief Indicate I just received a RPL DIO from a neighbor. +! +! This function should be called for each received a DIO is received so neighbor +! routing information in the neighbor table can be updated. +! +! The fields which are updated are: +! - DAGrank +! +! \param[in] msg The received message with msg->payload pointing to the DIO +! header. +! */ +! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg) { +! uint8_t i; +! +! // take ownership over the packet +! msg->owner = COMPONENT_NEIGHBORS; +! +! // update rank of that neighbor in table +! neighbors_vars.dio = (icmpv6rpl_dio_ht*)(msg->payload); +! if (isNeighbor(&(msg->l2_nextORpreviousHop))==TRUE) { +! for (i=0;il2_nextORpreviousHop),i)) { +! if ( +! neighbors_vars.dio->rank > neighbors_vars.neighbors[i].DAGrank && +! neighbors_vars.dio->rank - neighbors_vars.neighbors[i].DAGrank >(DEFAULTLINKCOST*2*MINHOPRANKINCREASE) +! ) { +! // the new DAGrank looks suspiciously high, only increment a bit +! neighbors_vars.neighbors[i].DAGrank += (DEFAULTLINKCOST*2*MINHOPRANKINCREASE); +! openserial_printError(COMPONENT_NEIGHBORS,ERR_LARGE_DAGRANK, +! (errorparameter_t)neighbors_vars.dio->rank, +! (errorparameter_t)neighbors_vars.neighbors[i].DAGrank); +! } else { +! neighbors_vars.neighbors[i].DAGrank = neighbors_vars.dio->rank; +! } +! break; +! } +! } +! } +! // update my routing information +! neighbors_updateMyDAGrankAndNeighborPreference(); +! } +! +! //===== write addresses +! +! /** +! \brief Write the 64-bit address of some neighbor to some location. +! +! */ +! +! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index){ +! switch(addr_type) { +! case ADDR_64B: +! memcpy(&(address->addr_64b),&(neighbors_vars.neighbors[index].addr_64b.addr_64b),LENGTH_ADDR64b); +! address->type=ADDR_64B; +! break; +! default: +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)addr_type, +! (errorparameter_t)1); +! break; +! } +! } +! +! +! //===== managing routing info +! +! /** +! \brief Update my DAG rank and neighbor preference. +! +! Call this function whenever some data is changed that could cause this mote's +! routing decisions to change. Examples are: +! - I received a DIO which updated by neighbor table. If this DIO indicated a +! very low DAGrank, I may want to change by routing parent. +! - I became a DAGroot, so my DAGrank should be 0. +! */ +! void neighbors_updateMyDAGrankAndNeighborPreference(void) { +! uint8_t i; +! uint16_t rankIncrease; +! uint32_t tentativeDAGrank; // 32-bit since is used to sum +! uint8_t prefParentIdx; +! bool prefParentFound; +! +! // if I'm a DAGroot, my DAGrank is always 0 +! if ((idmanager_getIsDAGroot())==TRUE) { +! neighbors_vars.myDAGrank=0; +! return; +! } +! +! // reset my DAG rank to max value. May be lowered below. +! neighbors_vars.myDAGrank = MAXDAGRANK; +! +! // by default, I haven't found a preferred parent +! prefParentFound = FALSE; +! prefParentIdx = 0; +! +! // loop through neighbor table, update myDAGrank +! for (i=0;itype!=ADDR_64B) { +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)2); +! return; +! } +! // add this neighbor +! if (isNeighbor(address)==FALSE) { +! i=0; +! while(itype) { +! case ADDR_64B: +! return neighbors_vars.neighbors[rowNumber].used && +! packetfunctions_sameAddress(address,&neighbors_vars.neighbors[rowNumber].addr_64b); +! default: +! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)3); +! return FALSE; +! } +! } +diff -crB openwsn/02b-MAChigh/neighbors.h ../../../sys/net/openwsn/02b-MAChigh/neighbors.h +*** openwsn/02b-MAChigh/neighbors.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02b-MAChigh/neighbors.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,103 **** +! #ifndef __NEIGHBORS_H +! #define __NEIGHBORS_H +! +! /** +! \addtogroup MAChigh +! \{ +! \addtogroup Neighbors +! \{ +! */ +! #include "openwsn.h" +! #include "icmpv6rpl.h" +! +! //=========================== define ========================================== +! +! #define MAXNUMNEIGHBORS 10 +! #define MAXPREFERENCE 2 +! #define BADNEIGHBORMAXRSSI -80 //dBm +! #define GOODNEIGHBORMINRSSI -90 //dBm +! #define SWITCHSTABILITYTHRESHOLD 3 +! #define DEFAULTLINKCOST 15 +! +! #define MAXDAGRANK 0xffff +! #define DEFAULTDAGRANK MAXDAGRANK +! +! //=========================== typedef ========================================= +! +! PRAGMA(pack(1)); +! typedef struct { +! bool used; +! uint8_t parentPreference; +! bool stableNeighbor; +! uint8_t switchStabilityCounter; +! open_addr_t addr_64b; +! dagrank_t DAGrank; +! int8_t rssi; +! uint8_t numRx; +! uint8_t numTx; +! uint8_t numTxACK; +! uint8_t numWraps;//number of times the tx counter wraps. can be removed if memory is a restriction. also check openvisualizer then. +! asn_t asn; +! } neighborRow_t; +! PRAGMA(pack()); +! +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t row; +! neighborRow_t neighborEntry; +! } debugNeighborEntry_t; +! PRAGMA(pack()); +! +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t last_addr_byte; // last byte of the neighbor's address +! int8_t rssi; +! uint8_t parentPreference; +! dagrank_t DAGrank; +! uint16_t asn; +! } netDebugNeigborEntry_t; +! PRAGMA(pack()); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void neighbors_init(); +! // getters +! dagrank_t neighbors_getMyDAGrank(); +! uint8_t neighbors_getNumNeighbors(); +! bool neighbors_getPreferredParentEui64(open_addr_t* addressToWrite); +! open_addr_t* neighbors_getKANeighbor(); +! // interrogators +! bool neighbors_isStableNeighbor(open_addr_t* address); +! bool neighbors_isPreferredParent(open_addr_t* address); +! bool neighbors_isNeighborWithLowerDAGrank(uint8_t index); +! bool neighbors_isNeighborWithHigherDAGrank(uint8_t index); +! +! // updating neighbor information +! void neighbors_indicateRx( +! open_addr_t* l2_src, +! int8_t rssi, +! asn_t* asnTimestamp +! ); +! void neighbors_indicateTx( +! open_addr_t* dest, +! uint8_t numTxAttempts, +! bool was_finally_acked, +! asn_t* asnTimestamp +! ); +! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg); +! // get addresses +! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index); +! // managing routing info +! void neighbors_updateMyDAGrankAndNeighborPreference(); +! // debug +! bool debugPrint_neighbors(); +! void debugNetPrint_neighbors(netDebugNeigborEntry_t* schlist); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,116 ---- +! #ifndef __NEIGHBORS_H +! #define __NEIGHBORS_H +! +! /** +! \addtogroup MAChigh +! \{ +! \addtogroup Neighbors +! \{ +! */ +! #include "openwsn.h" +! #include "icmpv6rpl.h" +! +! //=========================== define ========================================== +! +! #define MAXNUMNEIGHBORS 10 +! #define MAXPREFERENCE 2 +! #define BADNEIGHBORMAXRSSI -80 //dBm +! #define GOODNEIGHBORMINRSSI -90 //dBm +! #define SWITCHSTABILITYTHRESHOLD 3 +! #define DEFAULTLINKCOST 15 +! +! #define MAXDAGRANK 0xffff +! #define DEFAULTDAGRANK MAXDAGRANK +! #define MINHOPRANKINCREASE 256 //default value in RPL and Minimal 6TiSCH draft +! +! //=========================== typedef ========================================= +! +! //PRAGMA(pack(1)); +! typedef struct { +! bool used; +! uint8_t parentPreference; +! bool stableNeighbor; +! uint8_t switchStabilityCounter; +! open_addr_t addr_64b; +! dagrank_t DAGrank; +! int8_t rssi; +! uint8_t numRx; +! uint8_t numTx; +! uint8_t numTxACK; +! uint8_t numWraps;//number of times the tx counter wraps. can be removed if memory is a restriction. also check openvisualizer then. +! asn_t asn; +! uint8_t joinPrio; +! } neighborRow_t; +! //PRAGMA(pack()); +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t row; +! neighborRow_t neighborEntry; +! } debugNeighborEntry_t; +! //PRAGMA(pack()); +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t last_addr_byte; // last byte of the neighbor's address +! int8_t rssi; +! uint8_t parentPreference; +! dagrank_t DAGrank; +! uint16_t asn; +! } netDebugNeigborEntry_t; +! //PRAGMA(pack()); +! +! //=========================== module variables ================================ +! +! typedef struct { +! neighborRow_t neighbors[MAXNUMNEIGHBORS]; +! dagrank_t myDAGrank; +! uint8_t debugRow; +! icmpv6rpl_dio_ht* dio; //keep it global to be able to debug correctly. +! } neighbors_vars_t; +! +! //=========================== prototypes ====================================== +! +! void neighbors_init(void); +! // getters +! dagrank_t neighbors_getMyDAGrank(void); +! uint8_t neighbors_getNumNeighbors(void); +! bool neighbors_getPreferredParentEui64(open_addr_t* addressToWrite); +! open_addr_t* neighbors_getKANeighbor(void); +! +! // interrogators +! bool neighbors_isStableNeighbor(open_addr_t* address); +! bool neighbors_isPreferredParent(open_addr_t* address); +! bool neighbors_isNeighborWithLowerDAGrank(uint8_t index); +! bool neighbors_isNeighborWithHigherDAGrank(uint8_t index); +! +! // updating neighbor information +! void neighbors_indicateRx( +! open_addr_t* l2_src, +! int8_t rssi, +! asn_t* asnTimestamp, +! bool joinPrioPresent, +! uint8_t joinPrio +! ); +! +! void neighbors_indicateTx( +! open_addr_t* dest, +! uint8_t numTxAttempts, +! bool was_finally_acked, +! asn_t* asnTimestamp +! ); +! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg); +! // get addresses +! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index); +! // managing routing info +! void neighbors_updateMyDAGrankAndNeighborPreference(void); +! // debug +! bool debugPrint_neighbors(void); +! void debugNetPrint_neighbors(netDebugNeigborEntry_t* schlist); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/02b-MAChigh/res.c ../../../sys/net/openwsn/02b-MAChigh/res.c +*** openwsn/02b-MAChigh/res.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02b-MAChigh/res.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,355 **** +! #include "openwsn.h" +! #include "res.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "neighbors.h" +! #include "IEEE802154E.h" +! #include "iphc.h" +! #include "packetfunctions.h" +! #include "openrandom.h" +! #include "scheduler.h" +! #include "opentimers.h" +! #include "debugpins.h" +! //=========================== variables ======================================= +! +! typedef struct { +! uint16_t periodMaintenance; +! bool busySendingKa; // TRUE when busy sending a keep-alive +! bool busySendingAdv; // TRUE when busy sending an advertisement +! uint8_t dsn; // current data sequence number +! uint8_t MacMgtTaskCounter; // counter to determine what management task to do +! opentimer_id_t timerId; +! } res_vars_t; +! +! res_vars_t res_vars; +! +! //=========================== prototypes ====================================== +! +! error_t res_send_internal(OpenQueueEntry_t* msg); +! void sendAdv(); +! void sendKa(); +! void res_timer_cb(); +! +! //=========================== public ========================================== +! +! void res_init() { +! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); // fires every 1 sec on average +! res_vars.busySendingKa = FALSE; +! res_vars.busySendingAdv = FALSE; +! res_vars.dsn = 0; +! res_vars.MacMgtTaskCounter = 0; +! res_vars.timerId = opentimers_start(res_vars.periodMaintenance, +! TIMER_PERIODIC,TIME_MS, +! res_timer_cb); +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_myDAGrank() { +! uint8_t output=0; +! output = neighbors_getMyDAGrank(); +! openserial_printStatus(STATUS_DAGRANK,(uint8_t*)&output,sizeof(uint8_t)); +! return TRUE; +! } +! +! //======= from upper layer +! +! error_t res_send(OpenQueueEntry_t *msg) { +! msg->owner = COMPONENT_RES; +! msg->l2_frameType = IEEE154_TYPE_DATA; +! return res_send_internal(msg); +! } +! +! //======= from lower layer +! +! void task_resNotifSendDone() { +! OpenQueueEntry_t* msg; +! // get recently-sent packet from openqueue +! msg = openqueue_resGetSentPacket(); +! if (msg==NULL) { +! // log the error +! openserial_printCritical(COMPONENT_RES,ERR_NO_SENT_PACKET, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! return; +! } +! // declare it as mine +! msg->owner = COMPONENT_RES; +! // indicate transmission (to update statistics) +! if (msg->l2_sendDoneError==E_SUCCESS) { +! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), +! msg->l2_numTxAttempts, +! TRUE, +! &msg->l2_asn); +! } else { +! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), +! msg->l2_numTxAttempts, +! FALSE, +! &msg->l2_asn); +! } +! // send the packet to where it belongs +! if (msg->creator == COMPONENT_RES) { +! if (msg->l2_frameType==IEEE154_TYPE_BEACON) { +! // this is a ADV +! +! // not busy sending ADV anymore +! res_vars.busySendingAdv = FALSE; +! } else { +! // this is a KA +! +! // not busy sending KA anymore +! res_vars.busySendingKa = FALSE; +! } +! // discard packets +! openqueue_freePacketBuffer(msg); +! // restart a random timer +! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); +! opentimers_setPeriod(res_vars.timerId, +! TIME_MS, +! res_vars.periodMaintenance); +! } else { +! // send the rest up the stack +! iphc_sendDone(msg,msg->l2_sendDoneError); +! } +! } +! +! void task_resNotifReceive() { +! OpenQueueEntry_t* msg; +! +! // get received packet from openqueue +! msg = openqueue_resGetReceivedPacket(); +! if (msg==NULL) { +! // log the error +! openserial_printCritical(COMPONENT_RES,ERR_NO_RECEIVED_PACKET, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! return; +! } +! +! // declare it as mine +! msg->owner = COMPONENT_RES; +! +! // indicate reception (to update statistics) +! neighbors_indicateRx(&(msg->l2_nextORpreviousHop), +! msg->l1_rssi, +! &msg->l2_asn); +! +! // send the packet up the stack, if it qualifies +! switch (msg->l2_frameType) { +! case IEEE154_TYPE_BEACON: +! case IEEE154_TYPE_DATA: +! case IEEE154_TYPE_CMD: +! if (msg->length>0) { +! // send to upper layer +! iphc_receive(msg); +! } else { +! // free up the RAM +! openqueue_freePacketBuffer(msg); +! } +! break; +! case IEEE154_TYPE_ACK: +! default: +! // free the packet's RAM memory +! openqueue_freePacketBuffer(msg); +! // log the error +! openserial_printError(COMPONENT_RES,ERR_MSG_UNKNOWN_TYPE, +! (errorparameter_t)msg->l2_frameType, +! (errorparameter_t)0); +! break; +! } +! } +! +! //======= timer +! +! /** +! \brief Timer handlers which triggers MAC management task. +! +! This function is called in task context by the scheduler after the RES timer +! has fired. This timer is set to fire every second, on average. +! +! The body of this function executes one of the MAC management task. +! */ +! void timers_res_fired() { +! res_vars.MacMgtTaskCounter = (res_vars.MacMgtTaskCounter+1)%10; +! if (res_vars.MacMgtTaskCounter==0) { +! sendAdv(); // called every 10s +! } else { +! sendKa(); // called every second, except once every 10s +! } +! } +! +! //=========================== private ========================================= +! +! /** +! \brief Transfer packet to MAC. +! +! This function adds a IEEE802.15.4 header to the packet and leaves it the +! OpenQueue buffer. The very last thing it does is assigning this packet to the +! virtual component COMPONENT_RES_TO_IEEE802154E. Whenever it gets a change, +! IEEE802154E will handle the packet. +! +! \param [in] msg The packet to the transmitted +! +! \returns E_SUCCESS iff successful. +! */ +! error_t res_send_internal(OpenQueueEntry_t* msg) { +! // assign a number of retries +! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { +! msg->l2_retriesLeft = 1; +! } else { +! msg->l2_retriesLeft = TXRETRIES; +! } +! // record this packet's dsn (for matching the ACK) +! msg->l2_dsn = res_vars.dsn++; +! // this is a new packet which I never attempted to send +! msg->l2_numTxAttempts = 0; +! // transmit with the default TX power +! msg->l1_txPower = TX_POWER; +! // record the location, in the packet, where the l2 payload starts +! msg->l2_payload = msg->payload; +! // add a IEEE802.15.4 header +! ieee802154_prependHeader(msg, +! msg->l2_frameType, +! IEEE154_SEC_NO_SECURITY, +! msg->l2_dsn, +! &(msg->l2_nextORpreviousHop) +! ); +! // reserve space for 2-byte CRC +! packetfunctions_reserveFooterSize(msg,2); +! // change owner to IEEE802154E fetches it from queue +! msg->owner = COMPONENT_RES_TO_IEEE802154E; +! return E_SUCCESS; +! } +! +! /** +! \brief Send an advertisement. +! +! This is one of the MAC managament tasks. This function inlines in the +! timers_res_fired() function, but is declared as a separate function for better +! readability of the code. +! */ +! port_INLINE void sendAdv() { +! OpenQueueEntry_t* adv; +! +! if (ieee154e_isSynch()==FALSE) { +! // I'm not sync'ed +! +! // delete packets genereted by this module (ADV and KA) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_RES); +! +! // I'm now busy sending an ADV +! res_vars.busySendingAdv = FALSE; +! +! // stop here +! return; +! } +! +! if (res_vars.busySendingAdv==TRUE) { +! // don't continue if I'm still sending a previous ADV +! } +! +! // if I get here, I will send an ADV +! +! // get a free packet buffer +! adv = openqueue_getFreePacketBuffer(COMPONENT_RES); +! if (adv==NULL) { +! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! +! // declare ownership over that packet +! adv->creator = COMPONENT_RES; +! adv->owner = COMPONENT_RES; +! +! // reserve space for ADV-specific header +! packetfunctions_reserveHeaderSize(adv, ADV_PAYLOAD_LENGTH); +! // the actual value of the current ASN will be written by the +! // IEEE802.15.4e when transmitting +! +! // some l2 information about this packet +! adv->l2_frameType = IEEE154_TYPE_BEACON; +! adv->l2_nextORpreviousHop.type = ADDR_16B; +! adv->l2_nextORpreviousHop.addr_16b[0] = 0xff; +! adv->l2_nextORpreviousHop.addr_16b[1] = 0xff; +! +! // put in queue for MAC to handle +! res_send_internal(adv); +! +! // I'm now busy sending an ADV +! res_vars.busySendingAdv = TRUE; +! } +! +! /** +! \brief Send an keep-alive message, if nessary. +! +! This is one of the MAC managament tasks. This function inlines in the +! timers_res_fired() function, but is declared as a separate function for better +! readability of the code. +! */ +! port_INLINE void sendKa() { +! OpenQueueEntry_t* kaPkt; +! open_addr_t* kaNeighAddr; +! +! if (ieee154e_isSynch()==FALSE) { +! // I'm not sync'ed +! +! // delete packets genereted by this module (ADV and KA) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_RES); +! +! // I'm now busy sending a KA +! res_vars.busySendingKa = FALSE; +! +! // stop here +! return; +! } +! +! if (res_vars.busySendingKa==TRUE) { +! // don't proceed if I'm still sending a KA +! return; +! } +! +! kaNeighAddr = neighbors_getKANeighbor(); +! if (kaNeighAddr==NULL) { +! // don't proceed if I have no neighbor I need to send a KA to +! return; +! } +! +! // if I get here, I will send a KA +! +! // get a free packet buffer +! kaPkt = openqueue_getFreePacketBuffer(COMPONENT_RES); +! if (kaPkt==NULL) { +! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)1, +! (errorparameter_t)0); +! return; +! } +! +! // declare ownership over that packet +! kaPkt->creator = COMPONENT_RES; +! kaPkt->owner = COMPONENT_RES; +! +! // some l2 information about this packet +! kaPkt->l2_frameType = IEEE154_TYPE_DATA; +! memcpy(&(kaPkt->l2_nextORpreviousHop),kaNeighAddr,sizeof(open_addr_t)); +! +! // put in queue for MAC to handle +! res_send_internal(kaPkt); +! +! // I'm now busy sending a KA +! res_vars.busySendingKa = TRUE; +! } +! +! void res_timer_cb() { +! scheduler_push_task(timers_res_fired,TASKPRIO_RES); + } +\ No newline at end of file +--- 1,463 ---- +! #include "openwsn.h" +! #include "res.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "neighbors.h" +! #include "IEEE802154E.h" +! #include "iphc.h" +! #include "packetfunctions.h" +! #include "openrandom.h" +! #include "scheduler.h" +! #include "opentimers.h" +! //#include "debugpins.h" +! +! #include "thread.h" +! +! +! //=========================== variables ======================================= +! +! res_vars_t res_vars; +! //static char openwsn_res_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! +! //=========================== prototypes ====================================== +! +! owerror_t res_send_internal(OpenQueueEntry_t* msg, uint8_t iePresent,uint8_t frameVersion); +! void sendAdv(void); +! void sendKa(void); +! void res_timer_cb(void); +! uint8_t res_copySlotFrameAndLinkIE(OpenQueueEntry_t* adv);//returns reserved size +! +! //=========================== public ========================================== +! +! void res_init(void) { +! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); // fires every 1 sec on average +! res_vars.busySendingKa = FALSE; +! res_vars.busySendingAdv = FALSE; +! res_vars.dsn = 0; +! res_vars.MacMgtTaskCounter = 0; +! res_vars.timerId = opentimers_start(res_vars.periodMaintenance, +! TIMER_PERIODIC,TIME_MS, +! res_timer_cb); +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! // TODO: was bool but complained "conflicting types" +! uint8_t debugPrint_myDAGrank(void) { +! uint16_t output=0; +! output = neighbors_getMyDAGrank(); +! openserial_printStatus(STATUS_DAGRANK,(uint8_t*)&output,sizeof(uint16_t)); +! return TRUE; +! } +! +! //======= from upper layer +! +! owerror_t res_send(OpenQueueEntry_t *msg) { +! msg->owner = COMPONENT_RES; +! msg->l2_frameType = IEEE154_TYPE_DATA; +! return res_send_internal(msg,IEEE154_IELIST_NO,IEEE154_FRAMEVERSION_2006); +! } +! +! //======= from lower layer +! +! void task_resNotifSendDone(void) { +! OpenQueueEntry_t* msg; +! // get recently-sent packet from openqueue +! msg = openqueue_resGetSentPacket(); +! if (msg==NULL) { +! // log the error +! openserial_printCritical(COMPONENT_RES,ERR_NO_SENT_PACKET, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! return; +! } +! // declare it as mine +! msg->owner = COMPONENT_RES; +! // indicate transmission (to update statistics) +! if (msg->l2_sendDoneError==E_SUCCESS) { +! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), +! msg->l2_numTxAttempts, +! TRUE, +! &msg->l2_asn); +! } else { +! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), +! msg->l2_numTxAttempts, +! FALSE, +! &msg->l2_asn); +! } +! // send the packet to where it belongs +! if (msg->creator == COMPONENT_RES) { +! if (msg->l2_frameType==IEEE154_TYPE_BEACON) { +! // this is a ADV +! +! // not busy sending ADV anymore +! res_vars.busySendingAdv = FALSE; +! } else { +! // this is a KA +! +! // not busy sending KA anymore +! res_vars.busySendingKa = FALSE; +! } +! // discard packets +! openqueue_freePacketBuffer(msg); +! // restart a random timer +! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); +! opentimers_setPeriod(res_vars.timerId, +! TIME_MS, +! res_vars.periodMaintenance); +! } else { +! // send the rest up the stack +! iphc_sendDone(msg,msg->l2_sendDoneError); +! } +! } +! +! void task_resNotifReceive(void) { +! OpenQueueEntry_t* msg; +! +! // get received packet from openqueue +! msg = openqueue_resGetReceivedPacket(); +! if (msg==NULL) { +! // log the error +! openserial_printCritical(COMPONENT_RES,ERR_NO_RECEIVED_PACKET, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // abort +! return; +! } +! +! // declare it as mine +! msg->owner = COMPONENT_RES; +! +! // indicate reception (to update statistics) +! neighbors_indicateRx(&(msg->l2_nextORpreviousHop), +! msg->l1_rssi, +! &msg->l2_asn, +! msg->l2_joinPriorityPresent, +! msg->l2_joinPriority); +! +! msg->l2_joinPriorityPresent=FALSE; //reset it to avoid race conditions with this var. +! +! // send the packet up the stack, if it qualifies +! switch (msg->l2_frameType) { +! case IEEE154_TYPE_BEACON: +! case IEEE154_TYPE_DATA: +! case IEEE154_TYPE_CMD: +! if (msg->length>0) { +! // send to upper layer +! iphc_receive(msg); +! } else { +! // free up the RAM +! openqueue_freePacketBuffer(msg); +! } +! break; +! case IEEE154_TYPE_ACK: +! default: +! // free the packet's RAM memory +! openqueue_freePacketBuffer(msg); +! // log the error +! openserial_printError(COMPONENT_RES,ERR_MSG_UNKNOWN_TYPE, +! (errorparameter_t)msg->l2_frameType, +! (errorparameter_t)0); +! break; +! } +! } +! +! //======= timer +! +! /** +! \brief Timer handlers which triggers MAC management task. +! +! This function is called in task context by the scheduler after the RES timer +! has fired. This timer is set to fire every second, on average. +! +! The body of this function executes one of the MAC management task. +! */ +! void timers_res_fired(void) { +! res_vars.MacMgtTaskCounter = (res_vars.MacMgtTaskCounter+1)%10; +! if (res_vars.MacMgtTaskCounter==0) { +! sendAdv(); // called every 10s +! } else { +! sendKa(); // called every second, except once every 10s +! //leds_debug_toggle(); +! } +! } +! +! //=========================== private ========================================= +! +! /** +! \brief Transfer packet to MAC. +! +! This function adds a IEEE802.15.4 header to the packet and leaves it the +! OpenQueue buffer. The very last thing it does is assigning this packet to the +! virtual component COMPONENT_RES_TO_IEEE802154E. Whenever it gets a change, +! IEEE802154E will handle the packet. +! +! \param[in] msg The packet to the transmitted +! +! \returns E_SUCCESS iff successful. +! */ +! owerror_t res_send_internal(OpenQueueEntry_t* msg, uint8_t iePresent, uint8_t frameVersion) { +! // assign a number of retries +! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { +! msg->l2_retriesLeft = 1; +! } else { +! msg->l2_retriesLeft = TXRETRIES; +! } +! // record this packet's dsn (for matching the ACK) +! msg->l2_dsn = res_vars.dsn++; +! // this is a new packet which I never attempted to send +! msg->l2_numTxAttempts = 0; +! // transmit with the default TX power +! msg->l1_txPower = TX_POWER; +! // record the location, in the packet, where the l2 payload starts +! msg->l2_payload = msg->payload; +! // add a IEEE802.15.4 header +! ieee802154_prependHeader(msg, +! msg->l2_frameType, +! iePresent, +! frameVersion, +! IEEE154_SEC_NO_SECURITY, +! msg->l2_dsn, +! &(msg->l2_nextORpreviousHop) +! ); +! // reserve space for 2-byte CRC +! packetfunctions_reserveFooterSize(msg,2); +! // change owner to IEEE802154E fetches it from queue +! msg->owner = COMPONENT_RES_TO_IEEE802154E; +! return E_SUCCESS; +! } +! +! /** +! \brief Send an advertisement. +! +! This is one of the MAC managament tasks. This function inlines in the +! timers_res_fired() function, but is declared as a separate function for better +! readability of the code. +! */ +! port_INLINE void sendAdv(void) { +! OpenQueueEntry_t* adv; +! payload_IE_descriptor_t payload_IE_desc; +! MLME_IE_subHeader_t mlme_subHeader; +! uint8_t slotframeIElen=0; +! +! if (ieee154e_isSynch()==FALSE) { +! // I'm not sync'ed +! +! // delete packets genereted by this module (ADV and KA) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_RES); +! +! // I'm now busy sending an ADV +! res_vars.busySendingAdv = FALSE; +! +! // stop here +! return; +! } +! +! if (res_vars.busySendingAdv==TRUE) { +! // don't continue if I'm still sending a previous ADV +! } +! +! // if I get here, I will send an ADV +! +! // get a free packet buffer +! adv = openqueue_getFreePacketBuffer(COMPONENT_RES); +! if (adv==NULL) { +! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! +! // declare ownership over that packet +! adv->creator = COMPONENT_RES; +! adv->owner = COMPONENT_RES; +! +! // reserve space for ADV-specific header +! // xv poipoi -- reserving for IEs -- reverse order. +! //TODO reserve here for slotframe and link IE with minimal schedule information +! slotframeIElen = res_copySlotFrameAndLinkIE(adv); +! //create Sync IE with JP and ASN +! packetfunctions_reserveHeaderSize(adv, sizeof(synch_IE_t));//the asn + jp +! adv->l2_ASNpayload = adv->payload; //keep a pointer to where the ASN should be. +! // the actual value of the current ASN and JP will be written by the +! // IEEE802.15.4e when transmitting +! packetfunctions_reserveHeaderSize(adv, sizeof(MLME_IE_subHeader_t));//the MLME header +! //copy mlme sub-header +! mlme_subHeader.length_subID_type=sizeof(synch_IE_t) << IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; +! mlme_subHeader.length_subID_type |= (IEEE802154E_MLME_SYNC_IE_SUBID << IEEE802154E_MLME_SYNC_IE_SUBID_SHIFT) | IEEE802154E_DESC_TYPE_SHORT; +! //little endian +! adv->payload[0]= mlme_subHeader.length_subID_type & 0xFF; +! adv->payload[1]= (mlme_subHeader.length_subID_type >> 8) & 0xFF; +! +! packetfunctions_reserveHeaderSize(adv, sizeof(payload_IE_descriptor_t));//the payload IE header +! //prepare IE headers and copy them to the ADV +! +! payload_IE_desc.length_groupid_type = (sizeof(MLME_IE_subHeader_t)+sizeof(synch_IE_t)+slotframeIElen)<payload[0]= payload_IE_desc.length_groupid_type & 0xFF; +! adv->payload[1]= (payload_IE_desc.length_groupid_type >> 8) & 0xFF; +! +! // some l2 information about this packet +! adv->l2_frameType = IEEE154_TYPE_BEACON; +! adv->l2_nextORpreviousHop.type = ADDR_16B; +! adv->l2_nextORpreviousHop.addr_16b[0] = 0xff; +! adv->l2_nextORpreviousHop.addr_16b[1] = 0xff; +! +! // put in queue for MAC to handle +! res_send_internal(adv,IEEE154_IELIST_YES,IEEE154_FRAMEVERSION); +! +! // I'm now busy sending an ADV +! res_vars.busySendingAdv = TRUE; +! } +! +! port_INLINE uint8_t res_copySlotFrameAndLinkIE(OpenQueueEntry_t* adv){ +! MLME_IE_subHeader_t mlme_subHeader; +! uint8_t len=0; +! uint8_t linkOption=0; +! uint16_t slot=SCHEDULE_MINIMAL_6TISCH_ACTIVE_CELLS+SCHEDULE_MINIMAL_6TISCH_EB_CELLS; +! +! //reverse order and little endian. -- +! +! //for each link in the schedule (in basic configuration) +! //copy to adv 1B linkOption bitmap +! //copy to adv 2B ch.offset +! //copy to adv 2B timeslot +! +! //shared cells +! linkOption = (1<SCHEDULE_MINIMAL_6TISCH_EB_CELLS){ +! packetfunctions_reserveHeaderSize(adv,5); +! //ts +! adv->payload[0]= slot & 0xFF; +! adv->payload[1]= (slot >> 8) & 0xFF; +! //ch.offset as minimal draft +! adv->payload[2]= 0x00; +! adv->payload[3]= 0x00; +! //linkOption +! adv->payload[4]= linkOption; +! len+=5; +! slot--; +! } +! +! //eb slot +! linkOption = (1<payload[0]= SCHEDULE_MINIMAL_6TISCH_EB_CELLS & 0xFF; +! adv->payload[1]= (SCHEDULE_MINIMAL_6TISCH_EB_CELLS >> 8) & 0xFF; +! //ch.offset as minimal draft +! adv->payload[2]= 0x00; +! adv->payload[3]= 0x00; +! +! adv->payload[4]= linkOption; +! //now slotframe ie general fields +! //1B number of links == 6 +! //Slotframe Size 2B = 101 timeslots +! //1B slotframe handle (id) +! packetfunctions_reserveHeaderSize(adv,5);// +! len+=5; +! +! adv->payload[0]= SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_NUMBER; +! adv->payload[1]= SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE; +! adv->payload[2]= SCHEDULE_MINIMAL_6TISCH_SLOTFRAME_SIZE & 0xFF; +! adv->payload[3]= (SCHEDULE_MINIMAL_6TISCH_SLOTFRAME_SIZE >> 8) & 0xFF; +! adv->payload[4]= 0x06; //number of links +! +! //MLME sub IE header +! //1b -15 short ==0x00 +! //7b -8-14 Sub-ID=0x1b +! //8b - Length = 2 mlme-header + 5 slotframe general header +(6links*5bytes each) +! packetfunctions_reserveHeaderSize(adv, sizeof(MLME_IE_subHeader_t));//the MLME header +! +! +! //copy mlme sub-header +! mlme_subHeader.length_subID_type = len << IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; +! mlme_subHeader.length_subID_type |= (IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID << IEEE802154E_MLME_SYNC_IE_SUBID_SHIFT) | IEEE802154E_DESC_TYPE_SHORT; +! +! //little endian +! adv->payload[0]= mlme_subHeader.length_subID_type & 0xFF; +! adv->payload[1]= (mlme_subHeader.length_subID_type >> 8) & 0xFF; +! len+=2;//count len of mlme header +! +! return len; +! } +! +! /** +! \brief Send an keep-alive message, if nessary. +! +! This is one of the MAC managament tasks. This function inlines in the +! timers_res_fired() function, but is declared as a separate function for better +! readability of the code. +! */ +! port_INLINE void sendKa(void) { +! OpenQueueEntry_t* kaPkt; +! open_addr_t* kaNeighAddr; +! +! if (ieee154e_isSynch()==FALSE) { +! // I'm not sync'ed +! +! // delete packets genereted by this module (ADV and KA) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_RES); +! +! // I'm now busy sending a KA +! res_vars.busySendingKa = FALSE; +! +! // stop here +! return; +! } +! +! if (res_vars.busySendingKa==TRUE) { +! // don't proceed if I'm still sending a KA +! return; +! } +! +! kaNeighAddr = neighbors_getKANeighbor(); +! if (kaNeighAddr==NULL) { +! // don't proceed if I have no neighbor I need to send a KA to +! return; +! } +! +! // if I get here, I will send a KA +! +! // get a free packet buffer +! kaPkt = openqueue_getFreePacketBuffer(COMPONENT_RES); +! if (kaPkt==NULL) { +! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)1, +! (errorparameter_t)0); +! return; +! } +! +! // declare ownership over that packet +! kaPkt->creator = COMPONENT_RES; +! kaPkt->owner = COMPONENT_RES; +! +! // some l2 information about this packet +! kaPkt->l2_frameType = IEEE154_TYPE_DATA; +! memcpy(&(kaPkt->l2_nextORpreviousHop),kaNeighAddr,sizeof(open_addr_t)); +! +! // put in queue for MAC to handle +! res_send_internal(kaPkt,IEEE154_IELIST_NO,IEEE154_FRAMEVERSION_2006); +! +! // I'm now busy sending a KA +! res_vars.busySendingKa = TRUE; +! } +! +! void res_timer_cb(void) { +! puts(__PRETTY_FUNCTION__); +! scheduler_push_task(timers_res_fired,TASKPRIO_RES); +! /*thread_create(openwsn_res_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_RES, CREATE_STACKTEST, +! timers_res_fired, "timers res fired");*/ + } +\ No newline at end of file +diff -crB openwsn/02b-MAChigh/res.h ../../../sys/net/openwsn/02b-MAChigh/res.h +*** openwsn/02b-MAChigh/res.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02b-MAChigh/res.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,32 **** +! #ifndef __RES_H +! #define __RES_H +! +! /** +! \addtogroup MAChigh +! \{ +! \addtogroup RES +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void res_init(); +! bool debugPrint_myDAGrank(); +! // from upper layer +! error_t res_send(OpenQueueEntry_t *msg); +! // from lower layer +! void task_resNotifSendDone(); +! void task_resNotifReceive(); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,42 ---- +! #ifndef __RES_H +! #define __RES_H +! +! /** +! \addtogroup MAChigh +! \{ +! \addtogroup RES +! \{ +! */ +! #include "opentimers.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== module variables ================================ +! +! typedef struct { +! uint16_t periodMaintenance; +! bool busySendingKa; // TRUE when busy sending a keep-alive +! bool busySendingAdv; // TRUE when busy sending an advertisement +! uint8_t dsn; // current data sequence number +! uint8_t MacMgtTaskCounter; // counter to determine what management task to do +! opentimer_id_t timerId; +! } res_vars_t; +! +! //=========================== prototypes ====================================== +! +! void res_init(void); +! uint8_t debugPrint_myDAGrank(void); // TODO: was bool but complained "conflicting types" +! // from upper layer +! owerror_t res_send(OpenQueueEntry_t *msg); +! // from lower layer +! void task_resNotifSendDone(void); +! void task_resNotifReceive(void); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/02b-MAChigh/schedule.c ../../../sys/net/openwsn/02b-MAChigh/schedule.c +*** openwsn/02b-MAChigh/schedule.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02b-MAChigh/schedule.c Wed Jan 15 13:48:26 2014 +*************** +*** 1,476 **** +! #include "openwsn.h" +! #include "schedule.h" +! #include "openserial.h" +! #include "openrandom.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! scheduleEntry_t scheduleBuf[MAXACTIVESLOTS]; +! scheduleEntry_t* currentScheduleEntry; +! uint16_t frameLength; +! uint8_t backoffExponent; +! uint8_t backoff; +! slotOffset_t debugPrintRow; +! } schedule_vars_t; +! +! schedule_vars_t schedule_vars; +! +! typedef struct { +! uint8_t numActiveSlotsCur; +! uint8_t numActiveSlotsMax; +! } schedule_dbg_t; +! +! schedule_dbg_t schedule_dbg; +! +! //=========================== prototypes ====================================== +! +! void schedule_resetEntry(scheduleEntry_t* pScheduleEntry); +! +! //=========================== public ========================================== +! +! //=== admin +! +! void schedule_init() { +! uint8_t i; +! slotOffset_t running_slotOffset; +! open_addr_t temp_neighbor; +! +! // reset local variables +! memset(&schedule_vars,0,sizeof(schedule_vars_t)); +! for (i=0;itype!=CELLTYPE_OFF && +! slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { +! slotContainer++; +! } +! if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { +! // schedule has overflown +! openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! // fill that schedule entry with parameters passed +! slotContainer->slotOffset = slotOffset; +! slotContainer->type = type; +! slotContainer->shared = shared; +! slotContainer->channelOffset = channelOffset; +! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t)); +! +! if (schedule_vars.currentScheduleEntry==NULL) { +! // this is the first active slot added +! +! // the next slot of this slot is this slot +! slotContainer->next = slotContainer; +! +! // current slot points to this slot +! schedule_vars.currentScheduleEntry = slotContainer; +! } else { +! // this is NOT the first active slot added +! +! // find position in schedule +! previousSlotWalker = schedule_vars.currentScheduleEntry; +! while (1) { +! nextSlotWalker = previousSlotWalker->next; +! if ( +! ( +! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && +! (slotContainer->slotOffset < nextSlotWalker->slotOffset) +! ) +! || +! ( +! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && +! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) +! ) +! || +! ( +! (slotContainer->slotOffset < nextSlotWalker->slotOffset) && +! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) +! ) +! ) { +! break; +! } +! previousSlotWalker = nextSlotWalker; +! } +! // insert between previousSlotWalker and nextSlotWalker +! previousSlotWalker->next = slotContainer; +! slotContainer->next = nextSlotWalker; +! } +! +! // maintain debug stats +! schedule_dbg.numActiveSlotsCur++; +! if (schedule_dbg.numActiveSlotsCur>schedule_dbg.numActiveSlotsMax) { +! schedule_dbg.numActiveSlotsMax = schedule_dbg.numActiveSlotsCur; +! } +! ENABLE_INTERRUPTS(); +! } +! +! //=== from IEEE802154E: reading the schedule and updating statistics +! +! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! while (schedule_vars.currentScheduleEntry->slotOffset!=targetSlotOffset) { +! schedule_advanceSlot(); +! } +! ENABLE_INTERRUPTS(); +! } +! +! void schedule_advanceSlot() { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! // advance to next active slot +! schedule_vars.currentScheduleEntry = schedule_vars.currentScheduleEntry->next; +! ENABLE_INTERRUPTS(); +! } +! +! slotOffset_t schedule_getNextActiveSlotOffset() { +! slotOffset_t res; +! INTERRUPT_DECLARATION(); +! +! // return next active slot's slotOffset +! DISABLE_INTERRUPTS(); +! res = ((scheduleEntry_t*)(schedule_vars.currentScheduleEntry->next))->slotOffset; +! ENABLE_INTERRUPTS(); +! +! return res; +! } +! +! /** +! \brief Get the frame length. +! +! \returns The frame length. +! */ +! frameLength_t schedule_getFrameLength() { +! frameLength_t res; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! res= schedule_vars.frameLength; +! ENABLE_INTERRUPTS(); +! +! return res; +! } +! +! /** +! \brief Get the type of the current schedule entry. +! +! \returns The type of the current schedule entry. +! */ +! cellType_t schedule_getType() { +! cellType_t res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! res= schedule_vars.currentScheduleEntry->type; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! /** +! \brief Get the neighbor associated wit the current schedule entry. +! +! \returns The neighbor associated wit the current schedule entry. +! */ +! void schedule_getNeighbor(open_addr_t* addrToWrite) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! memcpy(addrToWrite,&(schedule_vars.currentScheduleEntry->neighbor),sizeof(open_addr_t)); +! ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Get the channel offset of the current schedule entry. +! +! \returns The channel offset of the current schedule entry. +! */ +! channelOffset_t schedule_getChannelOffset() { +! channelOffset_t res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! res= schedule_vars.currentScheduleEntry->channelOffset; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! /** +! \brief Check whether I can send on this slot. +! +! This function is called at the beginning of every TX slot. +! If the slot is *not* a shared slot, it always return TRUE. +! If the slot is a shared slot, it decrements the backoff counter and returns +! TRUE only if it hits 0. +! +! Note that the backoff counter is global, not per slot. +! +! \returns TRUE if it is OK to send on this slot, FALSE otherwise. +! */ +! bool schedule_getOkToSend() { +! bool returnVal; +! +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! if (schedule_vars.currentScheduleEntry->shared==FALSE) { +! // non-shared slot: backoff does not apply +! +! returnVal = TRUE; +! } else { +! // non-shared slot: check backoff before answering +! +! // decrement backoff +! if (schedule_vars.backoff>0) { +! schedule_vars.backoff--; +! } +! +! // only return TRUE if backoff hit 0 +! if (schedule_vars.backoff==0) { +! returnVal = TRUE; +! } else { +! returnVal = FALSE; +! } +! } +! +! ENABLE_INTERRUPTS(); +! return returnVal; +! } +! +! /** +! \brief Reset the backoff and backoffExponent. +! */ +! void schedule_resetBackoff() { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! // reset backoffExponent +! schedule_vars.backoffExponent = MINBE-1; +! // reset backoff +! schedule_vars.backoff = 0; +! +! ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Indicate the reception of a packet. +! */ +! void schedule_indicateRx(asn_t* asnTimestamp) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! // increment usage statistics +! schedule_vars.currentScheduleEntry->numRx++; +! +! // update last used timestamp +! memcpy(&(schedule_vars.currentScheduleEntry->lastUsedAsn), asnTimestamp, sizeof(asn_t)); +! ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Indicate the transmission of a packet. +! */ +! void schedule_indicateTx(asn_t* asnTimestamp, +! bool succesfullTx) { +! +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! // increment usage statistics +! if (schedule_vars.currentScheduleEntry->numTx==0xFF) { +! schedule_vars.currentScheduleEntry->numTx/=2; +! schedule_vars.currentScheduleEntry->numTxACK/=2; +! } +! schedule_vars.currentScheduleEntry->numTx++; +! if (succesfullTx==TRUE) { +! schedule_vars.currentScheduleEntry->numTxACK++; +! } +! +! // update last used timestamp +! memcpy(&schedule_vars.currentScheduleEntry->lastUsedAsn, asnTimestamp, sizeof(asn_t)); +! +! // update this backoff parameters for shared slots +! if (schedule_vars.currentScheduleEntry->shared==TRUE) { +! if (succesfullTx==TRUE) { +! // reset backoffExponent +! schedule_vars.backoffExponent = MINBE-1; +! // reset backoff +! schedule_vars.backoff = 0; +! } else { +! // increase the backoffExponent +! if (schedule_vars.backoffExponenttype = CELLTYPE_OFF; +! pScheduleEntry->shared = FALSE; +! pScheduleEntry->channelOffset = 0; +! pScheduleEntry->neighbor.type = ADDR_NONE; +! pScheduleEntry->neighbor.addr_64b[0] = 0x14; +! pScheduleEntry->neighbor.addr_64b[1] = 0x15; +! pScheduleEntry->neighbor.addr_64b[2] = 0x92; +! pScheduleEntry->neighbor.addr_64b[3] = 0x09; +! pScheduleEntry->neighbor.addr_64b[4] = 0x02; +! pScheduleEntry->neighbor.addr_64b[5] = 0x2c; +! pScheduleEntry->neighbor.addr_64b[6] = 0x00; +! pScheduleEntry->numRx = 0; +! pScheduleEntry->numTx = 0; +! pScheduleEntry->numTxACK = 0; +! pScheduleEntry->lastUsedAsn.bytes0and1 = 0; +! pScheduleEntry->lastUsedAsn.bytes2and3 = 0; +! pScheduleEntry->lastUsedAsn.byte4 = 0; +! } +--- 1,621 ---- +! #include "openwsn.h" +! #include "schedule.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "packetfunctions.h" +! +! //=========================== variables ======================================= +! +! schedule_vars_t schedule_vars; +! schedule_dbg_t schedule_dbg; +! +! //=========================== prototypes ====================================== +! +! void schedule_resetEntry(scheduleEntry_t* pScheduleEntry); +! +! //=========================== public ========================================== +! +! //=== admin +! +! void schedule_init(void) { +! uint8_t i; +! slotOffset_t running_slotOffset; +! open_addr_t temp_neighbor; +! +! // reset local variables +! memset(&schedule_vars,0,sizeof(schedule_vars_t)); +! for (i=0;itype!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { +! //check that this entry for that neighbour and timeslot is not already scheduled. +! if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){ +! //it exists so this is an update. +! info->link_type = slotContainer->type; +! info->shared =slotContainer->shared; +! info->channelOffset = slotContainer->channelOffset; +! return; //as this is an update. No need to re-insert as it is in the same position on the list. +! } +! slotContainer++; +! } +! //return cell type off. +! info->link_type = CELLTYPE_OFF; +! info->shared = FALSE; +! info->channelOffset = 0;//set to zero if not set. +! } +! +! /** +! \brief Add a new active slot into the schedule. +! +! If udpate param is set then update it in case it exists. +! +! \param slotOffset +! \param type +! \param shared +! \param channelOffset +! \param neighbor +! \param isUpdate +! */ +! owerror_t schedule_addActiveSlot( +! slotOffset_t slotOffset, +! cellType_t type, +! bool shared, +! channelOffset_t channelOffset, +! open_addr_t* neighbor, +! bool isUpdate +! ) { +! +! owerror_t outcome; +! +! scheduleEntry_t* slotContainer; +! scheduleEntry_t* previousSlotWalker; +! scheduleEntry_t* nextSlotWalker; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! +! // find an empty schedule entry container +! slotContainer = &schedule_vars.scheduleBuf[0]; +! while (slotContainer->type!=CELLTYPE_OFF && +! slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { +! +! //check that this entry for that neighbour and timeslot is not already scheduled. +! if (type!=CELLTYPE_SERIALRX && type!=CELLTYPE_MORESERIALRX && +! (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))|| +! (slotContainer->neighbor.type==ADDR_ANYCAST && isUpdate==TRUE)) +! &&(slotContainer->slotOffset==slotOffset)){ +! //it exists so this is an update. +! slotContainer->type = type; +! slotContainer->shared = shared; +! slotContainer->channelOffset = channelOffset; +! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t));//update the address too! +! schedule_dbg.numUpdatedSlotsCur++; +! ENABLE_INTERRUPTS(); +! return E_SUCCESS; //as this is an update. No need to re-insert as it is in the same position on the list. +! } +! +! slotContainer++; +! } +! +! if (isUpdate==TRUE) { +! //we are trying to update an item that is not in the schedule list. +! ENABLE_INTERRUPTS(); +! return E_FAIL; +! } +! if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { +! // schedule has overflown +! outcome=E_FAIL; +! openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN, +! (errorparameter_t)0, +! (errorparameter_t)0); +! +! +! } +! // fill that schedule entry with parameters passed +! slotContainer->slotOffset = slotOffset; +! slotContainer->type = type; +! slotContainer->shared = shared; +! slotContainer->channelOffset = channelOffset; +! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t)); +! +! if (schedule_vars.currentScheduleEntry==NULL) { +! // this is the first active slot added +! +! // the next slot of this slot is this slot +! slotContainer->next = slotContainer; +! +! // current slot points to this slot +! schedule_vars.currentScheduleEntry = slotContainer; +! } else { +! // this is NOT the first active slot added +! +! // find position in schedule +! previousSlotWalker = schedule_vars.currentScheduleEntry; +! while (1) { +! nextSlotWalker = previousSlotWalker->next; +! if ( +! ( +! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && +! (slotContainer->slotOffset < nextSlotWalker->slotOffset) +! ) +! || +! ( +! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && +! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) +! ) +! || +! ( +! (slotContainer->slotOffset < nextSlotWalker->slotOffset) && +! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) +! ) +! ) { +! break; +! } +! previousSlotWalker = nextSlotWalker; +! } +! // insert between previousSlotWalker and nextSlotWalker +! previousSlotWalker->next = slotContainer; +! slotContainer->next = nextSlotWalker; +! } +! +! // maintain debug stats +! schedule_dbg.numActiveSlotsCur++; +! if (schedule_dbg.numActiveSlotsCur>schedule_dbg.numActiveSlotsMax) { +! schedule_dbg.numActiveSlotsMax = schedule_dbg.numActiveSlotsCur; +! } +! outcome=E_SUCCESS; +! ENABLE_INTERRUPTS(); +! return outcome; +! } +! +! +! +! owerror_t schedule_removeActiveSlot(slotOffset_t slotOffset, open_addr_t* neighbor){ +! +! owerror_t outcome; +! +! scheduleEntry_t* slotContainer; +! scheduleEntry_t* previousSlotWalker; +! +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! +! // find the schedule entry +! slotContainer = &schedule_vars.scheduleBuf[0]; +! while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { +! //check that this entry for that neighbour and timeslot is not already scheduled. +! if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){ +! break; +! } +! slotContainer++; +! } +! +! if (slotContainer->next==slotContainer) { +! // this is the last active slot +! +! // the next slot of this slot is NULL +! slotContainer->next = NULL; +! +! // current slot points to this slot +! schedule_vars.currentScheduleEntry = NULL; +! } else { +! // this is NOT the last active slot +! +! // find the previous in the schedule +! previousSlotWalker = schedule_vars.currentScheduleEntry; +! +! while (1) { +! if ((previousSlotWalker->next=slotContainer)){ +! break; +! } +! previousSlotWalker = previousSlotWalker->next; +! } +! // remove this element from the linked list +! previousSlotWalker->next = slotContainer->next;//my next; +! slotContainer->next = NULL; +! } +! +! // clear that schedule entry +! slotContainer->slotOffset = 0; +! slotContainer->type = CELLTYPE_OFF; +! slotContainer->shared = FALSE; +! slotContainer->channelOffset = 0; +! memset(&slotContainer->neighbor,0,sizeof(open_addr_t)); +! +! // maintain debug stats +! schedule_dbg.numActiveSlotsCur--; +! +! outcome=E_SUCCESS; +! ENABLE_INTERRUPTS(); +! +! return outcome; +! } +! +! +! +! +! //=== from IEEE802154E: reading the schedule and updating statistics +! +! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! while (schedule_vars.currentScheduleEntry->slotOffset!=targetSlotOffset) { +! schedule_advanceSlot(); +! } +! ENABLE_INTERRUPTS(); +! } +! +! void schedule_advanceSlot(void) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! // advance to next active slot +! schedule_vars.currentScheduleEntry = schedule_vars.currentScheduleEntry->next; +! ENABLE_INTERRUPTS(); +! } +! +! slotOffset_t schedule_getNextActiveSlotOffset(void) { +! slotOffset_t res; +! INTERRUPT_DECLARATION(); +! +! // return next active slot's slotOffset +! DISABLE_INTERRUPTS(); +! res = ((scheduleEntry_t*)(schedule_vars.currentScheduleEntry->next))->slotOffset; +! ENABLE_INTERRUPTS(); +! +! return res; +! } +! +! /** +! \brief Get the frame length. +! +! \returns The frame length. +! */ +! frameLength_t schedule_getFrameLength(void) { +! frameLength_t res; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! res= schedule_vars.frameLength; +! ENABLE_INTERRUPTS(); +! +! return res; +! } +! +! /** +! \brief Get the type of the current schedule entry. +! +! \returns The type of the current schedule entry. +! */ +! cellType_t schedule_getType(void) { +! cellType_t res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! res= schedule_vars.currentScheduleEntry->type; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! /** +! \brief Get the neighbor associated wit the current schedule entry. +! +! \returns The neighbor associated wit the current schedule entry. +! */ +! void schedule_getNeighbor(open_addr_t* addrToWrite) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! memcpy(addrToWrite,&(schedule_vars.currentScheduleEntry->neighbor),sizeof(open_addr_t)); +! ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Get the channel offset of the current schedule entry. +! +! \returns The channel offset of the current schedule entry. +! */ +! channelOffset_t schedule_getChannelOffset(void) { +! channelOffset_t res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! res= schedule_vars.currentScheduleEntry->channelOffset; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! /** +! \brief Check whether I can send on this slot. +! +! This function is called at the beginning of every TX slot. +! If the slot is *not* a shared slot, it always return TRUE. +! If the slot is a shared slot, it decrements the backoff counter and returns +! TRUE only if it hits 0. +! +! Note that the backoff counter is global, not per slot. +! +! \returns TRUE if it is OK to send on this slot, FALSE otherwise. +! */ +! bool schedule_getOkToSend(void) { +! bool returnVal; +! +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! if (schedule_vars.currentScheduleEntry->shared==FALSE) { +! // non-shared slot: backoff does not apply +! +! returnVal = TRUE; +! } else { +! // non-shared slot: check backoff before answering +! +! // decrement backoff +! if (schedule_vars.backoff>0) { +! schedule_vars.backoff--; +! } +! +! // only return TRUE if backoff hit 0 +! if (schedule_vars.backoff==0) { +! returnVal = TRUE; +! } else { +! returnVal = FALSE; +! } +! } +! +! ENABLE_INTERRUPTS(); +! return returnVal; +! } +! +! /** +! \brief Reset the backoff and backoffExponent. +! */ +! void schedule_resetBackoff(void) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! // reset backoffExponent +! schedule_vars.backoffExponent = MINBE-1; +! // reset backoff +! schedule_vars.backoff = 0; +! +! ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Indicate the reception of a packet. +! */ +! void schedule_indicateRx(asn_t* asnTimestamp) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! // increment usage statistics +! schedule_vars.currentScheduleEntry->numRx++; +! +! // update last used timestamp +! memcpy(&(schedule_vars.currentScheduleEntry->lastUsedAsn), asnTimestamp, sizeof(asn_t)); +! ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Indicate the transmission of a packet. +! */ +! void schedule_indicateTx(asn_t* asnTimestamp, +! bool succesfullTx) { +! +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! // increment usage statistics +! if (schedule_vars.currentScheduleEntry->numTx==0xFF) { +! schedule_vars.currentScheduleEntry->numTx/=2; +! schedule_vars.currentScheduleEntry->numTxACK/=2; +! } +! schedule_vars.currentScheduleEntry->numTx++; +! if (succesfullTx==TRUE) { +! schedule_vars.currentScheduleEntry->numTxACK++; +! } +! +! // update last used timestamp +! memcpy(&schedule_vars.currentScheduleEntry->lastUsedAsn, asnTimestamp, sizeof(asn_t)); +! +! // update this backoff parameters for shared slots +! if (schedule_vars.currentScheduleEntry->shared==TRUE) { +! if (succesfullTx==TRUE) { +! // reset backoffExponent +! schedule_vars.backoffExponent = MINBE-1; +! // reset backoff +! schedule_vars.backoff = 0; +! } else { +! // increase the backoffExponent +! if (schedule_vars.backoffExponenttype = CELLTYPE_OFF; +! pScheduleEntry->shared = FALSE; +! pScheduleEntry->channelOffset = 0; +! +! pScheduleEntry->neighbor.type = ADDR_NONE; +! memset(&pScheduleEntry->neighbor.addr_64b[0], 0x00, sizeof(pScheduleEntry->neighbor.addr_64b)); +! +! pScheduleEntry->numRx = 0; +! pScheduleEntry->numTx = 0; +! pScheduleEntry->numTxACK = 0; +! pScheduleEntry->lastUsedAsn.bytes0and1 = 0; +! pScheduleEntry->lastUsedAsn.bytes2and3 = 0; +! pScheduleEntry->lastUsedAsn.byte4 = 0; +! } +diff -crB openwsn/02b-MAChigh/schedule.h ../../../sys/net/openwsn/02b-MAChigh/schedule.h +*** openwsn/02b-MAChigh/schedule.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/02b-MAChigh/schedule.h Wed Jan 15 13:48:26 2014 +*************** +*** 1,158 **** +! #ifndef __SCHEDULE_H +! #define __SCHEDULE_H +! +! /** +! \addtogroup MAChigh +! \{ +! \addtogroup Schedule +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! /** +! \brief The length of the superframe, in slots. +! +! The superframe repears over time and can be arbitrarly long. +! */ +! #define SUPERFRAME_LENGTH 9 +! +! #define NUMADVSLOTS 1 +! #define NUMSHAREDTXRX 4 +! #define NUMSERIALRX 3 +! +! /** +! \brief Maximum number of active slots in a superframe. +! +! Note that this is merely used to allocate RAM memory for the schedule. The +! schedule is represented, in RAM, by a table. There is one row per active slot +! in that table; a slot is "active" when it is not of type CELLTYPE_OFF. +! +! Set this number to the exact number of active slots you are planning on having +! in your schedule, so not to waste RAM. +! */ +! #define MAXACTIVESLOTS (NUMADVSLOTS+NUMSHAREDTXRX+NUMSERIALRX) +! +! /** +! \brief Minimum backoff exponent. +! +! Backoff is used only in slots that are marked as shared in the schedule. When +! not shared, the mote assumes that schedule is collision-free, and therefore +! does not use any backoff mechanism when a transmission fails. +! */ +! #define MINBE 2 +! +! /** +! \brief Maximum backoff exponent. +! +! See MINBE for an explanation of backoff. +! */ +! #define MAXBE 4 +! +! +! //=========================== typedef ========================================= +! +! typedef uint8_t channelOffset_t; +! typedef uint16_t slotOffset_t; +! typedef uint16_t frameLength_t; +! +! typedef enum { +! CELLTYPE_OFF = 0, +! CELLTYPE_ADV = 1, +! CELLTYPE_TX = 2, +! CELLTYPE_RX = 3, +! CELLTYPE_TXRX = 4, +! CELLTYPE_SERIALRX = 5, +! CELLTYPE_MORESERIALRX = 6 +! } cellType_t; +! +! //not packed as does not fly on the network +! //PRAGMA(pack(1)); +! typedef struct { +! slotOffset_t slotOffset; +! cellType_t type; +! bool shared; +! uint8_t channelOffset; +! open_addr_t neighbor; +! uint8_t numRx; +! uint8_t numTx; +! uint8_t numTxACK; +! asn_t lastUsedAsn; +! void* next; +! } scheduleEntry_t; +! //PRAGMA(pack()); +! +! //copy of the previous one but without the pointer and packed +! PRAGMA(pack(1)); +! typedef struct { +! slotOffset_t slotOffset; +! cellType_t type; +! bool shared; +! uint8_t channelOffset; +! open_addr_t neighbor; +! uint8_t numRx; +! uint8_t numTx; +! uint8_t numTxACK; +! asn_t lastUsedAsn; +! } scheduleEntryDebug_t; +! PRAGMA(pack()); +! +! //used to debug through ipv6 pkt. +! +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t last_addr_byte;//last byte of the address; poipoi could be [0]; endianness +! uint8_t slotOffset; +! uint8_t channelOffset; +! }netDebugScheduleEntry_t; +! PRAGMA(pack()); +! +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t row; +! scheduleEntryDebug_t scheduleEntry; +! } debugScheduleEntry_t; +! PRAGMA(pack()); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void schedule_init(); +! bool debugPrint_schedule(); +! bool debugPrint_backoff(); +! // from uRES +! void schedule_setFrameLength(frameLength_t newFrameLength); +! void schedule_addActiveSlot( +! slotOffset_t slotOffset, +! cellType_t type, +! bool shared, +! uint8_t channelOffset, +! open_addr_t* neighbor +! ); +! // from IEEE802154E +! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset); +! void schedule_advanceSlot(); +! slotOffset_t schedule_getNextActiveSlotOffset(); +! frameLength_t schedule_getFrameLength(); +! cellType_t schedule_getType(); +! void schedule_getNeighbor(open_addr_t* addrToWrite); +! channelOffset_t schedule_getChannelOffset(); +! bool schedule_getOkToSend(); +! void schedule_resetBackoff(); +! void schedule_indicateRx(asn_t* asnTimestamp); +! void schedule_indicateTx( +! asn_t* asnTimestamp, +! bool succesfullTx +! ); +! void schedule_getNetDebugInfo(netDebugScheduleEntry_t* schlist); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,189 ---- +! #ifndef __SCHEDULE_H +! #define __SCHEDULE_H +! +! /** +! \addtogroup MAChigh +! \{ +! \addtogroup Schedule +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! /** +! \brief The length of the superframe, in slots. +! +! The superframe repears over time and can be arbitrarly long. +! */ +! #define SUPERFRAME_LENGTH 11 //should be 101 +! +! #define NUMADVSLOTS 1 +! #define NUMSHAREDTXRX 5 +! #define NUMSERIALRX 3 +! +! /** +! \brief Maximum number of active slots in a superframe. +! +! Note that this is merely used to allocate RAM memory for the schedule. The +! schedule is represented, in RAM, by a table. There is one row per active slot +! in that table; a slot is "active" when it is not of type CELLTYPE_OFF. +! +! Set this number to the exact number of active slots you are planning on having +! in your schedule, so not to waste RAM. +! */ +! #define MAXACTIVESLOTS (NUMADVSLOTS+NUMSHAREDTXRX+NUMSERIALRX) +! +! /** +! \brief Minimum backoff exponent. +! +! Backoff is used only in slots that are marked as shared in the schedule. When +! not shared, the mote assumes that schedule is collision-free, and therefore +! does not use any backoff mechanism when a transmission fails. +! */ +! #define MINBE 2 +! +! /** +! \brief Maximum backoff exponent. +! +! See MINBE for an explanation of backoff. +! */ +! #define MAXBE 4 +! //6tisch minimal draft +! #define SCHEDULE_MINIMAL_6TISCH_ACTIVE_CELLS 5 +! #define SCHEDULE_MINIMAL_6TISCH_EB_CELLS 1 +! #define SCHEDULE_MINIMAL_6TISCH_SLOTFRAME_SIZE 101 +! #define SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE 1 //id of slotframe +! #define SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_NUMBER 1 //1 slotframe by default. +! +! //=========================== typedef ========================================= +! +! typedef uint8_t channelOffset_t; +! typedef uint16_t slotOffset_t; +! typedef uint16_t frameLength_t; +! +! typedef enum { +! CELLTYPE_OFF = 0, +! CELLTYPE_ADV = 1, +! CELLTYPE_TX = 2, +! CELLTYPE_RX = 3, +! CELLTYPE_TXRX = 4, +! CELLTYPE_SERIALRX = 5, +! CELLTYPE_MORESERIALRX = 6 +! } cellType_t; +! +! +! //PRAGMA(pack(1)); +! typedef struct { +! slotOffset_t slotOffset; +! cellType_t type; +! bool shared; +! uint8_t channelOffset; +! open_addr_t neighbor; +! uint8_t numRx; +! uint8_t numTx; +! uint8_t numTxACK; +! asn_t lastUsedAsn; +! void* next; +! } scheduleEntry_t; +! //PRAGMA(pack()); +! +! //used to debug through ipv6 pkt. +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t last_addr_byte;//last byte of the address; poipoi could be [0]; endianness +! uint8_t slotOffset; +! channelOffset_t channelOffset; +! }netDebugScheduleEntry_t; +! //PRAGMA(pack()); +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t row; +! slotOffset_t slotOffset; +! uint8_t type; +! bool shared; +! uint8_t channelOffset; +! open_addr_t neighbor; +! uint8_t numRx; +! uint8_t numTx; +! uint8_t numTxACK; +! asn_t lastUsedAsn; +! } debugScheduleEntry_t; +! //PRAGMA(pack()); +! +! //PRAGMA(pack(1)); //elements for slot info +! typedef struct { +! uint8_t address[LENGTH_ADDR64b];// +! cellType_t link_type;// rx,tx etc... +! bool shared; +! slotOffset_t slotOffset; +! channelOffset_t channelOffset; +! }slotinfo_element_t; +! //PRAGMA(pack()); +! //=========================== variables ======================================= +! +! typedef struct { +! scheduleEntry_t scheduleBuf[MAXACTIVESLOTS]; +! scheduleEntry_t* currentScheduleEntry; +! uint16_t frameLength; +! uint8_t backoffExponent; +! uint8_t backoff; +! slotOffset_t debugPrintRow; +! } schedule_vars_t; +! +! typedef struct { +! uint8_t numActiveSlotsCur; +! uint8_t numActiveSlotsMax; +! uint8_t numUpdatedSlotsCur; +! } schedule_dbg_t; +! +! //=========================== prototypes ====================================== +! +! // admin +! void schedule_init(void); +! bool debugPrint_schedule(void); +! bool debugPrint_backoff(void); +! // from uRES +! void schedule_setFrameLength(frameLength_t newFrameLength); +! owerror_t schedule_addActiveSlot( +! slotOffset_t slotOffset, +! cellType_t type, +! bool shared, +! uint8_t channelOffset, +! open_addr_t* neighbor, +! bool isUpdate); +! +! void schedule_getSlotInfo(slotOffset_t slotOffset, +! open_addr_t* neighbor, +! slotinfo_element_t* info); +! +! owerror_t schedule_removeActiveSlot(slotOffset_t slotOffset, +! open_addr_t* neighbor); +! +! +! // from IEEE802154E +! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset); +! void schedule_advanceSlot(void); +! slotOffset_t schedule_getNextActiveSlotOffset(void); +! frameLength_t schedule_getFrameLength(void); +! cellType_t schedule_getType(void); +! void schedule_getNeighbor(open_addr_t* addrToWrite); +! channelOffset_t schedule_getChannelOffset(void); +! bool schedule_getOkToSend(void); +! void schedule_resetBackoff(void); +! void schedule_indicateRx(asn_t* asnTimestamp); +! void schedule_indicateTx( +! asn_t* asnTimestamp, +! bool succesfullTx +! ); +! void schedule_getNetDebugInfo(netDebugScheduleEntry_t* schlist); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/03a-IPHC/Makefile ../../../sys/net/openwsn/03a-IPHC/Makefile +*** openwsn/03a-IPHC/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/03a-IPHC/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBMOD) ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/03a-IPHC/iphc.c ../../../sys/net/openwsn/03a-IPHC/iphc.c +*** openwsn/03a-IPHC/iphc.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03a-IPHC/iphc.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,560 **** +! #include "openwsn.h" +! #include "iphc.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "res.h" +! #include "forwarding.h" +! #include "neighbors.h" +! #include "openbridge.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! error_t prependIPv6Header( +! OpenQueueEntry_t* msg, +! uint8_t tf, +! uint32_t value_flowLabel, +! bool nh, +! uint8_t value_nextHeader, +! uint8_t hlim, +! uint8_t value_hopLimit, +! bool cid, +! bool sac, +! uint8_t sam, +! bool m, +! bool dac, +! uint8_t dam, +! open_addr_t* value_dest, +! open_addr_t* value_src, +! uint8_t fw_SendOrfw_Rcv +! ); +! ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg); +! +! //=========================== public ========================================== +! +! void iphc_init() { +! } +! +! //send from upper layer: I need to add 6LoWPAN header +! error_t iphc_sendFromForwarding(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv) { +! open_addr_t temp_dest_prefix; +! open_addr_t temp_dest_mac64b; +! open_addr_t* p_dest; +! open_addr_t* p_src; +! open_addr_t temp_src_prefix; +! open_addr_t temp_src_mac64b; +! uint8_t sam; +! uint8_t dam; +! uint8_t nh; +! +! // take ownership over the packet +! msg->owner = COMPONENT_IPHC; +! +! // by default, the "next header" field is carried inline +! nh=IPHC_NH_INLINE; +! +! // error checking +! if (idmanager_getIsBridge()==TRUE && +! packetfunctions_isAllRoutersMulticast(&(msg->l3_destinationAdd))==FALSE) { +! openserial_printCritical(COMPONENT_IPHC,ERR_BRIDGE_MISMATCH, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! +! //discard the packet.. hop limit reached. +! if (ipv6_header.hop_limit==0) { +! openserial_printError(COMPONENT_IPHC,ERR_HOP_LIMIT_REACHED, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! +! packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); +! //xv poipoi -- get the src prefix as well +! packetfunctions_ip128bToMac64b(&(msg->l3_sourceAdd),&temp_src_prefix,&temp_src_mac64b); +! //XV -poipoi we want to check if the source address prefix is the same as destination prefix +! if (packetfunctions_sameAddress(&temp_dest_prefix,&temp_src_prefix)) { +! //dest and src on same prefix +! if (neighbors_isStableNeighbor(&(msg->l3_destinationAdd))) { +! //if direct neighbors, MAC nextHop and IP destination indicate same node +! //the source can be ME or another who I am relaying from. If its me then SAM is elided, +! //if not SAM is 64b address +! if (fw_SendOrfw_Rcv==PCKTFORWARD){ +! sam = IPHC_SAM_64B; //case forwarding a packet +! p_src = &temp_src_mac64b; +! } else if (fw_SendOrfw_Rcv==PCKTSEND){ +! sam = IPHC_SAM_ELIDED; +! p_src = NULL; +! } else { +! openserial_printCritical(COMPONENT_IPHC,ERR_INVALID_FWDMODE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! dam = IPHC_DAM_ELIDED; +! p_dest = NULL; +! } else { +! //else, not a direct neighbour use 64B address +! sam = IPHC_SAM_64B; +! dam = IPHC_DAM_64B; +! p_dest = &temp_dest_mac64b; +! p_src = &temp_src_mac64b; +! } +! } else { +! //not the same prefix. so the packet travels to another network +! //check if this is a source routing pkt. in case it is then the DAM is elided as it is in the SrcRouting header. +! if(ipv6_header.next_header!=IANA_IPv6ROUTE){ +! sam = IPHC_SAM_128B; +! dam = IPHC_DAM_128B; +! p_dest = &(msg->l3_destinationAdd); +! p_src = &(msg->l3_sourceAdd); +! }else{ +! //source routing +! sam = IPHC_SAM_128B; +! dam = IPHC_DAM_ELIDED; +! p_dest = NULL; +! p_src = &(msg->l3_sourceAdd); +! } +! } +! //check if we are forwarding a packet and it comes with the next header compressed. We want to preserve that state in the following hop. +! +! if ((fw_SendOrfw_Rcv==PCKTFORWARD) && ipv6_header.next_header_compressed) nh=IPHC_NH_COMPRESSED; +! +! // decrement the packet's hop limit +! ipv6_header.hop_limit--; +! +! if (prependIPv6Header(msg, +! IPHC_TF_ELIDED, +! 0, // value_flowlabel is not copied +! nh, +! msg->l4_protocol, +! IPHC_HLIM_INLINE, +! ipv6_header.hop_limit, +! IPHC_CID_NO, +! IPHC_SAC_STATELESS, +! sam, +! IPHC_M_NO, +! IPHC_DAC_STATELESS, +! dam, +! p_dest, +! p_src, +! fw_SendOrfw_Rcv +! )==E_FAIL) { +! return E_FAIL; +! } +! return res_send(msg); +! } +! +! //send from bridge: 6LoWPAN header already added by OpenLBR, send as is +! error_t iphc_sendFromBridge(OpenQueueEntry_t *msg) { +! msg->owner = COMPONENT_IPHC; +! // error checking +! if (idmanager_getIsBridge()==FALSE) { +! openserial_printCritical(COMPONENT_IPHC,ERR_BRIDGE_MISMATCH, +! (errorparameter_t)1, +! (errorparameter_t)0); +! return E_FAIL; +! } +! return res_send(msg); +! } +! +! void iphc_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_IPHC; +! if (msg->creator==COMPONENT_OPENBRIDGE) { +! openbridge_sendDone(msg,error); +! } else { +! forwarding_sendDone(msg,error); +! } +! } +! +! void iphc_receive(OpenQueueEntry_t* msg) { +! ipv6_header_iht ipv6_header; +! msg->owner = COMPONENT_IPHC; +! ipv6_header = retrieveIPv6Header(msg); +! if (idmanager_getIsBridge()==FALSE || +! packetfunctions_isBroadcastMulticast(&(ipv6_header.dest))) { +! packetfunctions_tossHeader(msg,ipv6_header.header_length); +! forwarding_receive(msg,ipv6_header); //up the internal stack +! } else { +! openbridge_receive(msg); //out to the OpenVisualizer +! } +! } +! +! //=========================== private ========================================= +! +! error_t prependIPv6Header( +! OpenQueueEntry_t* msg, +! uint8_t tf, +! uint32_t value_flowLabel, +! bool nh, +! uint8_t value_nextHeader, +! uint8_t hlim, +! uint8_t value_hopLimit, +! bool cid, +! bool sac, +! uint8_t sam, +! bool m, +! bool dac, +! uint8_t dam, +! open_addr_t* value_dest, +! open_addr_t* value_src, +! uint8_t fw_SendOrfw_Rcv +! ) { +! +! uint8_t temp_8b; +! +! //destination address +! switch (dam) { +! case IPHC_DAM_ELIDED: +! break; +! case IPHC_DAM_16B: +! if (value_dest->type!=ADDR_16B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_dest->type, +! (errorparameter_t)0); +! return E_FAIL; +! }; +! packetfunctions_writeAddress(msg,value_dest,BIG_ENDIAN); +! break; +! case IPHC_DAM_64B: +! if (value_dest->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_dest->type, +! (errorparameter_t)1); +! return E_FAIL; +! }; +! packetfunctions_writeAddress(msg,value_dest,BIG_ENDIAN); +! break; +! case IPHC_DAM_128B: +! if (value_dest->type!=ADDR_128B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_dest->type, +! (errorparameter_t)2); +! return E_FAIL; +! }; +! packetfunctions_writeAddress(msg,value_dest,BIG_ENDIAN); +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)0, +! (errorparameter_t)dam); +! return E_FAIL; +! } +! //source address +! switch (sam) { +! case IPHC_SAM_ELIDED: +! break; +! case IPHC_SAM_16B: +! if(fw_SendOrfw_Rcv==PCKTSEND) +! { +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_16B)),BIG_ENDIAN); +! } +! if(fw_SendOrfw_Rcv==PCKTFORWARD) +! { +! if (value_src->type!=ADDR_16B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_src->type, +! (errorparameter_t)0); +! return E_FAIL; +! } +! packetfunctions_writeAddress(msg,value_src,BIG_ENDIAN); +! } +! break; +! case IPHC_SAM_64B: +! if(fw_SendOrfw_Rcv==PCKTSEND) +! { +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),BIG_ENDIAN); +! } +! if(fw_SendOrfw_Rcv==PCKTFORWARD) +! { +! if (value_src->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_src->type, +! (errorparameter_t)1); +! return E_FAIL; +! } +! packetfunctions_writeAddress(msg, value_src,BIG_ENDIAN); +! } +! break; +! case IPHC_SAM_128B: +! if(fw_SendOrfw_Rcv==PCKTSEND) +! { +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),BIG_ENDIAN); +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_PREFIX)),BIG_ENDIAN); +! } +! if(fw_SendOrfw_Rcv==PCKTFORWARD) +! { +! if (value_src->type!=ADDR_128B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_src->type, +! (errorparameter_t)2); +! return E_FAIL; +! } +! packetfunctions_writeAddress(msg,value_src,BIG_ENDIAN); +! } +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)1, +! (errorparameter_t)sam); +! return E_FAIL; +! } +! //hop limit +! switch (hlim) { +! case IPHC_HLIM_INLINE: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = value_hopLimit; +! break; +! case IPHC_HLIM_1: +! case IPHC_HLIM_64: +! case IPHC_HLIM_255: +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)2, +! (errorparameter_t)hlim); +! return E_FAIL; +! } +! //next header +! switch (nh) { +! case IPHC_NH_INLINE: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = value_nextHeader; +! break; +! case IPHC_NH_COMPRESSED: +! //do nothing, the next header will be there +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)3, +! (errorparameter_t)nh); +! return E_FAIL; +! } +! //flowlabel +! switch (tf) { +! case IPHC_TF_3B: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = ((uint32_t)(value_flowLabel & 0x000000ff) >> 0); +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = ((uint32_t)(value_flowLabel & 0x0000ff00) >> 8); +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = ((uint32_t)(value_flowLabel & 0x00ff0000) >> 16); +! break; +! case IPHC_TF_ELIDED: +! break; +! case IPHC_TF_4B: +! //unsupported +! case IPHC_TF_1B: +! //unsupported +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)4, +! (errorparameter_t)tf); +! return E_FAIL; +! } +! //header +! temp_8b = 0; +! temp_8b |= cid << IPHC_CID; +! temp_8b |= sac << IPHC_SAC; +! temp_8b |= sam << IPHC_SAM; +! temp_8b |= m << IPHC_M; +! temp_8b |= dac << IPHC_DAC; +! temp_8b |= dam << IPHC_DAM; +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = temp_8b; +! temp_8b = 0; +! temp_8b |= IPHC_DISPATCH_IPHC << IPHC_DISPATCH; +! temp_8b |= tf << IPHC_TF; +! temp_8b |= nh << IPHC_NH; +! temp_8b |= hlim << IPHC_HLIM; +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = temp_8b; +! return E_SUCCESS; +! } +! +! ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg) { +! uint8_t temp_8b; +! open_addr_t temp_addr_16b; +! open_addr_t temp_addr_64b; +! ipv6_header_iht ipv6_header; +! uint8_t dispatch; +! uint8_t tf; +! bool nh; +! uint8_t hlim; +! //bool cid; +! //bool sac; +! uint8_t sam; +! // bool m; +! //bool dac; +! uint8_t dam; +! +! ipv6_header.header_length = 0; +! //header +! temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! dispatch = (temp_8b >> IPHC_DISPATCH) & 0x07;//3b +! tf = (temp_8b >> IPHC_TF) & 0x03;//2b +! nh = (temp_8b >> IPHC_NH) & 0x01;//1b +! hlim = (temp_8b >> IPHC_HLIM) & 0x03;//2b +! ipv6_header.header_length += sizeof(uint8_t); +! temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! //cid = (temp_8b >> IPHC_CID) & 0x01;//1b unused +! //sac = (temp_8b >> IPHC_SAC) & 0x01;//1b unused +! sam = (temp_8b >> IPHC_SAM) & 0x03;//2b +! //m = (temp_8b >> IPHC_M) & 0x01;//1b unused +! //dac = (temp_8b >> IPHC_DAC) & 0x01;//1b unused +! dam = (temp_8b >> IPHC_DAM) & 0x03;//2b +! ipv6_header.header_length += sizeof(uint8_t); +! //dispatch +! switch (dispatch) { +! case IPHC_DISPATCH_IPHC: +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)5, +! (errorparameter_t)dispatch); +! break; +! } +! //flowlabel +! switch (tf) { +! case IPHC_TF_3B: +! ipv6_header.flow_label = ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header.header_length))<<0; +! ipv6_header.header_length += sizeof(uint8_t); +! ipv6_header.flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header.header_length))<<8; +! ipv6_header.header_length += sizeof(uint8_t); +! ipv6_header.flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header.header_length))<<16; +! ipv6_header.header_length += sizeof(uint8_t); +! break; +! case IPHC_TF_ELIDED: +! ipv6_header.flow_label = 0; +! break; +! case IPHC_TF_4B: +! //unsupported +! case IPHC_TF_1B: +! //unsupported +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)6, +! (errorparameter_t)tf); +! break; +! } +! //next header +! switch (nh) { +! case IPHC_NH_INLINE: +! // Full 8 bits for Next Header are carried in-line +! ipv6_header.next_header_compressed = FALSE; +! ipv6_header.next_header = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! ipv6_header.header_length += sizeof(uint8_t); +! break; +! case IPHC_NH_COMPRESSED: +! // the Next header field is compressed and the next header is encoded +! // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282 +! // we don't parse anything here, but will look at the (compressed) +! // next header after having parsed all address fields. +! ipv6_header.next_header_compressed = TRUE; +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)7, +! (errorparameter_t)nh); +! break; +! } +! //hop limit +! switch (hlim) { +! case IPHC_HLIM_INLINE: +! ipv6_header.hop_limit = *((uint8_t*)(msg->payload+ipv6_header.header_length)); +! ipv6_header.header_length += sizeof(uint8_t); +! break; +! case IPHC_HLIM_1: +! ipv6_header.hop_limit = 1; +! break; +! case IPHC_HLIM_64: +! ipv6_header.hop_limit = 64; +! break; +! case IPHC_HLIM_255: +! ipv6_header.hop_limit = 255; +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)8, +! (errorparameter_t)hlim); +! break; +! } +! //source address +! switch (sam) { +! case IPHC_SAM_ELIDED: +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&(msg->l2_nextORpreviousHop),&ipv6_header.src); +! break; +! case IPHC_SAM_16B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,BIG_ENDIAN); +! ipv6_header.header_length += 2*sizeof(uint8_t); +! packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); +! break; +! case IPHC_SAM_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,BIG_ENDIAN); +! ipv6_header.header_length += 8*sizeof(uint8_t); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); +! break; +! case IPHC_SAM_128B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.src,BIG_ENDIAN); +! ipv6_header.header_length += 16*sizeof(uint8_t); +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)9, +! (errorparameter_t)sam); +! break; +! } +! //destination address +! switch (dam) { +! case IPHC_DAM_ELIDED: +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),idmanager_getMyID(ADDR_64B),&(ipv6_header.dest)); +! break; +! case IPHC_DAM_16B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,BIG_ENDIAN); +! ipv6_header.header_length += 2*sizeof(uint8_t); +! packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); +! break; +! case IPHC_DAM_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,BIG_ENDIAN); +! ipv6_header.header_length += 8*sizeof(uint8_t); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); +! break; +! case IPHC_DAM_128B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.dest,BIG_ENDIAN); +! ipv6_header.header_length += 16*sizeof(uint8_t); +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)10, +! (errorparameter_t)dam); +! break; +! } +! /* +! During the parsing of the nh field, we found that the next header was +! compressed. We now identify which next (compressed) header this is, and +! populate the ipv6_header.next_header field accordingly. It's the role of the +! appropriate transport module to decompress the header. +! */ +! if (ipv6_header.next_header_compressed==TRUE) { +! temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { +! ipv6_header.next_header = IANA_UDP; +! } else { +! // the next header could be an IPv6 extension header, or misformed +! ipv6_header.next_header = IANA_UNDEFINED; +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)11, +! (errorparameter_t)ipv6_header.next_header); +! } +! } +! // this is a temporary workaround for allowing multicast RAs to go through +! //poipoi xv -- TODO -- check if this still needed. NO RAs anymore after RPL implementation. +! /*if (m==1 && dam==IPHC_DAM_ELIDED) { +! ipv6_header.header_length += sizeof(uint8_t); +! }*/ +! return ipv6_header; +! } +--- 1,695 ---- +! #include "openwsn.h" +! #include "iphc.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "openserial.h" +! #include "res.h" +! #include "forwarding.h" +! #include "neighbors.h" +! #include "openbridge.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! owerror_t prependIPv6Header( +! OpenQueueEntry_t* msg, +! uint8_t tf, +! uint32_t value_flowLabel, +! bool nh, +! uint8_t value_nextHeader, +! uint8_t hlim, +! uint8_t value_hopLimit, +! bool cid, +! bool sac, +! uint8_t sam, +! bool m, +! bool dac, +! uint8_t dam, +! open_addr_t* value_dest, +! open_addr_t* value_src, +! uint8_t fw_SendOrfw_Rcv +! ); +! ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg); +! //hop by hop header +! void prependIPv6HopByHopHeader(OpenQueueEntry_t* msg,uint8_t nextheader, bool nh, rpl_hopoption_ht *hopbyhop_option); +! void retrieveIPv6HopByHopHeader(OpenQueueEntry_t* msg, ipv6_hopbyhop_ht *hopbyhop_header, rpl_hopoption_ht *rpl_option); +! //=========================== public ========================================== +! +! void iphc_init(void) { +! } +! +! //send from upper layer: I need to add 6LoWPAN header +! owerror_t iphc_sendFromForwarding(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht *hopbyhop_option, uint8_t fw_SendOrfw_Rcv) { +! open_addr_t temp_dest_prefix; +! open_addr_t temp_dest_mac64b; +! open_addr_t* p_dest; +! open_addr_t* p_src; +! open_addr_t temp_src_prefix; +! open_addr_t temp_src_mac64b; +! uint8_t sam; +! uint8_t dam; +! uint8_t nh; +! uint8_t next_header; +! //option header +! +! // take ownership over the packet +! msg->owner = COMPONENT_IPHC; +! +! // by default, the "next header" field is carried inline +! nh=IPHC_NH_INLINE; +! +! // error checking +! if (idmanager_getIsBridge()==TRUE && +! packetfunctions_isAllRoutersMulticast(&(msg->l3_destinationAdd))==FALSE) { +! openserial_printCritical(COMPONENT_IPHC,ERR_BRIDGE_MISMATCH, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! +! //discard the packet.. hop limit reached. +! if (ipv6_header.hop_limit==0) { +! openserial_printError(COMPONENT_IPHC,ERR_HOP_LIMIT_REACHED, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! +! packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); +! //xv poipoi -- get the src prefix as well +! packetfunctions_ip128bToMac64b(&(msg->l3_sourceAdd),&temp_src_prefix,&temp_src_mac64b); +! //XV -poipoi we want to check if the source address prefix is the same as destination prefix +! if (packetfunctions_sameAddress(&temp_dest_prefix,&temp_src_prefix)) { +! //dest and src on same prefix +! if (neighbors_isStableNeighbor(&(msg->l3_destinationAdd))) { +! //if direct neighbors, MAC nextHop and IP destination indicate same node +! //the source can be ME or another who I am relaying from. If its me then SAM is elided, +! //if not SAM is 64b address +! if (fw_SendOrfw_Rcv==PCKTFORWARD){ +! sam = IPHC_SAM_64B; //case forwarding a packet +! p_src = &temp_src_mac64b; +! //poipoi xv forcing elided addresses on src routing, this needs to be fixed so any type of address should be supported supported. +! } else if (fw_SendOrfw_Rcv==PCKTSEND){ +! sam = IPHC_SAM_ELIDED; +! p_src = NULL; +! } else { +! openserial_printCritical(COMPONENT_IPHC,ERR_INVALID_FWDMODE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! dam = IPHC_DAM_ELIDED; +! p_dest = NULL; +! } else { +! //else, not a direct neighbour use 64B address +! sam = IPHC_SAM_64B; +! dam = IPHC_DAM_64B; +! p_dest = &temp_dest_mac64b; +! p_src = &temp_src_mac64b; +! } +! } else { +! //not the same prefix. so the packet travels to another network +! //check if this is a source routing pkt. in case it is then the DAM is elided as it is in the SrcRouting header. +! if(ipv6_header.next_header!=IANA_IPv6ROUTE){ +! sam = IPHC_SAM_128B; +! dam = IPHC_DAM_128B; +! p_dest = &(msg->l3_destinationAdd); +! p_src = &(msg->l3_sourceAdd); +! }else{ +! //source routing +! sam = IPHC_SAM_128B; +! dam = IPHC_DAM_ELIDED; //poipoi xv not true, should not be elided. +! p_dest = NULL; +! p_src = &(msg->l3_sourceAdd); +! } +! } +! //check if we are forwarding a packet and it comes with the next header compressed. We want to preserve that state in the following hop. +! +! if ((fw_SendOrfw_Rcv==PCKTFORWARD) && ipv6_header.next_header_compressed) nh=IPHC_NH_COMPRESSED; +! +! // decrement the packet's hop limit +! ipv6_header.hop_limit--; +! +! //prepend Option hop by hop header except when src routing and dst is not 0xffff -- this is a little trick as src routing is using an option header set to 0x00 +! next_header=msg->l4_protocol; +! if (hopbyhop_option->optionType==RPL_HOPBYHOP_HEADER_OPTION_TYPE +! && packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd))==FALSE ){ +! prependIPv6HopByHopHeader(msg, msg->l4_protocol, nh, hopbyhop_option); +! //change nh to point to the newly added header +! next_header=IANA_IPv6HOPOPT;// use 0x00 as NH to indicate option header -- see rfc 2460 +! } +! //then regular header +! if (prependIPv6Header(msg, +! IPHC_TF_ELIDED, +! 0, // value_flowlabel is not copied +! nh, +! next_header, +! IPHC_HLIM_INLINE, +! ipv6_header.hop_limit, +! IPHC_CID_NO, +! IPHC_SAC_STATELESS, +! sam, +! IPHC_M_NO, +! IPHC_DAC_STATELESS, +! dam, +! p_dest, +! p_src, +! fw_SendOrfw_Rcv +! )==E_FAIL) { +! return E_FAIL; +! } +! +! return res_send(msg); +! } +! +! +! +! +! //send from bridge: 6LoWPAN header already added by OpenLBR, send as is +! owerror_t iphc_sendFromBridge(OpenQueueEntry_t *msg) { +! msg->owner = COMPONENT_IPHC; +! // error checking +! if (idmanager_getIsBridge()==FALSE) { +! openserial_printCritical(COMPONENT_IPHC,ERR_BRIDGE_MISMATCH, +! (errorparameter_t)1, +! (errorparameter_t)0); +! return E_FAIL; +! } +! return res_send(msg); +! } +! +! void iphc_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_IPHC; +! if (msg->creator==COMPONENT_OPENBRIDGE) { +! openbridge_sendDone(msg,error); +! } else { +! forwarding_sendDone(msg,error); +! } +! } +! +! void iphc_receive(OpenQueueEntry_t* msg) { +! ipv6_header_iht ipv6_header; +! ipv6_hopbyhop_ht ipv6_hop_header; +! rpl_hopoption_ht hop_by_hop_option; +! +! msg->owner = COMPONENT_IPHC; +! +! //then regular header +! ipv6_header = retrieveIPv6Header(msg); +! +! +! if (idmanager_getIsBridge()==FALSE || +! packetfunctions_isBroadcastMulticast(&(ipv6_header.dest))) { +! packetfunctions_tossHeader(msg,ipv6_header.header_length); +! +! if (ipv6_header.next_header==IANA_IPv6HOPOPT){ +! //retrieve hop by hop header +! retrieveIPv6HopByHopHeader(msg,&ipv6_hop_header,&hop_by_hop_option); +! //toss the header + option +tlv on it if any +! packetfunctions_tossHeader(msg,IPv6HOP_HDR_LEN+ipv6_hop_header.HdrExtLen); +! } +! forwarding_receive(msg,ipv6_header,ipv6_hop_header,hop_by_hop_option); //up the internal stack +! } else { +! openbridge_receive(msg); //out to the OpenVisualizer +! } +! } +! +! //=========================== private ========================================= +! +! +! void prependIPv6HopByHopHeader(OpenQueueEntry_t *msg,uint8_t nextheader, bool nh, rpl_hopoption_ht *hopbyhop_option){ +! +! //copy them in reverse order, first option later header +! packetfunctions_reserveHeaderSize(msg,sizeof(rpl_hopoption_ht)); +! memcpy(msg->payload,hopbyhop_option,sizeof(rpl_hopoption_ht)); +! +! //hdr len as defined by rfc6282 sect 4.2 +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = sizeof(rpl_hopoption_ht); +! +! //next header +! switch (nh) { +! case IPHC_NH_INLINE: +! //add the next header inline +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = nextheader; +! +! //append NHC field on the extension header should be 1110 0000 -- see rfc 6282 sect 4.2 +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = NHC_IPv6EXT_ID; +! break; +! case IPHC_NH_COMPRESSED: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = NHC_IPv6EXT_ID | 0x01; //mark last bit as 1 -- see rfc 6282 sect 4.2 +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)3, +! (errorparameter_t)nh); +! } +! +! } +! +! owerror_t prependIPv6Header( +! OpenQueueEntry_t* msg, +! uint8_t tf, +! uint32_t value_flowLabel, +! bool nh, +! uint8_t value_nextHeader, +! uint8_t hlim, +! uint8_t value_hopLimit, +! bool cid, +! bool sac, +! uint8_t sam, +! bool m, +! bool dac, +! uint8_t dam, +! open_addr_t* value_dest, +! open_addr_t* value_src, +! uint8_t fw_SendOrfw_Rcv +! ) { +! +! uint8_t temp_8b; +! +! //destination address +! switch (dam) { +! case IPHC_DAM_ELIDED: +! break; +! case IPHC_DAM_16B: +! if (value_dest->type!=ADDR_16B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_dest->type, +! (errorparameter_t)0); +! return E_FAIL; +! }; +! packetfunctions_writeAddress(msg,value_dest,OW_BIG_ENDIAN); +! break; +! case IPHC_DAM_64B: +! if (value_dest->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_dest->type, +! (errorparameter_t)1); +! return E_FAIL; +! }; +! packetfunctions_writeAddress(msg,value_dest,OW_BIG_ENDIAN); +! break; +! case IPHC_DAM_128B: +! if (value_dest->type!=ADDR_128B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_dest->type, +! (errorparameter_t)2); +! return E_FAIL; +! }; +! packetfunctions_writeAddress(msg,value_dest,OW_BIG_ENDIAN); +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)0, +! (errorparameter_t)dam); +! return E_FAIL; +! } +! //source address +! switch (sam) { +! case IPHC_SAM_ELIDED: +! break; +! case IPHC_SAM_16B: +! if(fw_SendOrfw_Rcv==PCKTSEND) +! { +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_16B)),OW_BIG_ENDIAN); +! } +! if(fw_SendOrfw_Rcv==PCKTFORWARD) +! { +! if (value_src->type!=ADDR_16B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_src->type, +! (errorparameter_t)0); +! return E_FAIL; +! } +! packetfunctions_writeAddress(msg,value_src,OW_BIG_ENDIAN); +! } +! break; +! case IPHC_SAM_64B: +! if(fw_SendOrfw_Rcv==PCKTSEND) +! { +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),OW_BIG_ENDIAN); +! } +! if(fw_SendOrfw_Rcv==PCKTFORWARD) +! { +! if (value_src->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_src->type, +! (errorparameter_t)1); +! return E_FAIL; +! } +! packetfunctions_writeAddress(msg, value_src,OW_BIG_ENDIAN); +! } +! break; +! case IPHC_SAM_128B: +! if(fw_SendOrfw_Rcv==PCKTSEND) +! { +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),OW_BIG_ENDIAN); +! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_PREFIX)),OW_BIG_ENDIAN); +! } +! if(fw_SendOrfw_Rcv==PCKTFORWARD) +! { +! if (value_src->type!=ADDR_128B) { +! openserial_printCritical(COMPONENT_IPHC,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)value_src->type, +! (errorparameter_t)2); +! return E_FAIL; +! } +! packetfunctions_writeAddress(msg,value_src,OW_BIG_ENDIAN); +! } +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)1, +! (errorparameter_t)sam); +! return E_FAIL; +! } +! //hop limit +! switch (hlim) { +! case IPHC_HLIM_INLINE: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = value_hopLimit; +! break; +! case IPHC_HLIM_1: +! case IPHC_HLIM_64: +! case IPHC_HLIM_255: +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)2, +! (errorparameter_t)hlim); +! return E_FAIL; +! } +! //next header +! switch (nh) { +! case IPHC_NH_INLINE: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = value_nextHeader; +! break; +! case IPHC_NH_COMPRESSED: +! //do nothing, the next header will be there +! break; +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)3, +! (errorparameter_t)nh); +! return E_FAIL; +! } +! //flowlabel +! switch (tf) { +! case IPHC_TF_3B: +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = ((uint32_t)(value_flowLabel & 0x000000ff) >> 0); +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = ((uint32_t)(value_flowLabel & 0x0000ff00) >> 8); +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = ((uint32_t)(value_flowLabel & 0x00ff0000) >> 16); +! break; +! case IPHC_TF_ELIDED: +! break; +! case IPHC_TF_4B: +! //unsupported +! case IPHC_TF_1B: +! //unsupported +! default: +! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)4, +! (errorparameter_t)tf); +! return E_FAIL; +! } +! //header +! temp_8b = 0; +! temp_8b |= cid << IPHC_CID; +! temp_8b |= sac << IPHC_SAC; +! temp_8b |= sam << IPHC_SAM; +! temp_8b |= m << IPHC_M; +! temp_8b |= dac << IPHC_DAC; +! temp_8b |= dam << IPHC_DAM; +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = temp_8b; +! temp_8b = 0; +! temp_8b |= IPHC_DISPATCH_IPHC << IPHC_DISPATCH; +! temp_8b |= tf << IPHC_TF; +! temp_8b |= nh << IPHC_NH; +! temp_8b |= hlim << IPHC_HLIM; +! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); +! *((uint8_t*)(msg->payload)) = temp_8b; +! return E_SUCCESS; +! } +! +! +! +! void retrieveIPv6HopByHopHeader(OpenQueueEntry_t *msg,ipv6_hopbyhop_ht *hopbyhop_header, rpl_hopoption_ht *rpl_option){ +! uint8_t temp_8b; +! +! hopbyhop_header->headerlen=0; +! +! hopbyhop_header->lowpan_nhc = *((uint8_t*)(msg->payload)+ hopbyhop_header->headerlen); +! hopbyhop_header->headerlen += sizeof(uint8_t); +! +! //next header +! switch ( hopbyhop_header->lowpan_nhc & NHC_HOP_NH_MASK) { +! case IPHC_NH_INLINE: +! // Full 8 bits for Next Header are carried in-line +! hopbyhop_header->next_header_compressed = FALSE; +! hopbyhop_header->nextHeader = *((uint8_t*)(msg->payload)+hopbyhop_header->headerlen); +! hopbyhop_header->headerlen+= sizeof(uint8_t); +! break; +! case IPHC_NH_COMPRESSED: +! // the Next header field is compressed and the next header is encoded +! // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282 +! // we don't parse anything here, but will look at the (compressed) +! // next header after having parsed all address fields. +! hopbyhop_header->next_header_compressed = TRUE; +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)7, +! (errorparameter_t)hopbyhop_header->lowpan_nhc); +! break; +! } +! +! //len of options +! hopbyhop_header->HdrExtLen =*((uint8_t*)(msg->payload)+hopbyhop_header->headerlen); +! hopbyhop_header->headerlen+= sizeof(uint8_t); +! //copy the options +! memcpy(rpl_option,((uint8_t*)(msg->payload)+hopbyhop_header->headerlen),sizeof(rpl_hopoption_ht)); +! hopbyhop_header->headerlen+= sizeof(rpl_hopoption_ht); +! +! //now in case nh compressed: +! /* +! During the parsing of the nh field, we found that the next header was +! compressed. We now identify which next (compressed) header this is, and +! populate the hopbyhop_header.nextHeader field accordingly. It's the role of the +! appropriate transport module to decompress the header. +! */ +! if (hopbyhop_header->next_header_compressed==TRUE) { +! temp_8b = *((uint8_t*)(msg->payload)+ hopbyhop_header->headerlen); +! if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { +! hopbyhop_header->nextHeader = IANA_UDP; +! }else { +! // the next header could be an IPv6 extension header, or misformed +! hopbyhop_header->nextHeader = IANA_UNDEFINED; +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)14, +! (errorparameter_t)hopbyhop_header->nextHeader); +! } +! } +! } +! +! +! ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg) { +! uint8_t temp_8b; +! open_addr_t temp_addr_16b; +! open_addr_t temp_addr_64b; +! ipv6_header_iht ipv6_header; +! uint8_t dispatch; +! uint8_t tf; +! bool nh; +! uint8_t hlim; +! //bool cid; +! //bool sac; +! uint8_t sam; +! // bool m; +! //bool dac; +! uint8_t dam; +! +! ipv6_header.header_length = 0; +! //header +! temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! dispatch = (temp_8b >> IPHC_DISPATCH) & 0x07;//3b +! tf = (temp_8b >> IPHC_TF) & 0x03;//2b +! nh = (temp_8b >> IPHC_NH) & 0x01;//1b +! hlim = (temp_8b >> IPHC_HLIM) & 0x03;//2b +! ipv6_header.header_length += sizeof(uint8_t); +! temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! //cid = (temp_8b >> IPHC_CID) & 0x01;//1b unused +! //sac = (temp_8b >> IPHC_SAC) & 0x01;//1b unused +! sam = (temp_8b >> IPHC_SAM) & 0x03;//2b +! //m = (temp_8b >> IPHC_M) & 0x01;//1b unused +! //dac = (temp_8b >> IPHC_DAC) & 0x01;//1b unused +! dam = (temp_8b >> IPHC_DAM) & 0x03;//2b +! ipv6_header.header_length += sizeof(uint8_t); +! //dispatch +! switch (dispatch) { +! case IPHC_DISPATCH_IPHC: +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)5, +! (errorparameter_t)dispatch); +! break; +! } +! //flowlabel +! switch (tf) { +! case IPHC_TF_3B: +! ipv6_header.flow_label = ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header.header_length))<<0; +! ipv6_header.header_length += sizeof(uint8_t); +! ipv6_header.flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header.header_length))<<8; +! ipv6_header.header_length += sizeof(uint8_t); +! ipv6_header.flow_label |= ((uint32_t) *((uint8_t*)(msg->payload)+ipv6_header.header_length))<<16; +! ipv6_header.header_length += sizeof(uint8_t); +! break; +! case IPHC_TF_ELIDED: +! ipv6_header.flow_label = 0; +! break; +! case IPHC_TF_4B: +! //unsupported +! case IPHC_TF_1B: +! //unsupported +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)6, +! (errorparameter_t)tf); +! break; +! } +! //next header +! switch (nh) { +! case IPHC_NH_INLINE: +! // Full 8 bits for Next Header are carried in-line +! ipv6_header.next_header_compressed = FALSE; +! ipv6_header.next_header = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! ipv6_header.header_length += sizeof(uint8_t); +! +! break; +! case IPHC_NH_COMPRESSED: +! // the Next header field is compressed and the next header is encoded +! // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282 +! // we don't parse anything here, but will look at the (compressed) +! // next header after having parsed all address fields. +! ipv6_header.next_header_compressed = TRUE; +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)7, +! (errorparameter_t)nh); +! break; +! } +! //hop limit +! switch (hlim) { +! case IPHC_HLIM_INLINE: +! ipv6_header.hop_limit = *((uint8_t*)(msg->payload+ipv6_header.header_length)); +! ipv6_header.header_length += sizeof(uint8_t); +! break; +! case IPHC_HLIM_1: +! ipv6_header.hop_limit = 1; +! break; +! case IPHC_HLIM_64: +! ipv6_header.hop_limit = 64; +! break; +! case IPHC_HLIM_255: +! ipv6_header.hop_limit = 255; +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)8, +! (errorparameter_t)hlim); +! break; +! } +! //source address +! switch (sam) { +! case IPHC_SAM_ELIDED: +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&(msg->l2_nextORpreviousHop),&ipv6_header.src); +! break; +! case IPHC_SAM_16B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,OW_BIG_ENDIAN); +! ipv6_header.header_length += 2*sizeof(uint8_t); +! packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); +! break; +! case IPHC_SAM_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,OW_BIG_ENDIAN); +! ipv6_header.header_length += 8*sizeof(uint8_t); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); +! break; +! case IPHC_SAM_128B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.src,OW_BIG_ENDIAN); +! ipv6_header.header_length += 16*sizeof(uint8_t); +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)9, +! (errorparameter_t)sam); +! break; +! } +! //destination address +! switch (dam) { +! case IPHC_DAM_ELIDED: +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),idmanager_getMyID(ADDR_64B),&(ipv6_header.dest)); +! break; +! case IPHC_DAM_16B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,OW_BIG_ENDIAN); +! ipv6_header.header_length += 2*sizeof(uint8_t); +! packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); +! break; +! case IPHC_DAM_64B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,OW_BIG_ENDIAN); +! ipv6_header.header_length += 8*sizeof(uint8_t); +! packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); +! break; +! case IPHC_DAM_128B: +! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.dest,OW_BIG_ENDIAN); +! ipv6_header.header_length += 16*sizeof(uint8_t); +! break; +! default: +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)10, +! (errorparameter_t)dam); +! break; +! } +! /* +! During the parsing of the nh field, we found that the next header was +! compressed. We now identify which next (compressed) header this is, and +! populate the ipv6_header.next_header field accordingly. It's the role of the +! appropriate transport module to decompress the header. +! */ +! if (ipv6_header.next_header_compressed==TRUE) { +! temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); +! if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { +! ipv6_header.next_header = IANA_UDP; +! }else if ( (temp_8b & NHC_IPv6EXT_MASK) == NHC_IPv6EXT_ID){ +! if( (temp_8b & NHC_IPv6HOP_MASK) == NHC_IPv6HOP_VAL){ +! //it is hop by hop header +! ipv6_header.next_header = IANA_IPv6HOPOPT; +! }else{ +! // the next header could be another IPv6 extension header +! ipv6_header.next_header = IANA_UNDEFINED; +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)11, +! (errorparameter_t)ipv6_header.next_header); +! } +! }else { +! // the next header could be an IPv6 extension header, or misformed +! ipv6_header.next_header = IANA_UNDEFINED; +! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)12, +! (errorparameter_t)ipv6_header.next_header); +! } +! } +! +! return ipv6_header; +! } +diff -crB openwsn/03a-IPHC/iphc.h ../../../sys/net/openwsn/03a-IPHC/iphc.h +*** openwsn/03a-IPHC/iphc.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03a-IPHC/iphc.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,134 **** +! #ifndef __IPHC_H +! #define __IPHC_H +! +! /** +! \addtogroup LoWPAN +! \{ +! \addtogroup IPHC +! \{ +! */ +! +! //=========================== define ========================================== +! +! #define IPHC_DEFAULT_HOP_LIMIT 65 +! +! enum IPHC_enums { +! IPHC_DISPATCH = 5, +! IPHC_TF = 3, +! IPHC_NH = 2, +! IPHC_HLIM = 0, +! IPHC_CID = 7, +! IPHC_SAC = 6, +! IPHC_SAM = 4, +! IPHC_M = 3, +! IPHC_DAC = 2, +! IPHC_DAM = 0, +! }; +! +! enum IPHC_DISPATCH_enums { +! IPHC_DISPATCH_IPHC = 3, +! }; +! +! enum IPHC_TF_enums { +! IPHC_TF_4B = 0, +! IPHC_TF_3B = 1, +! IPHC_TF_1B = 2, +! IPHC_TF_ELIDED = 3, +! }; +! +! enum IPHC_NH_enums { +! IPHC_NH_INLINE = 0, +! IPHC_NH_COMPRESSED = 1, +! }; +! +! enum NHC_enums { +! // IPv6 Extension Header Encoding starts with b1110 xxxx +! NHC_IPv6EXT_MASK = 0xf0, // b1111 0000 +! NHC_IPv6EXT_ID = 0xe0, // b1110 0000 +! // UDP Header Encoding starts with b1111 0xxx +! NHC_UDP_MASK = 0xf8, // b1111 1000 +! NHC_UDP_ID = 0xf0, // b1111 0000 +! }; +! +! enum NHC_UDP_enums { +! NHC_UDP_C_MASK = 0x40, +! NHC_UDP_PORTS_MASK = 0x03, +! }; +! +! enum NHC_UDP_PORTS_enums { +! NHC_UDP_PORTS_INLINE = 0, +! NHC_UDP_PORTS_16S_8D = 1, +! NHC_UDP_PORTS_8S_8D = 2, +! NHC_UDP_PORTS_4S_4D = 3, +! }; +! +! enum IPHC_HLIM_enums { +! IPHC_HLIM_INLINE = 0, +! IPHC_HLIM_1 = 1, +! IPHC_HLIM_64 = 2, +! IPHC_HLIM_255 = 3, +! }; +! +! enum IPHC_CID_enums { +! IPHC_CID_NO = 0, +! IPHC_CID_YES = 1, +! }; +! +! enum IPHC_SAC_enums { +! IPHC_SAC_STATELESS = 0, +! IPHC_SAC_STATEFUL = 1, +! }; +! +! enum IPHC_SAM_enums { +! IPHC_SAM_128B = 0, +! IPHC_SAM_64B = 1, +! IPHC_SAM_16B = 2, +! IPHC_SAM_ELIDED = 3, +! }; +! +! enum IPHC_M_enums { +! IPHC_M_NO = 0, +! IPHC_M_YES = 1, +! }; +! +! enum IPHC_DAC_enums { +! IPHC_DAC_STATELESS = 0, +! IPHC_DAC_STATEFUL = 1, +! }; +! +! enum IPHC_DAM_enums { +! IPHC_DAM_128B = 0, +! IPHC_DAM_64B = 1, +! IPHC_DAM_16B = 2, +! IPHC_DAM_ELIDED = 3, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t traffic_class; +! uint32_t flow_label; +! bool next_header_compressed; +! uint8_t next_header; +! uint8_t hop_limit; +! open_addr_t src; +! open_addr_t dest; +! uint8_t header_length; ///< needed to toss the header +! } ipv6_header_iht; //iht for "internal header type" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void iphc_init(); +! error_t iphc_sendFromForwarding(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv); +! error_t iphc_sendFromBridge(OpenQueueEntry_t *msg); +! void iphc_sendDone(OpenQueueEntry_t* msg, error_t error); +! void iphc_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,184 ---- +! #ifndef __IPHC_H +! #define __IPHC_H +! +! /** +! \addtogroup LoWPAN +! \{ +! \addtogroup IPHC +! \{ +! */ +! +! #include "openwsn.h" +! //=========================== define ========================================== +! +! #define IPHC_DEFAULT_HOP_LIMIT 65 +! #define IPv6HOP_HDR_LEN 3 +! +! enum IPHC_enums { +! IPHC_DISPATCH = 5, +! IPHC_TF = 3, +! IPHC_NH = 2, +! IPHC_HLIM = 0, +! IPHC_CID = 7, +! IPHC_SAC = 6, +! IPHC_SAM = 4, +! IPHC_M = 3, +! IPHC_DAC = 2, +! IPHC_DAM = 0, +! }; +! +! enum IPHC_DISPATCH_enums { +! IPHC_DISPATCH_IPHC = 3, +! }; +! +! enum IPHC_TF_enums { +! IPHC_TF_4B = 0, +! IPHC_TF_3B = 1, +! IPHC_TF_1B = 2, +! IPHC_TF_ELIDED = 3, +! }; +! +! enum IPHC_NH_enums { +! IPHC_NH_INLINE = 0, +! IPHC_NH_COMPRESSED = 1, +! }; +! +! enum NHC_enums { +! // IPv6 Extension Header Encoding starts with b1110 xxxx +! NHC_IPv6EXT_MASK = 0xf0, // b1111 0000 +! NHC_IPv6EXT_ID = 0xe0, // b1110 0000 +! // UDP Header Encoding starts with b1111 0xxx +! NHC_UDP_MASK = 0xf8, // b1111 1000 +! NHC_UDP_ID = 0xf0, // b1111 0000 +! }; +! +! enum NHC_IPv6HOP_enums { +! NHC_IPv6HOP_MASK = 0x0e, +! NHC_IPv6HOP_VAL = 0x0e, +! NHC_HOP_NH_MASK = 0x01, +! }; +! +! +! enum NHC_UDP_enums { +! NHC_UDP_C_MASK = 0x40, +! NHC_UDP_PORTS_MASK = 0x03, +! }; +! +! enum NHC_UDP_PORTS_enums { +! NHC_UDP_PORTS_INLINE = 0, +! NHC_UDP_PORTS_16S_8D = 1, +! NHC_UDP_PORTS_8S_8D = 2, +! NHC_UDP_PORTS_4S_4D = 3, +! }; +! +! enum IPHC_HLIM_enums { +! IPHC_HLIM_INLINE = 0, +! IPHC_HLIM_1 = 1, +! IPHC_HLIM_64 = 2, +! IPHC_HLIM_255 = 3, +! }; +! +! enum IPHC_CID_enums { +! IPHC_CID_NO = 0, +! IPHC_CID_YES = 1, +! }; +! +! enum IPHC_SAC_enums { +! IPHC_SAC_STATELESS = 0, +! IPHC_SAC_STATEFUL = 1, +! }; +! +! enum IPHC_SAM_enums { +! IPHC_SAM_128B = 0, +! IPHC_SAM_64B = 1, +! IPHC_SAM_16B = 2, +! IPHC_SAM_ELIDED = 3, +! }; +! +! enum IPHC_M_enums { +! IPHC_M_NO = 0, +! IPHC_M_YES = 1, +! }; +! +! enum IPHC_DAC_enums { +! IPHC_DAC_STATELESS = 0, +! IPHC_DAC_STATEFUL = 1, +! }; +! +! enum IPHC_DAM_enums { +! IPHC_DAM_128B = 0, +! IPHC_DAM_64B = 1, +! IPHC_DAM_16B = 2, +! IPHC_DAM_ELIDED = 3, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t traffic_class; +! uint32_t flow_label; +! bool next_header_compressed; +! uint8_t next_header; +! uint8_t hop_limit; +! open_addr_t src; +! open_addr_t dest; +! uint8_t header_length; ///< needed to toss the header +! } ipv6_header_iht; //iht for "internal header type" +! +! +! /* +! The Hop-by-Hop Options header is used to carry optional information +! that must be examined by every node along a packet's delivery path. +! The Hop-by-Hop Options header is identified by a Next Header value of +! 0 in the IPv6 header, and has the following format: +! */ +! typedef struct { +! /*see rfc 6282 section 4.2 The first 7 bits serve as an identifier for the IPv6 Extension Header immediately +! following the LOWPAN_NHC octet. The remaining bit indicates whether +! or not the following header utilizes LOWPAN_NHC encoding. */ +! uint8_t headerlen;// counter for internal use +! bool next_header_compressed; +! uint8_t lowpan_nhc; +! uint8_t nextHeader;//IPv6 hop by hop header field see rfc 2460 section 4.3 +! uint8_t HdrExtLen; //IPv6 hop by hop header field see rfc 6282 section 4.2 +! /* +! The Length field contained in a compressed IPv6 Extension Header +! indicates the number of octets that pertain to the (compressed) +! extension header following the Length field. Note that this changes +! the Length field definition in [RFC2460] from indicating the header +! size in 8-octet units, not including the first 8 octets. Changing +! the Length field to be in units of octets removes wasteful internal +! fragmentation.*/ +! +! } ipv6_hopbyhop_ht; +! +! //PRAGMA(pack(1)); +! typedef struct { +! //RPL hop by hop option header as described by RFC 6553 p.3 +! uint8_t optionType; ///0x63. +! uint8_t optionLen; /////8-bit field indicating the length of the option, in octets, excluding the Option Type and Opt Data Len fields. +! uint8_t flags; //ORF00000. +! uint8_t rplInstanceID; //instanceid +! uint16_t senderRank; //sender rank +! } rpl_hopoption_ht; +! //PRAGMA(pack()); +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void iphc_init(void); +! owerror_t iphc_sendFromForwarding(OpenQueueEntry_t *msg, +! ipv6_header_iht ipv6_header, +! rpl_hopoption_ht *hopbyhop_option, +! uint8_t fw_SendOrfw_Rcv); +! +! owerror_t iphc_sendFromBridge(OpenQueueEntry_t *msg); +! void iphc_sendDone(OpenQueueEntry_t *msg, owerror_t error); +! void iphc_receive(OpenQueueEntry_t *msg); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/03a-IPHC/openbridge.c ../../../sys/net/openwsn/03a-IPHC/openbridge.c +*** openwsn/03a-IPHC/openbridge.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03a-IPHC/openbridge.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,93 **** +! #include "openwsn.h" +! #include "openbridge.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "iphc.h" +! #include "idmanager.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void openbridge_init() { +! } +! +! void openbridge_triggerData() { +! uint8_t input_buffer[136];//worst case: 8B of next hop + 128B of data +! OpenQueueEntry_t* pkt; +! uint8_t numDataBytes; +! +! numDataBytes = openserial_getNumDataBytes(); +! openserial_getInputBuffer(&(input_buffer[0]),numDataBytes); +! +! //poipoi xv +! //this is a temporal workaround as we are never supposed to get chunks of data +! //longer than input buffer size.. I assume that HDLC will solve that. +! +! if (numDataBytes>136){ +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)0, +! (errorparameter_t)numDataBytes); +! //return; +! //poipoi xv test that.. +! numDataBytes=sizeof(input_buffer); +! } +! +! if (idmanager_getIsBridge()==TRUE && numDataBytes>0) { +! pkt = openqueue_getFreePacketBuffer(COMPONENT_OPENBRIDGE); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! //admin +! pkt->creator = COMPONENT_OPENBRIDGE; +! pkt->owner = COMPONENT_OPENBRIDGE; +! //l2 +! pkt->l2_nextORpreviousHop.type = ADDR_64B; +! memcpy(&(pkt->l2_nextORpreviousHop.addr_64b[0]),&(input_buffer[0]),8); +! //payload +! packetfunctions_reserveHeaderSize(pkt,numDataBytes-8); +! memcpy(pkt->payload,&(input_buffer[8]),numDataBytes-8); +! //send +! if ((iphc_sendFromBridge(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! } +! +! void openbridge_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_OPENBRIDGE; +! if (msg->creator!=COMPONENT_OPENBRIDGE) { +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! /** +! \brief Receive a frame at the openbridge, which sends it out over serial. +! */ +! void openbridge_receive(OpenQueueEntry_t* msg) { +! +! // prepend previous hop +! packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b); +! memcpy(msg->payload,msg->l2_nextORpreviousHop.addr_64b,LENGTH_ADDR64b); +! +! // prepend next hop (me) +! packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b); +! memcpy(msg->payload,idmanager_getMyID(ADDR_64B)->addr_64b,LENGTH_ADDR64b); +! +! // send packet over serial (will be memcopied into serial buffer) +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! +! // free packet +! openqueue_freePacketBuffer(msg); +! } +! +! //=========================== private ========================================= +--- 1,100 ---- +! #include "openwsn.h" +! #include "openbridge.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "iphc.h" +! #include "idmanager.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! //=========================== public ========================================== +! +! void openbridge_init(void) { +! } +! +! void openbridge_triggerData(void) { +! uint8_t input_buffer[136];//worst case: 8B of next hop + 128B of data +! OpenQueueEntry_t* pkt; +! uint8_t numDataBytes; +! +! numDataBytes = openserial_getNumDataBytes(); +! +! //poipoi xv +! //this is a temporal workaround as we are never supposed to get chunks of data +! //longer than input buffer size.. I assume that HDLC will solve that. +! // MAC header is 13B + 8 next hop so we cannot accept packets that are longer than 118B +! if (numDataBytes>(136 - 21) || numDataBytes<8){ +! //to prevent too short or too long serial frames to kill the stack +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)numDataBytes, +! (errorparameter_t)0); +! return; +! } +! +! //copying the buffer once we know it is not too big +! openserial_getInputBuffer(&(input_buffer[0]),numDataBytes); +! +! if (idmanager_getIsBridge()==TRUE && numDataBytes>0) { +! pkt = openqueue_getFreePacketBuffer(COMPONENT_OPENBRIDGE); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! //admin +! pkt->creator = COMPONENT_OPENBRIDGE; +! pkt->owner = COMPONENT_OPENBRIDGE; +! //l2 +! pkt->l2_nextORpreviousHop.type = ADDR_64B; +! memcpy(&(pkt->l2_nextORpreviousHop.addr_64b[0]),&(input_buffer[0]),8); +! //payload +! packetfunctions_reserveHeaderSize(pkt,numDataBytes-8); +! memcpy(pkt->payload,&(input_buffer[8]),numDataBytes-8); +! +! //this is to catch the too short packet. remove it after fw-103 is solved. +! if (numDataBytes<16){ +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_INVALIDSERIALFRAME, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! //send +! if ((iphc_sendFromBridge(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! } +! +! void openbridge_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_OPENBRIDGE; +! if (msg->creator!=COMPONENT_OPENBRIDGE) { +! openserial_printError(COMPONENT_OPENBRIDGE,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! /** +! \brief Receive a frame at the openbridge, which sends it out over serial. +! */ +! void openbridge_receive(OpenQueueEntry_t* msg) { +! +! // prepend previous hop +! packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b); +! memcpy(msg->payload,msg->l2_nextORpreviousHop.addr_64b,LENGTH_ADDR64b); +! +! // prepend next hop (me) +! packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b); +! memcpy(msg->payload,idmanager_getMyID(ADDR_64B)->addr_64b,LENGTH_ADDR64b); +! +! // send packet over serial (will be memcopied into serial buffer) +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! +! // free packet +! openqueue_freePacketBuffer(msg); +! } +! +! //=========================== private ========================================= +diff -crB openwsn/03a-IPHC/openbridge.h ../../../sys/net/openwsn/03a-IPHC/openbridge.h +*** openwsn/03a-IPHC/openbridge.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03a-IPHC/openbridge.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,29 **** +! #ifndef __OPENBRIDGE_H +! #define __OPENBRIDGE_H +! +! /** +! \addtogroup LoWPAN +! \{ +! \addtogroup OpenBridge +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openbridge_init(); +! void openbridge_triggerData(); +! void openbridge_sendDone(OpenQueueEntry_t* msg, error_t error); +! void openbridge_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,29 ---- +! #ifndef __OPENBRIDGE_H +! #define __OPENBRIDGE_H +! +! /** +! \addtogroup LoWPAN +! \{ +! \addtogroup OpenBridge +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openbridge_init(void); +! void openbridge_triggerData(void); +! void openbridge_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void openbridge_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/03b-IPv6/Makefile ../../../sys/net/openwsn/03b-IPv6/Makefile +*** openwsn/03b-IPv6/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/03b-IPv6/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBMOD) ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/03b-IPv6/forwarding.c ../../../sys/net/openwsn/03b-IPv6/forwarding.c +*** openwsn/03b-IPv6/forwarding.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/forwarding.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,406 **** +! #include "openwsn.h" +! #include "forwarding.h" +! #include "iphc.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "idmanager.h" +! #include "packetfunctions.h" +! #include "neighbors.h" +! #include "icmpv6.h" +! #include "openudp.h" +! #include "opentcp.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! error_t fowarding_send_internal_RoutingTable(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv); +! void forwarding_getNextHop_RoutingTable(open_addr_t* destination, open_addr_t* addressToWrite); +! error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header); +! +! //=========================== public ========================================== +! +! /** +! \brief Initialize this module. +! */ +! void forwarding_init() { +! } +! +! /** +! \brief Send a packet originating at this mote. +! +! This function is called by an upper layer, and only concerns packets originated +! at this mote. +! +! \param[in,out] msg Packet to send. +! */ +! error_t forwarding_send(OpenQueueEntry_t* msg) { +! ipv6_header_iht ipv6_header; +! open_addr_t* myprefix; +! open_addr_t* myadd64; +! +! // take ownership +! msg->owner = COMPONENT_FORWARDING; +! +! // retrieve my prefix and EUI64 +! myprefix = idmanager_getMyID(ADDR_PREFIX); +! myadd64 = idmanager_getMyID(ADDR_64B); +! +! // set source address (to me) +! msg->l3_sourceAdd.type=ADDR_128B; +! memcpy(&(msg->l3_sourceAdd.addr_128b[0]),myprefix->prefix,8); +! memcpy(&(msg->l3_sourceAdd.addr_128b[8]),myadd64->addr_64b,8); +! +! // initialize IPv6 header +! memset(&ipv6_header,0,sizeof(ipv6_header_iht)); +! +! //set hop limit to the default in-network value as this packet is being sent from upper layer. +! //this is done here as send_internal is used by forwarding of packets as well which +! //carry a hlim. This value is required to be set to a value as the following function can decrement it +! ipv6_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; +! +! return fowarding_send_internal_RoutingTable(msg,ipv6_header,PCKTSEND); +! } +! +! /** +! \brief Indicates a packet has been sent. +! +! \param[in,out] msg The packet just sent. +! \param[in] error The outcome of sending it. +! */ +! void forwarding_sendDone(OpenQueueEntry_t* msg, error_t error) { +! +! // take ownership +! msg->owner = COMPONENT_FORWARDING; +! +! if (msg->creator==COMPONENT_RADIO || msg->creator==COMPONENT_FORWARDING) { +! // that is a packet I relayed +! +! // free packet +! openqueue_freePacketBuffer(msg); +! } else { +! // that is a packet I created +! +! // indicate sendDone to upper layer +! switch(msg->l4_protocol) { +! case IANA_TCP: +! opentcp_sendDone(msg,error); +! break; +! case IANA_UDP: +! openudp_sendDone(msg,error); +! break; +! case IANA_ICMPv6: +! icmpv6_sendDone(msg,error); +! break; +! default: +! openserial_printCritical(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)msg->l4_protocol, +! (errorparameter_t)0); +! // free packet +! openqueue_freePacketBuffer(msg); +! } +! } +! } +! +! /** +! \brief Indicates a packet was received. +! +! \param[in,out] msg The packet just sent. +! \param[in] ipv6_header The information contained in the 6LoWPAN header. +! */ +! void forwarding_receive(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header) { +! +! // take ownership +! msg->owner = COMPONENT_FORWARDING; +! +! // populate packets metadata with l4 information +! msg->l4_protocol = ipv6_header.next_header; +! msg->l4_protocol_compressed = ipv6_header.next_header_compressed; +! +! // populate packets metadata with l3 information +! memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t)); +! memcpy(&(msg->l3_sourceAdd), &ipv6_header.src, sizeof(open_addr_t)); +! +! if ( +! ( +! idmanager_isMyAddress(&ipv6_header.dest) +! || +! packetfunctions_isBroadcastMulticast(&ipv6_header.dest) +! ) +! && +! ipv6_header.next_header!=IANA_IPv6ROUTE +! ) { +! // this packet is for me, but no routing header. +! +! // indicate received packet to upper layer +! switch(msg->l4_protocol) { +! case IANA_TCP: +! opentcp_receive(msg); +! break; +! case IANA_UDP: +! openudp_receive(msg); +! break; +! case IANA_ICMPv6: +! icmpv6_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)msg->l4_protocol, +! (errorparameter_t)1); +! openqueue_freePacketBuffer(msg); +! } +! } else { +! // this packet is not for me: relay +! +! // change the creator of the packet +! msg->creator = COMPONENT_FORWARDING; +! +! if (ipv6_header.next_header!=IANA_IPv6ROUTE) { +! // no source routing header present +! +! // resend as if from upper layer +! if (fowarding_send_internal_RoutingTable(msg, ipv6_header,PCKTFORWARD)==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } else { +! // source routing header present +! +! if (fowarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } +! } +! } +! +! //=========================== private ========================================= +! +! /** +! \brief Send a packet using the routing table to find the next hop. +! +! \param[in,out] msg The packet to send. +! \param[in] ipv6_header The packet's IPv6 header. +! \param[in] fw_SendOrfw_Rcv The packet is originating from this mote +! (PCKTSEND), or forwarded (PCKTFORWARD). +! */ +! error_t fowarding_send_internal_RoutingTable(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv) { +! +! // retrieve the next hop from the routing table +! forwarding_getNextHop_RoutingTable(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop)); +! if (msg->l2_nextORpreviousHop.type==ADDR_NONE) { +! openserial_printError(COMPONENT_FORWARDING,ERR_NO_NEXTHOP, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! +! // send to next lower layer +! return iphc_sendFromForwarding(msg, ipv6_header, fw_SendOrfw_Rcv); +! } +! +! /** +! \brief Send a packet using the source rout to find the next hop. +! +! \note This is always called for packets being forwarded. +! +! How to process the routing header is detailed in +! http://tools.ietf.org/html/rfc6554#page-9. +! +! \param[in,out] msg The packet to send. +! \param[in] ipv6_header The packet's IPv6 header. +! */ +! error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) { +! uint8_t local_CmprE; +! uint8_t local_CmprI; +! uint8_t numAddr; +! uint8_t hlen; +! uint8_t addressposition; +! uint8_t* runningPointer; +! uint8_t octetsAddressSize; +! open_addr_t* prefix; +! rpl_routing_ht* rpl_routing_hdr; +! +! // get my prefix +! prefix = idmanager_getMyID(ADDR_PREFIX); +! +! // cast packet to RPL routing header +! rpl_routing_hdr = (rpl_routing_ht*)(msg->payload); +! +! // point behind the RPL routing header +! runningPointer = (msg->payload)+sizeof(rpl_routing_ht); +! +! // retrieve CmprE and CmprI +! +! /*CmprE 4-bit unsigned integer. Number of prefix octets +! from the last segment (i.e., segment n) that are +! elided. For example, an SRH carrying a full IPv6 +! address in Addressesn sets CmprE to 0.*/ +! +! local_CmprE = rpl_routing_hdr->CmprICmprE & 0x0f; +! local_CmprI = rpl_routing_hdr->CmprICmprE & 0xf0; +! local_CmprI = local_CmprI>>4; +! +! numAddr = (((rpl_routing_hdr->HdrExtLen*8)-rpl_routing_hdr->PadRes-(16-local_CmprE))/(16-local_CmprI))+1; +! +! if (rpl_routing_hdr->SegmentsLeft==0){ +! // no more segments left, this is the last hop +! +! // push packet up the stack +! msg->l4_protocol = rpl_routing_hdr->nextHeader; +! hlen = rpl_routing_hdr->HdrExtLen; //in 8-octet units +! +! // toss RPL routing header +! packetfunctions_tossHeader(msg,sizeof(rpl_routing_ht)); +! +! // toss source route addresses +! octetsAddressSize = LENGTH_ADDR128b - local_CmprE; //total length - number of octets that are elided +! packetfunctions_tossHeader(msg,octetsAddressSize*hlen); +! +! // indicate reception to upper layer +! switch(msg->l4_protocol) { +! case IANA_TCP: +! opentcp_receive(msg); +! break; +! case IANA_UDP: +! openudp_receive(msg); +! break; +! case IANA_ICMPv6: +! icmpv6_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)msg->l4_protocol, +! (errorparameter_t)1); +! openqueue_freePacketBuffer(msg); +! return E_FAIL; +! } +! +! // stop executing here (successful) +! return E_SUCCESS; +! +! } else { +! // this is not the last hop +! +! if (rpl_routing_hdr->SegmentsLeft>numAddr) { +! // error code: there are more segments left than space in source route +! +! // TODO: send ICMPv6 packet (code 0) to originator +! +! openserial_printError(COMPONENT_FORWARDING,ERR_NO_NEXTHOP, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return E_FAIL; +! +! } else { +! +! // decrement number of segments left +! rpl_routing_hdr->SegmentsLeft--; +! +! // find next hop address in source route +! addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft); +! +! // how many octets have the address? +! if (rpl_routing_hdr->SegmentsLeft > 1){ +! octetsAddressSize = LENGTH_ADDR128b - local_CmprI; //max addr length - number of prefix octets that are elided in the internal route elements +! }else{ +! octetsAddressSize = LENGTH_ADDR128b - local_CmprE; //max addr length - number of prefix octets that are elided in the internal route elements +! } +! switch(octetsAddressSize) { +! case LENGTH_ADDR16b: +! // write previous hop +! msg->l2_nextORpreviousHop.type = ADDR_16B; +! memcpy( +! &(msg->l2_nextORpreviousHop.addr_16b), +! runningPointer+((addressposition-1)*octetsAddressSize), +! octetsAddressSize +! ); +! // write next hop +! msg->l3_destinationAdd.type = ADDR_16B; +! memcpy( +! &(msg->l3_destinationAdd.addr_16b), +! runningPointer+((addressposition-1)*octetsAddressSize), +! octetsAddressSize +! ); +! break; +! case LENGTH_ADDR64b: +! // write previous hop +! msg->l2_nextORpreviousHop.type = ADDR_64B; +! memcpy( +! &(msg->l2_nextORpreviousHop.addr_64b), +! runningPointer+((addressposition-1)*octetsAddressSize), +! octetsAddressSize +! ); +! +! //this is 128b address as send from forwarding function +! //takes care of reducing it if needed. +! +! //write next hop +! msg->l3_destinationAdd.type = ADDR_128B; +! memcpy( +! &(msg->l3_destinationAdd.addr_128b[0]), +! prefix->prefix, +! LENGTH_ADDR64b +! ); +! +! memcpy( +! &(msg->l3_destinationAdd.addr_128b[8]), +! runningPointer+((addressposition-1)*octetsAddressSize), +! octetsAddressSize +! ); +! +! break; +! case LENGTH_ADDR128b: +! // write previous hop +! msg->l2_nextORpreviousHop.type = ADDR_128B; +! memcpy( +! &(msg->l2_nextORpreviousHop.addr_128b), +! runningPointer+((addressposition-1)*octetsAddressSize), +! octetsAddressSize +! ); +! // write next hop +! msg->l3_destinationAdd.type = ADDR_128B; +! memcpy( +! &(msg->l3_destinationAdd.addr_128b), +! runningPointer+((addressposition-1)*octetsAddressSize), +! octetsAddressSize +! ); +! break; +! default: +! //poipoi xv +! //any other value is not supported by now. +! openserial_printError(COMPONENT_FORWARDING,ERR_INVALID_PARAM, +! (errorparameter_t)1, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return E_FAIL; +! } +! } +! } +! +! // send to next lower layer +! return iphc_sendFromForwarding(msg, ipv6_header, PCKTFORWARD); +! } +! +! /** +! \brief Retrieve the next hop's address from routing table. +! +! \param[in] destination128b Final IPv6 destination address. +! \param[out]addressToWrite64b Location to write the EUI64 of next hop to. +! */ +! void forwarding_getNextHop_RoutingTable(open_addr_t* destination128b, open_addr_t* addressToWrite64b) { +! uint8_t i; +! open_addr_t temp_prefix64btoWrite; +! if (packetfunctions_isBroadcastMulticast(destination128b)) { +! // IP destination is broadcast, send to 0xffffffffffffffff +! addressToWrite64b->type = ADDR_64B; +! for (i=0;i<8;i++) { +! addressToWrite64b->addr_64b[i] = 0xff; +! } +! } else if (neighbors_isStableNeighbor(destination128b)) { +! // IP destination is 1-hop neighbor, send directly +! packetfunctions_ip128bToMac64b(destination128b,&temp_prefix64btoWrite,addressToWrite64b); +! } else { +! // destination is remote, send to preferred parent +! neighbors_getPreferredParentEui64(addressToWrite64b); +! } +! } +\ No newline at end of file +--- 1,478 ---- +! #include "openwsn.h" +! #include "forwarding.h" +! #include "iphc.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "idmanager.h" +! #include "packetfunctions.h" +! #include "neighbors.h" +! #include "icmpv6.h" +! #include "icmpv6rpl.h" +! #include "openudp.h" +! #include "opentcp.h" +! //#include "debugpins.h" +! #include "scheduler.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! owerror_t forwarding_send_internal_RoutingTable(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht hopbyhop_header, uint8_t fw_SendOrfw_Rcv); +! void forwarding_getNextHop_RoutingTable(open_addr_t* destination, open_addr_t* addressToWrite); +! owerror_t forwarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header); +! void forwarding_createHopByHopOption(rpl_hopoption_ht *hopbyhop_opt, uint8_t flags); +! +! //=========================== public ========================================== +! +! /** +! \brief Initialize this module. +! */ +! void forwarding_init(void) { +! } +! +! +! /** +! \brief Send a packet originating at this mote. +! +! This function is called by an upper layer, and only concerns packets originated +! at this mote. +! +! \param[in,out] msg Packet to send. +! */ +! owerror_t forwarding_send(OpenQueueEntry_t* msg) { +! ipv6_header_iht ipv6_header; +! rpl_hopoption_ht hopbyhop_opt; +! +! open_addr_t* myprefix; +! open_addr_t* myadd64; +! +! // take ownership +! msg->owner = COMPONENT_FORWARDING; +! +! // retrieve my prefix and EUI64 +! myprefix = idmanager_getMyID(ADDR_PREFIX); +! myadd64 = idmanager_getMyID(ADDR_64B); +! +! // set source address (to me) +! msg->l3_sourceAdd.type=ADDR_128B; +! memcpy(&(msg->l3_sourceAdd.addr_128b[0]),myprefix->prefix,8); +! memcpy(&(msg->l3_sourceAdd.addr_128b[8]),myadd64->addr_64b,8); +! +! // initialize IPv6 header +! memset(&ipv6_header,0,sizeof(ipv6_header_iht)); +! +! //set hop limit to the default in-network value as this packet is being sent from upper layer. +! //this is done here as send_internal is used by forwarding of packets as well which +! //carry a hlim. This value is required to be set to a value as the following function can decrement it +! ipv6_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; +! //create hop by hop option +! forwarding_createHopByHopOption(&hopbyhop_opt, 0x00); //flags are 0x00 -- TODO check and define macro +! +! return forwarding_send_internal_RoutingTable(msg,ipv6_header,hopbyhop_opt,PCKTSEND); +! } +! +! /** +! \brief Indicates a packet has been sent. +! +! \param[in,out] msg The packet just sent. +! \param[in] error The outcome of sending it. +! */ +! void forwarding_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! +! // take ownership +! msg->owner = COMPONENT_FORWARDING; +! +! if (msg->creator==COMPONENT_RADIO || msg->creator==COMPONENT_FORWARDING) { +! // that is a packet I relayed +! +! // free packet +! openqueue_freePacketBuffer(msg); +! } else { +! // that is a packet I created +! +! // indicate sendDone to upper layer +! switch(msg->l4_protocol) { +! case IANA_TCP: +! opentcp_sendDone(msg,error); +! break; +! case IANA_UDP: +! openudp_sendDone(msg,error); +! break; +! case IANA_ICMPv6: +! icmpv6_sendDone(msg,error); +! break; +! default: +! openserial_printCritical(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)msg->l4_protocol, +! (errorparameter_t)0); +! // free packet +! openqueue_freePacketBuffer(msg); +! } +! } +! } +! +! /** +! \brief Indicates a packet was received. +! +! \param[in,out] msg The packet just sent. +! \param[in] ipv6_header The information contained in the 6LoWPAN header. +! */ +! void forwarding_receive(OpenQueueEntry_t* msg, +! ipv6_header_iht ipv6_header, +! ipv6_hopbyhop_ht ipv6_hop_header, +! rpl_hopoption_ht hop_by_hop_option) { +! +! uint8_t temp_flags; +! +! // take ownership +! msg->owner = COMPONENT_FORWARDING; +! +! +! //contains a +! if (ipv6_header.next_header==IANA_IPv6HOPOPT){ +! // populate packets metadata with l4 information +! msg->l4_protocol = ipv6_hop_header.nextHeader; +! msg->l4_protocol_compressed = ipv6_hop_header.next_header_compressed; // rfc 6282 +! +! //process HOP BY HOP header +! +! +! }else{ +! msg->l4_protocol = ipv6_header.next_header; +! msg->l4_protocol_compressed = ipv6_header.next_header_compressed; // rfc 6282 +! } +! +! // populate packets metadata with l3 information +! memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t)); +! memcpy(&(msg->l3_sourceAdd), &ipv6_header.src, sizeof(open_addr_t)); +! +! +! if ( +! ( +! idmanager_isMyAddress(&ipv6_header.dest) +! || +! packetfunctions_isBroadcastMulticast(&ipv6_header.dest) +! ) +! && +! //ipv6 header - next header will be IANA_IPv6HOPOPT or IANA_IPv6ROUTE +! ipv6_header.next_header!=IANA_IPv6ROUTE +! ) { +! // this packet is for me, but no src routing header. +! +! // indicate received packet to upper layer +! switch(msg->l4_protocol) { +! case IANA_TCP: +! opentcp_receive(msg); +! break; +! case IANA_UDP: +! openudp_receive(msg); +! break; +! case IANA_ICMPv6: +! icmpv6_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)msg->l4_protocol, +! (errorparameter_t)1); +! openqueue_freePacketBuffer(msg); +! } +! } else { +! // this packet is not for me: relay +! +! // change the creator of the packet +! msg->creator = COMPONENT_FORWARDING; +! +! if (ipv6_header.next_header!=IANA_IPv6ROUTE) { +! // no source routing header present +! +! //process HOP bY HOP header +! temp_flags = hop_by_hop_option.flags; +! if ((temp_flags & O_FLAG)!=0){ +! //error wrong direction +! //what todo? print the error +! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_DIRECTION, +! (errorparameter_t)1, +! (errorparameter_t)1); +! } +! if (hop_by_hop_option.senderRank < neighbors_getMyDAGrank()){ +! //wrong rank relation.. loop detected +! temp_flags |= R_FLAG; //set r flag. +! openserial_printError(COMPONENT_FORWARDING,ERR_LOOP_DETECTED, +! (errorparameter_t) hop_by_hop_option.senderRank, +! (errorparameter_t) neighbors_getMyDAGrank()); +! } +! +! //O flag should always be 0 as this is upstream route. +! +! forwarding_createHopByHopOption(&hop_by_hop_option, temp_flags); +! +! +! // resend as if from upper layer +! if (forwarding_send_internal_RoutingTable(msg, ipv6_header,hop_by_hop_option,PCKTFORWARD)==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } else { +! // source routing header present +! if (forwarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) { +! //already freed by send_internal if it fails +! //todo change error type to another that says src_route failure. +! openserial_printError(COMPONENT_FORWARDING,ERR_INVALID_FWDMODE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! } +! } +! } +! +! +! +! /** +! \brief Send a packet using the routing table to find the next hop. +! +! \param[in,out] msg The packet to send. +! \param[in] ipv6_header The packet's IPv6 header. +! \param[in] fw_SendOrfw_Rcv The packet is originating from this mote +! (PCKTSEND), or forwarded (PCKTFORWARD). +! */ +! owerror_t forwarding_send_internal_RoutingTable(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht hopbyhop_opt, uint8_t fw_SendOrfw_Rcv) { +! +! // retrieve the next hop from the routing table +! forwarding_getNextHop_RoutingTable(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop)); +! if (msg->l2_nextORpreviousHop.type==ADDR_NONE) { +! openserial_printError(COMPONENT_FORWARDING,ERR_NO_NEXTHOP, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! +! // send to next lower layer +! return iphc_sendFromForwarding(msg, ipv6_header, &hopbyhop_opt,fw_SendOrfw_Rcv); +! } +! +! /** +! \brief Send a packet using the source rout to find the next hop. +! +! \note This is always called for packets being forwarded. +! +! How to process the routing header is detailed in +! http://tools.ietf.org/html/rfc6554#page-9. +! +! \param[in,out] msg The packet to send. +! \param[in] ipv6_header The packet's IPv6 header. +! */ +! owerror_t forwarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) { +! uint8_t local_CmprE; +! uint8_t local_CmprI; +! uint8_t numAddr; +! uint8_t hlen; +! uint8_t addressposition; +! uint8_t* runningPointer; +! uint8_t octetsAddressSize; +! open_addr_t* prefix; +! rpl_routing_ht* rpl_routing_hdr; +! +! rpl_hopoption_ht hopbyhop_opt; +! +! memset(&hopbyhop_opt,0,sizeof(rpl_hopoption_ht));//reset everything +! +! // get my prefix +! prefix = idmanager_getMyID(ADDR_PREFIX); +! +! // cast packet to RPL routing header +! rpl_routing_hdr = (rpl_routing_ht*)(msg->payload); +! +! // point behind the RPL routing header +! runningPointer = (msg->payload)+sizeof(rpl_routing_ht); +! +! // retrieve CmprE and CmprI +! +! /*CmprE 4-bit unsigned integer. Number of prefix octets +! from the last segment (i.e., segment n) that are +! elided. For example, an SRH carrying a full IPv6 +! address in Addressesn sets CmprE to 0.*/ +! +! local_CmprE = rpl_routing_hdr->CmprICmprE & 0x0f; +! local_CmprI = rpl_routing_hdr->CmprICmprE & 0xf0; +! local_CmprI = local_CmprI>>4; +! +! numAddr = (((rpl_routing_hdr->HdrExtLen*8)-rpl_routing_hdr->PadRes-(16-local_CmprE))/(16-local_CmprI))+1; +! +! if (rpl_routing_hdr->SegmentsLeft==0){ +! // no more segments left, this is the last hop +! +! // push packet up the stack +! msg->l4_protocol = rpl_routing_hdr->nextHeader; +! hlen = rpl_routing_hdr->HdrExtLen; //in 8-octet units +! +! // toss RPL routing header +! packetfunctions_tossHeader(msg,sizeof(rpl_routing_ht)); +! +! // toss source route addresses +! octetsAddressSize = LENGTH_ADDR128b - local_CmprE; //total length - number of octets that are elided +! packetfunctions_tossHeader(msg,octetsAddressSize*hlen); +! +! // indicate reception to upper layer +! switch(msg->l4_protocol) { +! case IANA_TCP: +! opentcp_receive(msg); +! break; +! case IANA_UDP: +! openudp_receive(msg); +! break; +! case IANA_ICMPv6: +! icmpv6_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)msg->l4_protocol, +! (errorparameter_t)1); +! //not sure that this is correct as iphc will free it? +! openqueue_freePacketBuffer(msg); +! return E_FAIL; +! } +! +! // stop executing here (successful) +! return E_SUCCESS; +! +! } else { +! // this is not the last hop +! +! if (rpl_routing_hdr->SegmentsLeft>numAddr) { +! // error code: there are more segments left than space in source route +! +! // TODO: send ICMPv6 packet (code 0) to originator +! +! openserial_printError(COMPONENT_FORWARDING,ERR_NO_NEXTHOP, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return E_FAIL; +! +! } else { +! +! // decrement number of segments left +! rpl_routing_hdr->SegmentsLeft--; +! +! // find next hop address in source route +! //addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft); +! addressposition = rpl_routing_hdr->SegmentsLeft; +! // how many octets have the address? +! if (rpl_routing_hdr->SegmentsLeft > 1){ +! octetsAddressSize = LENGTH_ADDR128b - local_CmprI; //max addr length - number of prefix octets that are elided in the internal route elements +! }else{ +! octetsAddressSize = LENGTH_ADDR128b - local_CmprE; //max addr length - number of prefix octets that are elided in the internal route elements +! } +! switch(octetsAddressSize) { +! case LENGTH_ADDR16b: +! // write previous hop +! msg->l2_nextORpreviousHop.type = ADDR_16B; +! memcpy( +! &(msg->l2_nextORpreviousHop.addr_16b), +! runningPointer+((addressposition)*octetsAddressSize), +! octetsAddressSize +! ); +! // write next hop +! msg->l3_destinationAdd.type = ADDR_16B; +! memcpy( +! &(msg->l3_destinationAdd.addr_16b), +! runningPointer+((addressposition)*octetsAddressSize), +! octetsAddressSize +! ); +! break; +! case LENGTH_ADDR64b: +! // write previous hop +! msg->l2_nextORpreviousHop.type = ADDR_64B; +! memcpy( +! &(msg->l2_nextORpreviousHop.addr_64b), +! runningPointer+((addressposition)*octetsAddressSize), +! octetsAddressSize +! ); +! +! //this is 128b address as send from forwarding function +! //takes care of reducing it if needed. +! +! //write next hop +! msg->l3_destinationAdd.type = ADDR_128B; +! memcpy( +! &(msg->l3_destinationAdd.addr_128b[0]), +! prefix->prefix, +! LENGTH_ADDR64b +! ); +! +! memcpy( +! &(msg->l3_destinationAdd.addr_128b[8]), +! runningPointer+((addressposition)*octetsAddressSize), +! octetsAddressSize +! ); +! +! break; +! case LENGTH_ADDR128b: +! // write previous hop +! msg->l2_nextORpreviousHop.type = ADDR_128B; +! memcpy( +! &(msg->l2_nextORpreviousHop.addr_128b), +! runningPointer+((addressposition)*octetsAddressSize), +! octetsAddressSize +! ); +! // write next hop +! msg->l3_destinationAdd.type = ADDR_128B; +! memcpy( +! &(msg->l3_destinationAdd.addr_128b), +! runningPointer+((addressposition)*octetsAddressSize), +! octetsAddressSize +! ); +! break; +! default: +! //poipoi xv +! //any other value is not supported by now. +! openserial_printError(COMPONENT_FORWARDING,ERR_INVALID_PARAM, +! (errorparameter_t)1, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return E_FAIL; +! } +! } +! } +! +! // send to next lower layer +! return iphc_sendFromForwarding(msg, ipv6_header,&hopbyhop_opt, PCKTFORWARD); +! } +! +! /** +! \brief Retrieve the next hop's address from routing table. +! +! \param[in] destination128b Final IPv6 destination address. +! \param[out] addressToWrite64b Location to write the EUI64 of next hop to. +! */ +! void forwarding_getNextHop_RoutingTable(open_addr_t* destination128b, open_addr_t* addressToWrite64b) { +! uint8_t i; +! open_addr_t temp_prefix64btoWrite; +! if (packetfunctions_isBroadcastMulticast(destination128b)) { +! // IP destination is broadcast, send to 0xffffffffffffffff +! addressToWrite64b->type = ADDR_64B; +! for (i=0;i<8;i++) { +! addressToWrite64b->addr_64b[i] = 0xff; +! } +! } else if (neighbors_isStableNeighbor(destination128b)) { +! // IP destination is 1-hop neighbor, send directly +! packetfunctions_ip128bToMac64b(destination128b,&temp_prefix64btoWrite,addressToWrite64b); +! } else { +! // destination is remote, send to preferred parent +! neighbors_getPreferredParentEui64(addressToWrite64b); +! } +! } +! /* +! * HOP BY HOP HEADER OPTION +! */ +! +! +! void forwarding_createHopByHopOption(rpl_hopoption_ht *hopbyhop_opt, uint8_t flags) { +! //set the rpl hop by hop header +! hopbyhop_opt->optionType = RPL_HOPBYHOP_HEADER_OPTION_TYPE; +! //8-bit field indicating the length of the option, in +! //octets, excluding the Option Type and Opt Data Len fields. +! hopbyhop_opt->optionLen = 0x04; //4-bytes, flags+instanceID+senderrank - no sub-tlvs +! hopbyhop_opt->flags = flags; +! hopbyhop_opt->rplInstanceID = icmpv6rpl_getRPLIntanceID(); //getit.. +! hopbyhop_opt->senderRank = neighbors_getMyDAGrank(); //TODO change to DAGRAnk(rank) instead of rank +! } +diff -crB openwsn/03b-IPv6/forwarding.h ../../../sys/net/openwsn/03b-IPv6/forwarding.h +*** openwsn/03b-IPv6/forwarding.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/forwarding.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,53 **** +! #ifndef __FORWARDING_H +! #define __FORWARDING_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup Forwarding +! \{ +! */ +! +! #include "iphc.h" +! +! //=========================== define ========================================== +! +! enum { +! PCKTFORWARD = 1, +! PCKTSEND = 2, +! }; +! +! //=========================== typedef ========================================= +! +! /** +! \brief RPL source routing header. +! +! As defined in http://tools.ietf.org/html/rfc6554#section-3. +! */ +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t nextHeader; ///< Header immediately following. +! uint8_t HdrExtLen; ///< In 8-octet units, excluding first 8. +! uint8_t RoutingType; ///< Set to 3 for "Source Routing Header". +! uint8_t SegmentsLeft; ///< Number of addresses still to visit. +! uint8_t CmprICmprE; ///< Number of prefix octets elided for all (CmprI) and last (CmprE) segment +! uint8_t PadRes; ///< Number of padding octets. Set to 0 if using EUI64. +! uint16_t Reserved; ///< Set to 0. +! } rpl_routing_ht; +! PRAGMA(pack()); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void forwarding_init(); +! error_t forwarding_send(OpenQueueEntry_t *msg); +! void forwarding_sendDone(OpenQueueEntry_t* msg, error_t error); +! void forwarding_receive(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,68 ---- +! #ifndef __FORWARDING_H +! #define __FORWARDING_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup Forwarding +! \{ +! */ +! +! #include "iphc.h" +! +! +! //=========================== define ========================================== +! +! #define RPL_HOPBYHOP_HEADER_OPTION_TYPE 0x63 +! +! enum { +! PCKTFORWARD = 1, +! PCKTSEND = 2, +! }; +! +! enum { +! O_FLAG = 0x80, +! R_FLAG = 0x40, +! F_FLAG = 0x20, +! }; +! +! +! //=========================== typedef ========================================= +! +! /** +! \brief RPL source routing header. +! +! As defined in http://tools.ietf.org/html/rfc6554#section-3. +! */ +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t nextHeader; ///< Header immediately following. +! uint8_t HdrExtLen; ///< In 8-octet units, excluding first 8. +! uint8_t RoutingType; ///< Set to 3 for "Source Routing Header". +! uint8_t SegmentsLeft; ///< Number of addresses still to visit. +! uint8_t CmprICmprE; ///< Number of prefix octets elided for all (CmprI) and last (CmprE) segment +! uint8_t PadRes; ///< Number of padding octets. Set to 0 if using EUI64. +! uint16_t Reserved; ///< Set to 0. +! } rpl_routing_ht; +! //PRAGMA(pack()); +! +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void forwarding_init(void); +! owerror_t forwarding_send(OpenQueueEntry_t *msg); +! void forwarding_sendDone(OpenQueueEntry_t *msg, owerror_t error); +! void forwarding_receive(OpenQueueEntry_t *msg, +! ipv6_header_iht ipv6_header, +! ipv6_hopbyhop_ht ipv6_hop_header, +! rpl_hopoption_ht hop_by_hop_option); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/03b-IPv6/icmpv6.c ../../../sys/net/openwsn/03b-IPv6/icmpv6.c +*** openwsn/03b-IPv6/icmpv6.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/icmpv6.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,63 **** +! #include "openwsn.h" +! #include "icmpv6.h" +! #include "icmpv6echo.h" +! #include "icmpv6rpl.h" +! #include "forwarding.h" +! #include "openqueue.h" +! #include "openserial.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void icmpv6_init() { +! } +! +! error_t icmpv6_send(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_ICMPv6; +! msg->l4_protocol = IANA_ICMPv6; +! return forwarding_send(msg); +! } +! +! void icmpv6_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_ICMPv6; +! switch (msg->l4_sourcePortORicmpv6Type) { +! case IANA_ICMPv6_ECHO_REQUEST: +! case IANA_ICMPv6_ECHO_REPLY: +! icmpv6echo_sendDone(msg, error); +! break; +! case IANA_ICMPv6_RPL: +! icmpv6rpl_sendDone(msg, error); +! break; +! default: +! openserial_printCritical(COMPONENT_ICMPv6,ERR_UNSUPPORTED_ICMPV6_TYPE, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)0); +! // free the corresponding packet buffer +! openqueue_freePacketBuffer(msg); +! break; +! } +! } +! +! void icmpv6_receive(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = ((ICMPv6_ht*)(msg->payload))->type; +! switch (msg->l4_sourcePortORicmpv6Type) { +! case IANA_ICMPv6_ECHO_REQUEST: +! case IANA_ICMPv6_ECHO_REPLY: +! icmpv6echo_receive(msg); +! break; +! case IANA_ICMPv6_RPL: +! icmpv6rpl_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_ICMPv6,ERR_UNSUPPORTED_ICMPV6_TYPE, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)1); +! // free the corresponding packet buffer +! openqueue_freePacketBuffer(msg); +! break; +! } + } +\ No newline at end of file +--- 1,63 ---- +! #include "openwsn.h" +! #include "icmpv6.h" +! #include "icmpv6echo.h" +! #include "icmpv6rpl.h" +! #include "forwarding.h" +! #include "openqueue.h" +! #include "openserial.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void icmpv6_init(void) { +! } +! +! owerror_t icmpv6_send(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_ICMPv6; +! msg->l4_protocol = IANA_ICMPv6; +! return forwarding_send(msg); +! } +! +! void icmpv6_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_ICMPv6; +! switch (msg->l4_sourcePortORicmpv6Type) { +! case IANA_ICMPv6_ECHO_REQUEST: +! case IANA_ICMPv6_ECHO_REPLY: +! icmpv6echo_sendDone(msg, error); +! break; +! case IANA_ICMPv6_RPL: +! icmpv6rpl_sendDone(msg, error); +! break; +! default: +! openserial_printCritical(COMPONENT_ICMPv6,ERR_UNSUPPORTED_ICMPV6_TYPE, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)0); +! // free the corresponding packet buffer +! openqueue_freePacketBuffer(msg); +! break; +! } +! } +! +! void icmpv6_receive(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = ((ICMPv6_ht*)(msg->payload))->type; +! switch (msg->l4_sourcePortORicmpv6Type) { +! case IANA_ICMPv6_ECHO_REQUEST: +! case IANA_ICMPv6_ECHO_REPLY: +! icmpv6echo_receive(msg); +! break; +! case IANA_ICMPv6_RPL: +! icmpv6rpl_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_ICMPv6,ERR_UNSUPPORTED_ICMPV6_TYPE, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)1); +! // free the corresponding packet buffer +! openqueue_freePacketBuffer(msg); +! break; +! } + } +\ No newline at end of file +diff -crB openwsn/03b-IPv6/icmpv6.h ../../../sys/net/openwsn/03b-IPv6/icmpv6.h +*** openwsn/03b-IPv6/icmpv6.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/icmpv6.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,61 **** +! #ifndef __ICMPv6_H +! #define __ICMPv6_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup ICMPv6 +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t type; +! uint8_t code; +! uint16_t checksum; +! // Below Identifier might need to be replaced by the identifier used by icmpv6rpl +! // uint16_t identifier; +! // Below sequence_number might need to be removed +! // uint16_t sequence_number; +! } ICMPv6_ht; +! +! typedef struct { +! uint8_t type; +! uint8_t code; +! uint16_t checksum; +! uint8_t hop_limit; +! uint8_t flags; +! uint16_t router_lifetime; +! uint32_t reachable_time; +! uint32_t retransmission_timer; +! } ICMPv6_RA_ht; +! +! typedef struct { +! uint8_t option_type; +! uint8_t option_length; +! uint8_t prefix_length; +! uint8_t flags; +! uint32_t valid_lifetime; +! uint32_t preferred_lifetime; +! uint32_t unused; +! uint8_t prefix[16]; // prefix container always 16B +! } ICMPv6_64bprefix_option_ht; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void icmpv6_init(); +! error_t icmpv6_send(OpenQueueEntry_t* msg); +! void icmpv6_sendDone(OpenQueueEntry_t* msg, error_t error); +! void icmpv6_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,61 ---- +! #ifndef __ICMPv6_H +! #define __ICMPv6_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup ICMPv6 +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t type; +! uint8_t code; +! uint16_t checksum; +! // Below Identifier might need to be replaced by the identifier used by icmpv6rpl +! // uint16_t identifier; +! // Below sequence_number might need to be removed +! // uint16_t sequence_number; +! } ICMPv6_ht; +! +! typedef struct { +! uint8_t type; +! uint8_t code; +! uint16_t checksum; +! uint8_t hop_limit; +! uint8_t flags; +! uint16_t router_lifetime; +! uint32_t reachable_time; +! uint32_t retransmission_timer; +! } ICMPv6_RA_ht; +! +! typedef struct { +! uint8_t option_type; +! uint8_t option_length; +! uint8_t prefix_length; +! uint8_t flags; +! uint32_t valid_lifetime; +! uint32_t preferred_lifetime; +! uint32_t unused; +! uint8_t prefix[16]; // prefix container always 16B +! } ICMPv6_64bprefix_option_ht; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void icmpv6_init(void); +! owerror_t icmpv6_send(OpenQueueEntry_t* msg); +! void icmpv6_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void icmpv6_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/03b-IPv6/icmpv6echo.c ../../../sys/net/openwsn/03b-IPv6/icmpv6echo.c +*** openwsn/03b-IPv6/icmpv6echo.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/icmpv6echo.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,152 **** +! #include "openwsn.h" +! #include "icmpv6echo.h" +! #include "icmpv6.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! bool busySending; +! open_addr_t hisAddress; +! uint16_t seq; +! } icmpv6echo_vars_t; +! +! icmpv6echo_vars_t icmpv6echo_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void icmpv6echo_init() { +! icmpv6echo_vars.busySending = FALSE; +! icmpv6echo_vars.seq = 0; +! } +! +! void icmpv6echo_trigger() { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[16]; +! OpenQueueEntry_t* msg; +! +! //get command from OpenSerial (16B IPv6 destination address) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! icmpv6echo_vars.hisAddress.type = ADDR_128B; +! memcpy(&(icmpv6echo_vars.hisAddress.addr_128b[0]),&(input_buffer[0]),16); +! +! //send +! if (icmpv6echo_vars.busySending==TRUE) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_BUSY_SENDING, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } else { +! icmpv6echo_vars.busySending = TRUE; +! +! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); +! if (msg==NULL) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! icmpv6echo_vars.busySending = FALSE; +! return; +! } +! //admin +! msg->creator = COMPONENT_ICMPv6ECHO; +! msg->owner = COMPONENT_ICMPv6ECHO; +! //l4 +! msg->l4_protocol = IANA_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REQUEST; +! //l3 +! memcpy(&(msg->l3_destinationAdd),&icmpv6echo_vars.hisAddress,sizeof(open_addr_t)); +! //payload +! packetfunctions_reserveHeaderSize(msg,4); +! packetfunctions_htonl(0x789abcde,(uint8_t*)(msg->payload)); +! //ICMPv6 header +! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); +! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; +! ((ICMPv6_ht*)(msg->payload))->code = 0; +! // Below Identifier might need to be replaced by the identifier used by icmpv6rpl +! // packetfunctions_htons(0x1234 ,(uint8_t*)&((ICMPv6_ht*)(msg->payload))->identifier); +! // Below sequence_number might need to be removed +! // packetfunctions_htons(icmpv6echo_vars.seq++ ,(uint8_t*)&((ICMPv6_ht*)(msg->payload))->sequence_number); +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//do last +! //send +! if (icmpv6_send(msg)!=E_SUCCESS) { +! icmpv6echo_vars.busySending = FALSE; +! openqueue_freePacketBuffer(msg); +! } +! } +! } +! +! void icmpv6echo_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_ICMPv6ECHO; +! if (msg->creator!=COMPONENT_ICMPv6ECHO) {//that was a packet I had not created +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! icmpv6echo_vars.busySending = FALSE; +! } +! +! void icmpv6echo_receive(OpenQueueEntry_t* msg) { +! OpenQueueEntry_t* reply; +! msg->owner = COMPONENT_ICMPv6ECHO; +! switch(msg->l4_sourcePortORicmpv6Type) { +! case IANA_ICMPv6_ECHO_REQUEST: +! openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REQUEST, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // get a new openqueuEntry_t for the echo reply +! reply = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); +! if (reply==NULL) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)1, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! // take ownership over reply +! reply->creator = COMPONENT_ICMPv6ECHO; +! reply->owner = COMPONENT_ICMPv6ECHO; +! // copy payload from msg to (end of) reply +! packetfunctions_reserveHeaderSize(reply,msg->length); +! memcpy(reply->payload,msg->payload,msg->length); +! // copy source of msg in destination of reply +! memcpy(&(reply->l3_destinationAdd),&(msg->l3_sourceAdd),sizeof(open_addr_t)); +! // free up msg +! openqueue_freePacketBuffer(msg); +! msg = NULL; +! // administrative information for reply +! reply->l4_protocol = IANA_ICMPv6; +! reply->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REPLY; +! ((ICMPv6_ht*)(reply->payload))->type = reply->l4_sourcePortORicmpv6Type; +! packetfunctions_calculateChecksum(reply,(uint8_t*)&(((ICMPv6_ht*)(reply->payload))->checksum));//do last +! icmpv6echo_vars.busySending = TRUE; +! if (icmpv6_send(reply)!=E_SUCCESS) { +! icmpv6echo_vars.busySending = FALSE; +! openqueue_freePacketBuffer(reply); +! } +! break; +! case IANA_ICMPv6_ECHO_REPLY: +! openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REPLY, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! break; +! default: +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_UNSUPPORTED_ICMPV6_TYPE, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)2); +! openqueue_freePacketBuffer(msg); +! break; +! } +! } +! +! //=========================== private ========================================= +\ No newline at end of file +--- 1,148 ---- +! #include "openwsn.h" +! #include "icmpv6echo.h" +! #include "icmpv6.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! //#include "debugpins.h" +! +! //=========================== variables ======================================= +! +! icmpv6echo_vars_t icmpv6echo_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void icmpv6echo_init(void) { +! icmpv6echo_vars.busySending = FALSE; +! icmpv6echo_vars.seq = 0; +! } +! +! void icmpv6echo_trigger(void) { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[16]; +! OpenQueueEntry_t* msg; +! +! +! //get command from OpenSerial (16B IPv6 destination address) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! icmpv6echo_vars.hisAddress.type = ADDR_128B; +! memcpy(&(icmpv6echo_vars.hisAddress.addr_128b[0]),&(input_buffer[0]),16); +! +! //send +! if (icmpv6echo_vars.busySending==TRUE) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_BUSY_SENDING, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } else { +! icmpv6echo_vars.busySending = TRUE; +! +! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); +! if (msg==NULL) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! icmpv6echo_vars.busySending = FALSE; +! return; +! } +! //admin +! msg->creator = COMPONENT_ICMPv6ECHO; +! msg->owner = COMPONENT_ICMPv6ECHO; +! //l4 +! msg->l4_protocol = IANA_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REQUEST; +! //l3 +! memcpy(&(msg->l3_destinationAdd),&icmpv6echo_vars.hisAddress,sizeof(open_addr_t)); +! //payload +! packetfunctions_reserveHeaderSize(msg,4); +! packetfunctions_htonl(0x789abcde,(uint8_t*)(msg->payload)); +! //ICMPv6 header +! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); +! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; +! ((ICMPv6_ht*)(msg->payload))->code = 0; +! // Below Identifier might need to be replaced by the identifier used by icmpv6rpl +! // packetfunctions_htons(0x1234 ,(uint8_t*)&((ICMPv6_ht*)(msg->payload))->identifier); +! // Below sequence_number might need to be removed +! // packetfunctions_htons(icmpv6echo_vars.seq++ ,(uint8_t*)&((ICMPv6_ht*)(msg->payload))->sequence_number); +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//do last +! //send +! if (icmpv6_send(msg)!=E_SUCCESS) { +! icmpv6echo_vars.busySending = FALSE; +! openqueue_freePacketBuffer(msg); +! } +! } +! } +! +! void icmpv6echo_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_ICMPv6ECHO; +! if (msg->creator!=COMPONENT_ICMPv6ECHO) {//that was a packet I had not created +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! icmpv6echo_vars.busySending = FALSE; +! } +! +! void icmpv6echo_receive(OpenQueueEntry_t* msg) { +! OpenQueueEntry_t* reply; +! msg->owner = COMPONENT_ICMPv6ECHO; +! switch(msg->l4_sourcePortORicmpv6Type) { +! case IANA_ICMPv6_ECHO_REQUEST: +! openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REQUEST, +! (errorparameter_t)0, +! (errorparameter_t)0); +! // get a new openqueuEntry_t for the echo reply +! reply = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6ECHO); +! if (reply==NULL) { +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)1, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! // take ownership over reply +! reply->creator = COMPONENT_ICMPv6ECHO; +! reply->owner = COMPONENT_ICMPv6ECHO; +! // copy payload from msg to (end of) reply +! packetfunctions_reserveHeaderSize(reply,msg->length); +! memcpy(reply->payload,msg->payload,msg->length); +! // copy source of msg in destination of reply +! memcpy(&(reply->l3_destinationAdd),&(msg->l3_sourceAdd),sizeof(open_addr_t)); +! // free up msg +! openqueue_freePacketBuffer(msg); +! msg = NULL; +! // administrative information for reply +! reply->l4_protocol = IANA_ICMPv6; +! reply->l4_sourcePortORicmpv6Type = IANA_ICMPv6_ECHO_REPLY; +! ((ICMPv6_ht*)(reply->payload))->type = reply->l4_sourcePortORicmpv6Type; +! packetfunctions_calculateChecksum(reply,(uint8_t*)&(((ICMPv6_ht*)(reply->payload))->checksum));//do last +! icmpv6echo_vars.busySending = TRUE; +! if (icmpv6_send(reply)!=E_SUCCESS) { +! icmpv6echo_vars.busySending = FALSE; +! openqueue_freePacketBuffer(reply); +! } +! break; +! case IANA_ICMPv6_ECHO_REPLY: +! openserial_printInfo(COMPONENT_ICMPv6ECHO,ERR_RCVD_ECHO_REPLY, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! break; +! default: +! openserial_printError(COMPONENT_ICMPv6ECHO,ERR_UNSUPPORTED_ICMPV6_TYPE, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)2); +! openqueue_freePacketBuffer(msg); +! break; +! } +! } +! +! //=========================== private ========================================= +diff -crB openwsn/03b-IPv6/icmpv6echo.h ../../../sys/net/openwsn/03b-IPv6/icmpv6echo.h +*** openwsn/03b-IPv6/icmpv6echo.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/icmpv6echo.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,29 **** +! #ifndef __ICMPv6ECHO_H +! #define __ICMPv6ECHO_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup ICMPv6Echo +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void icmpv6echo_init(); +! void icmpv6echo_trigger(); +! void icmpv6echo_sendDone(OpenQueueEntry_t* msg, error_t error); +! void icmpv6echo_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,35 ---- +! #ifndef __ICMPv6ECHO_H +! #define __ICMPv6ECHO_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup ICMPv6Echo +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== module variables ================================ +! +! typedef struct { +! bool busySending; +! open_addr_t hisAddress; +! uint16_t seq; +! } icmpv6echo_vars_t; +! +! //=========================== prototypes ====================================== +! +! void icmpv6echo_init(void); +! void icmpv6echo_trigger(void); +! void icmpv6echo_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void icmpv6echo_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/03b-IPv6/icmpv6rpl.c ../../../sys/net/openwsn/03b-IPv6/icmpv6rpl.c +*** openwsn/03b-IPv6/icmpv6rpl.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/icmpv6rpl.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,562 **** +! #include "openwsn.h" +! #include "icmpv6rpl.h" +! #include "icmpv6.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "neighbors.h" +! #include "packetfunctions.h" +! #include "openrandom.h" +! #include "scheduler.h" +! #include "idmanager.h" +! #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)); +! +! //=== admin +! +! icmpv6rpl_vars.busySending = FALSE; +! icmpv6rpl_vars.DODAGIDFlagSet = 0; +! +! //=== DIO-related +! +! icmpv6rpl_vars.dio.rplinstanceId = 0x00; ///< TODO: put correct value +! icmpv6rpl_vars.dio.verNumb = 0x00; ///< TODO: put correct value +! // rank: to be populated upon TX +! icmpv6rpl_vars.dio.rplOptions = MOP_DIO_A | \ +! MOP_DIO_B | \ +! MOP_DIO_C | \ +! PRF_DIO_A | \ +! PRF_DIO_B | \ +! PRF_DIO_C | \ +! G_DIO ; +! icmpv6rpl_vars.dio.DTSN = 0x33; ///< TODO: put correct value +! icmpv6rpl_vars.dio.flags = 0x00; +! icmpv6rpl_vars.dio.reserved = 0x00; +! // DODAGID: to be populated upon receiving DIO +! +! icmpv6rpl_vars.dioDestination.type = ADDR_128B; +! memcpy(&icmpv6rpl_vars.dioDestination.addr_128b[0],all_routers_multicast,sizeof(all_routers_multicast)); +! +! icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); +! icmpv6rpl_vars.timerIdDIO = opentimers_start( +! icmpv6rpl_vars.periodDIO, +! TIMER_PERIODIC, +! TIME_MS, +! icmpv6rpl_timer_DIO_cb +! ); +! +! //=== DAO-related +! +! icmpv6rpl_vars.dao.rplinstanceId = 0x00; ///< TODO: put correct value +! icmpv6rpl_vars.dao.K_D_flags = FLAG_DAO_A | \ +! FLAG_DAO_B | \ +! FLAG_DAO_C | \ +! FLAG_DAO_D | \ +! FLAG_DAO_E | \ +! PRF_DIO_C | \ +! FLAG_DAO_F | \ +! 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; +! // optionLength: to be populated upon TX +! icmpv6rpl_vars.dao_transit.E_flags = E_DAO_Transit_Info; +! icmpv6rpl_vars.dao_transit.PathControl = PC1_A_DAO_Transit_Info | \ +! PC1_B_DAO_Transit_Info | \ +! PC2_A_DAO_Transit_Info | \ +! PC2_B_DAO_Transit_Info | \ +! PC3_A_DAO_Transit_Info | \ +! PC3_B_DAO_Transit_Info | \ +! PC4_A_DAO_Transit_Info | \ +! PC4_B_DAO_Transit_Info; +! icmpv6rpl_vars.dao_transit.PathSequence = 0x00; // to be incremented at each TX +! icmpv6rpl_vars.dao_transit.PathLifetime = 0xAA; +! //target information +! icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE; +! icmpv6rpl_vars.dao_target.optionLength = 0; +! icmpv6rpl_vars.dao_target.flags = 0; +! icmpv6rpl_vars.dao_target.prefixLength = 0; +! +! icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); +! icmpv6rpl_vars.timerIdDAO = opentimers_start( +! icmpv6rpl_vars.periodDAO, +! TIMER_PERIODIC, +! TIME_MS, +! icmpv6rpl_timer_DAO_cb +! ); +! +! } +! +! /** +! \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; +! +! // make sure I created it +! if (msg->creator!=COMPONENT_ICMPv6RPL) { +! openserial_printError(COMPONENT_ICMPv6RPL,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! +! // free packet +! openqueue_freePacketBuffer(msg); +! +! // I'm not busy sending anymore +! icmpv6rpl_vars.busySending = FALSE; +! } +! +! /** +! \brief Called when RPL message received. +! +! \param[in] msg Pointer to the received message. +! */ +! void icmpv6rpl_receive(OpenQueueEntry_t* msg) { +! uint8_t icmpv6code; +! open_addr_t myPrefix; +! +! // take ownership +! msg->owner = COMPONENT_ICMPv6RPL; +! +! // retrieve ICMPv6 code +! icmpv6code = (((ICMPv6_ht*)(msg->payload))->code); +! +! // toss ICMPv6 header +! packetfunctions_tossHeader(msg,sizeof(ICMPv6_ht)); +! +! // handle message +! switch (icmpv6code) { +! +! case IANA_ICMPv6_RPL_DIO: +! if (idmanager_getIsBridge()==TRUE) { +! // stop here if I'm in bridge mode +! break; // break, don't return +! } +! +! // update neighbor table +! neighbors_indicateRxDIO(msg); +! +! // update DODAGID in DIO/DAO +! memcpy( +! &(icmpv6rpl_vars.dio.DODAGID[0]), +! &(((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0]), +! sizeof(icmpv6rpl_vars.dio.DODAGID) +! ); +! memcpy( +! &(icmpv6rpl_vars.dao.DODAGID[0]), +! &(((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0]), +! sizeof(icmpv6rpl_vars.dao.DODAGID) +! ); +! +! // remember I got a DODAGID +! icmpv6rpl_vars.DODAGIDFlagSet=1; +! +! // update my prefix +! myPrefix.type = ADDR_PREFIX; +! memcpy( +! myPrefix.prefix, +! &((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0], +! sizeof(myPrefix.prefix) +! ); +! idmanager_setMyID(&myPrefix); +! +! break; +! +! case IANA_ICMPv6_RPL_DAO: +! // this should never happen +! openserial_printCritical(COMPONENT_ICMPv6RPL,ERR_UNEXPECTED_DAO, +! (errorparameter_t)0, +! (errorparameter_t)0); +! break; +! +! default: +! // this should never happen +! openserial_printCritical(COMPONENT_ICMPv6RPL,ERR_MSG_UNKNOWN_TYPE, +! (errorparameter_t)icmpv6code, +! (errorparameter_t)0); +! break; +! +! } +! +! // free message +! openqueue_freePacketBuffer(msg); +! } +! +! //=========================== private ========================================= +! +! //===== DIO-related +! +! /** +! \brief DIO timer callback function. +! +! \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); +! } +! +! /** +! \brief Handler for DIO timer event. +! +! \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; +! +! // check whether we need to send DIO +! if (icmpv6rpl_vars.delayDIO==0) { +! +! // send DIO +! sendDIO(); +! +! // pick a new pseudo-random periodDIO +! icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); +! +! // arm the DIO timer with this new value +! opentimers_setPeriod( +! icmpv6rpl_vars.timerIdDIO, +! TIME_MS, +! icmpv6rpl_vars.periodDIO +! ); +! } +! } +! +! /** +! \brief Prepare and a send a RPL DIO. +! */ +! void sendDIO() { +! OpenQueueEntry_t* msg; +! +! // stop if I'm not sync'ed +! if (ieee154e_isSynch()==FALSE) { +! +! // remove packets genereted by this module (DIO and DAO) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); +! +! // I'm not busy sending a DIO/DAO +! icmpv6rpl_vars.busySending = FALSE; +! +! // stop here +! return; +! } +! +! // do not send DIO if I'm in in bridge mode +! if (idmanager_getIsBridge()==TRUE) { +! return; +! } +! +! // do not send DIO if I have the default DAG rank +! if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { +! return; +! } +! +! // do not send DIO if I'm already busy sending +! if (icmpv6rpl_vars.busySending==TRUE) { +! return; +! } +! +! // if you get here, all good to send a DIO +! +! // I'm now busy sending +! icmpv6rpl_vars.busySending = TRUE; +! +! // reserve a free packet buffer for DIO +! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); +! if (msg==NULL) { +! openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! icmpv6rpl_vars.busySending = FALSE; +! +! return; +! } +! +! // take ownership +! msg->creator = COMPONENT_ICMPv6RPL; +! msg->owner = COMPONENT_ICMPv6RPL; +! +! // set transport information +! msg->l4_protocol = IANA_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; +! +! // set DIO destination +! memcpy(&(msg->l3_destinationAdd),&icmpv6rpl_vars.dioDestination,sizeof(open_addr_t)); +! +! //===== DIO payload +! // note: DIO is already mostly populated +! icmpv6rpl_vars.dio.rank = neighbors_getMyDAGrank(); +! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dio_ht)); +! memcpy( +! ((icmpv6rpl_dio_ht*)(msg->payload)), +! &(icmpv6rpl_vars.dio), +! sizeof(icmpv6rpl_dio_ht) +! ); +! +! //===== ICMPv6 header +! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); +! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; +! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DIO; +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//call last +! +! //send +! if (icmpv6_send(msg)!=E_SUCCESS) { +! icmpv6rpl_vars.busySending = FALSE; +! openqueue_freePacketBuffer(msg); +! } else { +! icmpv6rpl_vars.busySending = FALSE; +! } +! } +! +! //===== DAO-related +! +! /** +! \brief DAO timer callback function. +! +! \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); +! } +! +! /** +! \brief Handler for DAO timer event. +! +! \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; +! +! // check whether we need to send DAO +! if (icmpv6rpl_vars.delayDAO==0) { +! +! // send DAO +! sendDAO(); +! +! // pick a new pseudo-random periodDAO +! icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); +! +! // arm the DAO timer with this new value +! opentimers_setPeriod( +! icmpv6rpl_vars.timerIdDAO, +! TIME_MS, +! icmpv6rpl_vars.periodDAO +! ); +! } +! } +! +! /** +! \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 +! +! // delete packets genereted by this module (DIO and DAO) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); +! +! // I'm not busy sending a DIO/DAO +! icmpv6rpl_vars.busySending = FALSE; +! +! // stop here +! return; +! } +! +! // dont' send a DAO if you're in bridge mode +! if (idmanager_getIsBridge()==TRUE) { +! return; +! } +! +! // dont' send a DAO if you did not acquire a DAGrank +! if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { +! return; +! } +! +! // dont' send a DAO if you're still busy sending the previous one +! if (icmpv6rpl_vars.busySending==TRUE) { +! return; +! } +! +! // if you get here, you start construct DAO +! +! // reserve a free packet buffer for DAO +! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); +! if (msg==NULL) { +! openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! +! // take ownership +! msg->creator = COMPONENT_ICMPv6RPL; +! msg->owner = COMPONENT_ICMPv6RPL; +! +! // set transport information +! msg->l4_protocol = IANA_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; +! +! // set DAO destination +! msg->l3_destinationAdd.type=ADDR_128B; +! memcpy(msg->l3_destinationAdd.addr_128b,icmpv6rpl_vars.dio.DODAGID,sizeof(icmpv6rpl_vars.dio.DODAGID)); +! +! //===== fill in packet +! +! //=== transit option -- from RFC 6550, page 55 - 1 transit information header per parent is required. +! numTransitParents = 0; +! for (nbrIdx=0;nbrIdxpayload)), +! &(icmpv6rpl_vars.dao_transit), +! sizeof(icmpv6rpl_dao_transit_ht) +! ); +! +! // remember I found it +! numTransitParents++; +! } +! } +! +! //target information is required. RFC 6550 page 55. +! /* +! One or more Transit Information options MUST be preceded by one or +! more RPL Target options. +! */ +! numTargetParents = 0; +! for (nbrIdx=0;nbrIdxpayload)), +! &(icmpv6rpl_vars.dao_target), +! sizeof(icmpv6rpl_dao_target_ht) +! ); +! +! // remember I found it +! numTargetParents++; +! } +! } +! +! +! // stop here if no parents found +! if (numTransitParents==0) { +! openqueue_freePacketBuffer(msg); +! return; +! } +! +! icmpv6rpl_vars.dao_transit.PathSequence++; //increment path sequence. +! // if you get here, you will send a DAO +! +! +! //=== DAO header +! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_ht)); +! memcpy( +! ((icmpv6rpl_dao_ht*)(msg->payload)), +! &(icmpv6rpl_vars.dao), +! sizeof(icmpv6rpl_dao_ht) +! ); +! +! //=== ICMPv6 header +! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); +! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; +! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DAO; +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum)); //call last +! +! //===== send +! if (icmpv6_send(msg)==E_SUCCESS) { +! icmpv6rpl_vars.busySending = TRUE; +! } else { +! openqueue_freePacketBuffer(msg); +! } +! } +--- 1,561 ---- +! #include "openwsn.h" +! #include "icmpv6rpl.h" +! #include "icmpv6.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "neighbors.h" +! #include "packetfunctions.h" +! #include "openrandom.h" +! #include "scheduler.h" +! #include "idmanager.h" +! #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)); +! +! //=== admin +! +! icmpv6rpl_vars.busySending = FALSE; +! icmpv6rpl_vars.DODAGIDFlagSet = 0; +! +! //=== DIO-related +! +! icmpv6rpl_vars.dio.rplinstanceId = 0x00; ///< TODO: put correct value +! icmpv6rpl_vars.dio.verNumb = 0x00; ///< TODO: put correct value +! // rank: to be populated upon TX +! icmpv6rpl_vars.dio.rplOptions = MOP_DIO_A | \ +! MOP_DIO_B | \ +! MOP_DIO_C | \ +! PRF_DIO_A | \ +! PRF_DIO_B | \ +! PRF_DIO_C | \ +! G_DIO ; +! icmpv6rpl_vars.dio.DTSN = 0x33; ///< TODO: put correct value +! icmpv6rpl_vars.dio.flags = 0x00; +! icmpv6rpl_vars.dio.reserved = 0x00; +! // DODAGID: to be populated upon receiving DIO +! +! icmpv6rpl_vars.dioDestination.type = ADDR_128B; +! memcpy(&icmpv6rpl_vars.dioDestination.addr_128b[0],all_routers_multicast,sizeof(all_routers_multicast)); +! +! icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); +! icmpv6rpl_vars.timerIdDIO = opentimers_start( +! icmpv6rpl_vars.periodDIO, +! TIMER_PERIODIC, +! TIME_MS, +! icmpv6rpl_timer_DIO_cb +! ); +! +! //=== DAO-related +! +! icmpv6rpl_vars.dao.rplinstanceId = 0x00; ///< TODO: put correct value +! icmpv6rpl_vars.dao.K_D_flags = FLAG_DAO_A | \ +! FLAG_DAO_B | \ +! FLAG_DAO_C | \ +! FLAG_DAO_D | \ +! FLAG_DAO_E | \ +! PRF_DIO_C | \ +! FLAG_DAO_F | \ +! 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; +! // optionLength: to be populated upon TX +! icmpv6rpl_vars.dao_transit.E_flags = E_DAO_Transit_Info; +! icmpv6rpl_vars.dao_transit.PathControl = PC1_A_DAO_Transit_Info | \ +! PC1_B_DAO_Transit_Info | \ +! PC2_A_DAO_Transit_Info | \ +! PC2_B_DAO_Transit_Info | \ +! PC3_A_DAO_Transit_Info | \ +! PC3_B_DAO_Transit_Info | \ +! PC4_A_DAO_Transit_Info | \ +! PC4_B_DAO_Transit_Info; +! icmpv6rpl_vars.dao_transit.PathSequence = 0x00; // to be incremented at each TX +! icmpv6rpl_vars.dao_transit.PathLifetime = 0xAA; +! //target information +! icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE; +! icmpv6rpl_vars.dao_target.optionLength = 0; +! icmpv6rpl_vars.dao_target.flags = 0; +! icmpv6rpl_vars.dao_target.prefixLength = 0; +! +! icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); +! icmpv6rpl_vars.timerIdDAO = opentimers_start( +! icmpv6rpl_vars.periodDAO, +! TIMER_PERIODIC, +! TIME_MS, +! icmpv6rpl_timer_DAO_cb +! ); +! +! } +! +! 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; +! +! // make sure I created it +! if (msg->creator!=COMPONENT_ICMPv6RPL) { +! openserial_printError(COMPONENT_ICMPv6RPL,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! +! // free packet +! openqueue_freePacketBuffer(msg); +! +! // I'm not busy sending anymore +! icmpv6rpl_vars.busySending = FALSE; +! } +! +! /** +! \brief Called when RPL message received. +! +! \param[in] msg Pointer to the received message. +! */ +! void icmpv6rpl_receive(OpenQueueEntry_t* msg) { +! uint8_t icmpv6code; +! open_addr_t myPrefix; +! +! // take ownership +! msg->owner = COMPONENT_ICMPv6RPL; +! +! // retrieve ICMPv6 code +! icmpv6code = (((ICMPv6_ht*)(msg->payload))->code); +! +! // toss ICMPv6 header +! packetfunctions_tossHeader(msg,sizeof(ICMPv6_ht)); +! +! // handle message +! switch (icmpv6code) { +! +! case IANA_ICMPv6_RPL_DIO: +! if (idmanager_getIsBridge()==TRUE) { +! // stop here if I'm in bridge mode +! break; // break, don't return +! } +! +! // update neighbor table +! neighbors_indicateRxDIO(msg); +! +! // update DODAGID in DIO/DAO +! memcpy( +! &(icmpv6rpl_vars.dio.DODAGID[0]), +! &(((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0]), +! sizeof(icmpv6rpl_vars.dio.DODAGID) +! ); +! memcpy( +! &(icmpv6rpl_vars.dao.DODAGID[0]), +! &(((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0]), +! sizeof(icmpv6rpl_vars.dao.DODAGID) +! ); +! +! // remember I got a DODAGID +! icmpv6rpl_vars.DODAGIDFlagSet=1; +! +! // update my prefix +! myPrefix.type = ADDR_PREFIX; +! memcpy( +! myPrefix.prefix, +! &((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0], +! sizeof(myPrefix.prefix) +! ); +! idmanager_setMyID(&myPrefix); +! +! break; +! +! case IANA_ICMPv6_RPL_DAO: +! // this should never happen +! openserial_printCritical(COMPONENT_ICMPv6RPL,ERR_UNEXPECTED_DAO, +! (errorparameter_t)0, +! (errorparameter_t)0); +! break; +! +! default: +! // this should never happen +! openserial_printCritical(COMPONENT_ICMPv6RPL,ERR_MSG_UNKNOWN_TYPE, +! (errorparameter_t)icmpv6code, +! (errorparameter_t)0); +! break; +! +! } +! +! // free message +! openqueue_freePacketBuffer(msg); +! } +! +! //=========================== private ========================================= +! +! //===== DIO-related +! +! /** +! \brief DIO timer callback function. +! +! \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");*/ +! } +! +! /** +! \brief Handler for DIO timer event. +! +! \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; +! +! // check whether we need to send DIO +! if (icmpv6rpl_vars.delayDIO==0) { +! +! // send DIO +! sendDIO(); +! +! // pick a new pseudo-random periodDIO +! icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); +! +! // arm the DIO timer with this new value +! opentimers_setPeriod( +! icmpv6rpl_vars.timerIdDIO, +! TIME_MS, +! icmpv6rpl_vars.periodDIO +! ); +! } +! } +! +! /** +! \brief Prepare and a send a RPL DIO. +! */ +! void sendDIO(void) { +! OpenQueueEntry_t* msg; +! +! // stop if I'm not sync'ed +! if (ieee154e_isSynch()==FALSE) { +! +! // remove packets genereted by this module (DIO and DAO) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); +! +! // I'm not busy sending a DIO/DAO +! icmpv6rpl_vars.busySending = FALSE; +! +! // stop here +! return; +! } +! +! // do not send DIO if I'm in in bridge mode +! if (idmanager_getIsBridge()==TRUE) { +! return; +! } +! +! // do not send DIO if I have the default DAG rank +! if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { +! return; +! } +! +! // do not send DIO if I'm already busy sending +! if (icmpv6rpl_vars.busySending==TRUE) { +! return; +! } +! +! // if you get here, all good to send a DIO +! +! // I'm now busy sending +! icmpv6rpl_vars.busySending = TRUE; +! +! // reserve a free packet buffer for DIO +! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); +! if (msg==NULL) { +! openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! icmpv6rpl_vars.busySending = FALSE; +! +! return; +! } +! +! // take ownership +! msg->creator = COMPONENT_ICMPv6RPL; +! msg->owner = COMPONENT_ICMPv6RPL; +! +! // set transport information +! msg->l4_protocol = IANA_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; +! +! // set DIO destination +! memcpy(&(msg->l3_destinationAdd),&icmpv6rpl_vars.dioDestination,sizeof(open_addr_t)); +! +! //===== DIO payload +! // note: DIO is already mostly populated +! icmpv6rpl_vars.dio.rank = neighbors_getMyDAGrank(); +! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dio_ht)); +! memcpy( +! ((icmpv6rpl_dio_ht*)(msg->payload)), +! &(icmpv6rpl_vars.dio), +! sizeof(icmpv6rpl_dio_ht) +! ); +! +! //===== ICMPv6 header +! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); +! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; +! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DIO; +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//call last +! +! //send +! if (icmpv6_send(msg)!=E_SUCCESS) { +! icmpv6rpl_vars.busySending = FALSE; +! openqueue_freePacketBuffer(msg); +! } else { +! icmpv6rpl_vars.busySending = FALSE; +! } +! } +! +! //===== DAO-related +! +! /** +! \brief DAO timer callback function. +! +! \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");*/ +! } +! +! /** +! \brief Handler for DAO timer event. +! +! \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; +! +! // check whether we need to send DAO +! if (icmpv6rpl_vars.delayDAO==0) { +! +! // send DAO +! sendDAO(); +! +! // pick a new pseudo-random periodDAO +! icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); +! +! // arm the DAO timer with this new value +! opentimers_setPeriod( +! icmpv6rpl_vars.timerIdDAO, +! TIME_MS, +! icmpv6rpl_vars.periodDAO +! ); +! } +! } +! +! /** +! \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 +! +! // delete packets genereted by this module (DIO and DAO) from openqueue +! openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); +! +! // I'm not busy sending a DIO/DAO +! icmpv6rpl_vars.busySending = FALSE; +! +! // stop here +! return; +! } +! +! // dont' send a DAO if you're in bridge mode +! if (idmanager_getIsBridge()==TRUE) { +! return; +! } +! +! // dont' send a DAO if you did not acquire a DAGrank +! if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { +! return; +! } +! +! // dont' send a DAO if you're still busy sending the previous one +! if (icmpv6rpl_vars.busySending==TRUE) { +! return; +! } +! +! // if you get here, you start construct DAO +! +! // reserve a free packet buffer for DAO +! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); +! if (msg==NULL) { +! openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! +! // take ownership +! msg->creator = COMPONENT_ICMPv6RPL; +! msg->owner = COMPONENT_ICMPv6RPL; +! +! // set transport information +! msg->l4_protocol = IANA_ICMPv6; +! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; +! +! // set DAO destination +! msg->l3_destinationAdd.type=ADDR_128B; +! memcpy(msg->l3_destinationAdd.addr_128b,icmpv6rpl_vars.dio.DODAGID,sizeof(icmpv6rpl_vars.dio.DODAGID)); +! +! //===== 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. +! /* +! One or more Transit Information options MUST be preceded by one or +! more RPL Target options. +! */ +! numTargetParents = 0; +! for (nbrIdx=0;nbrIdxpayload)), +! &(icmpv6rpl_vars.dao_target), +! sizeof(icmpv6rpl_dao_target_ht) +! ); +! +! // 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; +! } +! +! +! // stop here if no parents found +! if (numTransitParents==0) { +! openqueue_freePacketBuffer(msg); +! return; +! } +! +! icmpv6rpl_vars.dao_transit.PathSequence++; //increment path sequence. +! // if you get here, you will send a DAO +! +! +! //=== DAO header +! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_ht)); +! memcpy( +! ((icmpv6rpl_dao_ht*)(msg->payload)), +! &(icmpv6rpl_vars.dao), +! sizeof(icmpv6rpl_dao_ht) +! ); +! +! //=== ICMPv6 header +! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); +! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; +! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DAO; +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum)); //call last +! +! //===== send +! if (icmpv6_send(msg)==E_SUCCESS) { +! icmpv6rpl_vars.busySending = TRUE; +! } else { +! openqueue_freePacketBuffer(msg); +! } +! } +diff -crB openwsn/03b-IPv6/icmpv6rpl.h ../../../sys/net/openwsn/03b-IPv6/icmpv6rpl.h +*** openwsn/03b-IPv6/icmpv6rpl.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/03b-IPv6/icmpv6rpl.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,140 **** +! #ifndef __ICMPv6RPL_H +! #define __ICMPv6RPL_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup ICMPv6RPL +! \{ +! */ +! +! //=========================== define ========================================== +! +! #define TIMER_DIO_TIMEOUT 1700 +! #define TIMER_DAO_TIMEOUT 10000 +! +! #define MOP_DIO_A 1<<5 +! #define MOP_DIO_B 1<<4 +! #define MOP_DIO_C 1<<3 +! #define PRF_DIO_A 0<<2 +! #define PRF_DIO_B 0<<1 +! #define PRF_DIO_C 0<<0 +! #define G_DIO 1<<7 +! +! #define FLAG_DAO_A 0<<0 +! #define FLAG_DAO_B 0<<1 +! #define FLAG_DAO_C 0<<2 +! #define FLAG_DAO_D 0<<3 +! #define FLAG_DAO_E 0<<4 +! #define FLAG_DAO_F 0<<5 +! #define D_DAO 1<<6 +! #define K_DAO 0<<7 +! +! #define E_DAO_Transit_Info 0<<7 +! +! #define PC1_A_DAO_Transit_Info 0<<7 +! #define PC1_B_DAO_Transit_Info 1<<6 +! +! #define PC2_A_DAO_Transit_Info 0<<5 +! #define PC2_B_DAO_Transit_Info 0<<4 +! +! #define PC3_A_DAO_Transit_Info 0<<3 +! #define PC3_B_DAO_Transit_Info 0<<2 +! +! #define PC4_A_DAO_Transit_Info 0<<1 +! #define PC4_B_DAO_Transit_Info 0<<0 +! +! #define Prf_A_dio_options 0<<4 +! #define Prf_B_dio_options 0<<3 +! +! enum{ +! OPTION_ROUTE_INFORMATION_TYPE = 0x03, +! OPTION_DODAG_CONFIGURATION_TYPE = 0x04, +! OPTION_TARGET_INFORMATION_TYPE = 0x05, +! OPTION_TRANSIT_INFORMATION_TYPE = 0x06, +! }; +! +! //=========================== static ========================================== +! +! /** +! \brief Well-known IPv6 multicast address for "all routers". +! */ +! static const uint8_t all_routers_multicast[] = { +! 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 +! }; +! +! //=========================== typedef ========================================= +! +! //===== DIO +! +! /** +! \brief Header format of a RPL DIO packet. +! */ +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t rplinstanceId; ///< set by the DODAG root. +! uint8_t verNumb; +! dagrank_t rank; +! uint8_t rplOptions; +! uint8_t DTSN; +! uint8_t flags; +! uint8_t reserved; +! uint8_t DODAGID[16]; +! } icmpv6rpl_dio_ht; +! PRAGMA(pack()); +! +! //===== DAO +! +! /** +! \brief Header format of a RPL DAO packet. +! */ +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t rplinstanceId; ///< set by the DODAG root. +! uint8_t K_D_flags; +! uint8_t reserved; +! uint8_t DAOSequance; +! uint8_t DODAGID[16]; +! } icmpv6rpl_dao_ht; +! PRAGMA(pack()); +! +! /** +! \brief Header format of a RPL DAO "Transit Information" option. +! */ +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t type; ///< set by the DODAG root. +! uint8_t optionLength; +! uint8_t E_flags; +! uint8_t PathControl; +! uint8_t PathSequence; +! uint8_t PathLifetime; +! } icmpv6rpl_dao_transit_ht; +! PRAGMA(pack()); +! +! /** +! \brief Header format of a RPL DAO "Target" option. +! */ +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t type; ///< set by the DODAG root. +! uint8_t optionLength; +! uint8_t flags; +! uint8_t prefixLength; +! } icmpv6rpl_dao_target_ht; +! PRAGMA(pack()); +! +! +! //=========================== prototypes ====================================== +! +! void icmpv6rpl_init(); +! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, error_t error); +! void icmpv6rpl_receive(OpenQueueEntry_t* msg); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,167 ---- +! #ifndef __ICMPv6RPL_H +! #define __ICMPv6RPL_H +! +! /** +! \addtogroup IPv6 +! \{ +! \addtogroup ICMPv6RPL +! \{ +! */ +! +! #include "opentimers.h" +! +! //=========================== define ========================================== +! +! #define TIMER_DIO_TIMEOUT 1700 +! #define TIMER_DAO_TIMEOUT 10000 +! +! #define MOP_DIO_A 1<<5 +! #define MOP_DIO_B 1<<4 +! #define MOP_DIO_C 1<<3 +! #define PRF_DIO_A 0<<2 +! #define PRF_DIO_B 0<<1 +! #define PRF_DIO_C 0<<0 +! #define G_DIO 1<<7 +! +! #define FLAG_DAO_A 0<<0 +! #define FLAG_DAO_B 0<<1 +! #define FLAG_DAO_C 0<<2 +! #define FLAG_DAO_D 0<<3 +! #define FLAG_DAO_E 0<<4 +! #define FLAG_DAO_F 0<<5 +! #define D_DAO 1<<6 +! #define K_DAO 0<<7 +! +! #define E_DAO_Transit_Info 0<<7 +! +! #define PC1_A_DAO_Transit_Info 0<<7 +! #define PC1_B_DAO_Transit_Info 1<<6 +! +! #define PC2_A_DAO_Transit_Info 0<<5 +! #define PC2_B_DAO_Transit_Info 0<<4 +! +! #define PC3_A_DAO_Transit_Info 0<<3 +! #define PC3_B_DAO_Transit_Info 0<<2 +! +! #define PC4_A_DAO_Transit_Info 0<<1 +! #define PC4_B_DAO_Transit_Info 0<<0 +! +! #define Prf_A_dio_options 0<<4 +! #define Prf_B_dio_options 0<<3 +! +! // max number of parents and children to send in DAO +! //section 8.2.1 pag 67 RFC6550 -- using a subset +! #define MAX_TARGET_PARENTS 0x01 +! +! enum{ +! OPTION_ROUTE_INFORMATION_TYPE = 0x03, +! OPTION_DODAG_CONFIGURATION_TYPE = 0x04, +! OPTION_TARGET_INFORMATION_TYPE = 0x05, +! OPTION_TRANSIT_INFORMATION_TYPE = 0x06, +! }; +! +! //=========================== static ========================================== +! +! /** +! \brief Well-known IPv6 multicast address for "all routers". +! */ +! static const uint8_t all_routers_multicast[] = { +! 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 +! }; +! +! //=========================== typedef ========================================= +! +! //===== DIO +! +! /** +! \brief Header format of a RPL DIO packet. +! */ +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t rplinstanceId; ///< set by the DODAG root. +! uint8_t verNumb; +! dagrank_t rank; +! uint8_t rplOptions; +! uint8_t DTSN; +! uint8_t flags; +! uint8_t reserved; +! uint8_t DODAGID[16]; +! } icmpv6rpl_dio_ht; +! //PRAGMA(pack()); +! +! //===== DAO +! +! /** +! \brief Header format of a RPL DAO packet. +! */ +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t rplinstanceId; ///< set by the DODAG root. +! uint8_t K_D_flags; +! uint8_t reserved; +! uint8_t DAOSequence; +! uint8_t DODAGID[16]; +! } icmpv6rpl_dao_ht; +! //PRAGMA(pack()); +! +! /** +! \brief Header format of a RPL DAO "Transit Information" option. +! */ +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t type; ///< set by the DODAG root. +! uint8_t optionLength; +! uint8_t E_flags; +! uint8_t PathControl; +! uint8_t PathSequence; +! uint8_t PathLifetime; +! } icmpv6rpl_dao_transit_ht; +! //PRAGMA(pack()); +! +! /** +! \brief Header format of a RPL DAO "Target" option. +! */ +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t type; ///< set by the DODAG root. +! uint8_t optionLength; +! uint8_t flags; +! uint8_t prefixLength; +! } icmpv6rpl_dao_target_ht; +! //PRAGMA(pack()); +! +! //=========================== module 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; +! +! //=========================== prototypes ====================================== +! +! void icmpv6rpl_init(void); +! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void icmpv6rpl_receive(OpenQueueEntry_t* msg); +! uint8_t icmpv6rpl_getRPLIntanceID(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/04-TRAN/Makefile ../../../sys/net/openwsn/04-TRAN/Makefile +*** openwsn/04-TRAN/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/04-TRAN/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,42 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/07-APP/ohlone ++ INCLUDES += -I$(CURDIR)/07-APP/tcpecho ++ INCLUDES += -I$(CURDIR)/07-APP/tcpinject ++ INCLUDES += -I$(CURDIR)/07-APP/tcpprint ++ INCLUDES += -I$(CURDIR)/07-APP/udpecho ++ INCLUDES += -I$(CURDIR)/07-APP/udpinject ++ INCLUDES += -I$(CURDIR)/07-APP/udplatency ++ INCLUDES += -I$(CURDIR)/07-APP/udpprint ++ INCLUDES += -I$(CURDIR)/07-APP/udprand ++ INCLUDES += -I$(CURDIR)/07-APP/udpstorm ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBMOD) ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/04-TRAN/opencoap.c ../../../sys/net/openwsn/04-TRAN/opencoap.c +*** openwsn/04-TRAN/opencoap.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/opencoap.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,335 **** +! #include "openwsn.h" +! #include "opencoap.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "opentimers.h" +! #include "scheduler.h" +! +! //=========================== variables ======================================= +! +! // general variable to the CoAP core +! typedef struct { +! coap_resource_desc_t* resources; +! bool busySending; +! uint8_t delayCounter; +! uint16_t messageID; +! opentimer_id_t timerId; +! } opencoap_vars_t; +! +! opencoap_vars_t opencoap_vars; +! +! //=========================== prototype ======================================= +! +! void icmpv6coap_timer_cb(); +! +! //=========================== public ========================================== +! +! //===== from stack +! +! void opencoap_init() { +! // initialize the resource linked list +! opencoap_vars.resources = NULL; +! +! // initialize the messageID +! opencoap_vars.messageID = openrandom_get16b(); +! +! // start the timer +! if (idmanager_getIsDAGroot()==FALSE) { +! opencoap_vars.timerId = opentimers_start(1000, +! TIMER_PERIODIC,TIME_MS, +! icmpv6coap_timer_cb); +! } +! } +! +! void opencoap_receive(OpenQueueEntry_t* msg) { +! uint16_t temp_l4_destination_port; +! uint8_t i; +! uint8_t index; +! coap_option_t last_option; +! coap_resource_desc_t* temp_desc; +! bool found; +! error_t outcome; +! // local variables passed to the handlers (with msg) +! coap_header_iht coap_header; +! coap_option_iht coap_options[MAX_COAP_OPTIONS]; +! +! // take ownership over the received packet +! msg->owner = COMPONENT_OPENCOAP; +! +! //=== step 1. parse the packet +! +! // parse the CoAP header and remove from packet +! index = 0; +! coap_header.Ver = (msg->payload[index] & 0xc0) >> 6; +! coap_header.T = (coap_type_t)((msg->payload[index] & 0x30) >> 4); +! coap_header.OC = (msg->payload[index] & 0x0f); +! index++; +! coap_header.Code = (coap_code_t)(msg->payload[index]); +! index++; +! coap_header.messageID = msg->payload[index]*256+msg->payload[index+1]; +! index+=2; +! // reject unsupported header +! if ( +! coap_header.Ver!=COAP_VERSION || +! coap_header.OC>MAX_COAP_OPTIONS +! ) { +! openserial_printError(COMPONENT_OPENCOAP,ERR_6LOWPAN_UNSUPPORTED, +! (errorparameter_t)0, +! (errorparameter_t)coap_header.Ver); +! openqueue_freePacketBuffer(msg); +! return; +! } +! // initialize the coap_options +! for (i=0;ipayload[index] & 0xf0) >> 4)); +! last_option = coap_options[i].type; +! coap_options[i].length = (msg->payload[index] & 0x0f); +! index++; +! coap_options[i].pValue = &(msg->payload[index]); +! index += coap_options[i].length; +! } +! // remove the CoAP header+options +! packetfunctions_tossHeader(msg,index); +! +! //=== step 2. find the resource to handle the packet +! +! // find the resource this applies to +! found = FALSE; +! if (coap_header.Code>=COAP_CODE_REQ_GET && +! coap_header.Code<=COAP_CODE_REQ_DELETE) { +! // this is a request: target resource is indicated as COAP_OPTION_LOCATIONPATH option(s) +! +! // find the resource which matches +! temp_desc = opencoap_vars.resources; +! while (found==FALSE) { +! if ( +! coap_options[0].type==COAP_OPTION_URIPATH && +! coap_options[1].type==COAP_OPTION_URIPATH && +! temp_desc->path0len>0 && +! temp_desc->path0val!=NULL && +! temp_desc->path1len>0 && +! temp_desc->path1val!=NULL +! ) { +! // resource has a path of form path0/path1 +! +! if ( +! coap_options[0].length==temp_desc->path0len && +! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 && +! coap_options[1].length==temp_desc->path1len && +! memcmp(coap_options[1].pValue,temp_desc->path1val,temp_desc->path1len)==0 +! ) { +! found = TRUE; +! }; +! } else if ( +! coap_options[0].type==COAP_OPTION_URIPATH && +! temp_desc->path0len>0 && +! temp_desc->path0val!=NULL +! ) { +! // resource has a path of form path0 +! +! if ( +! coap_options[0].length==temp_desc->path0len && +! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 +! ) { +! found = TRUE; +! }; +! }; +! // iterate to next resource +! if (found==FALSE) { +! if (temp_desc->next!=NULL) { +! temp_desc = temp_desc->next; +! } else { +! break; +! } +! } +! }; +! } else { +! // this is a response: target resource is indicated by message ID +! +! // find the resource which matches +! temp_desc = opencoap_vars.resources; +! while (found==FALSE) { +! if (coap_header.messageID==temp_desc->messageID) { +! found=TRUE; +! if (temp_desc->callbackRx!=NULL) { +! temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); +! } +! } +! // iterate to next resource +! if (found==FALSE) { +! if (temp_desc->next!=NULL) { +! temp_desc = temp_desc->next; +! } else { +! break; +! } +! } +! }; +! openqueue_freePacketBuffer(msg); +! // stop here: will will not respond to a response +! return; +! } +! +! //=== step 3. ask the resource to prepare response +! +! if (found==TRUE) { +! outcome = temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); +! } else { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! // set the CoAP header +! coap_header.OC = 0; +! coap_header.Code = COAP_CODE_RESP_NOTFOUND; +! } +! +! if (outcome==E_FAIL) { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! // set the CoAP header +! coap_header.OC = 0; +! coap_header.Code = COAP_CODE_RESP_METHODNOTALLOWED; +! } +! +! //=== step 4. send that packet back +! +! // fill in packet metadata +! if (found==TRUE) { +! msg->creator = temp_desc->componentID; +! } else { +! msg->creator = COMPONENT_OPENCOAP; +! } +! msg->l4_protocol = IANA_UDP; +! temp_l4_destination_port = msg->l4_destination_port; +! msg->l4_destination_port = msg->l4_sourcePortORicmpv6Type; +! msg->l4_sourcePortORicmpv6Type = temp_l4_destination_port; +! +! // fill in CoAP header +! packetfunctions_reserveHeaderSize(msg,4); +! msg->payload[0] = (COAP_VERSION << 6) | +! (COAP_TYPE_ACK << 4) | +! (coap_header.OC << 0); +! msg->payload[1] = coap_header.Code; +! msg->payload[2] = coap_header.messageID/256; +! msg->payload[3] = coap_header.messageID%256; +! +! if ((openudp_send(msg))==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } +! +! void opencoap_sendDone(OpenQueueEntry_t* msg, error_t error) { +! coap_resource_desc_t* temp_resource; +! +! // take ownership over that packet +! msg->owner = COMPONENT_OPENCOAP; +! +! // indicate sendDone to creator of that packet +! //=== mine +! if (msg->creator==COMPONENT_OPENCOAP) { +! openqueue_freePacketBuffer(msg); +! return; +! } +! //=== someone else's +! temp_resource = opencoap_vars.resources; +! while (temp_resource!=NULL) { +! if (temp_resource->componentID==msg->creator && +! temp_resource->callbackSendDone!=NULL) { +! temp_resource->callbackSendDone(msg,error); +! return; +! } +! temp_resource = temp_resource->next; +! } +! +! openserial_printError(COMPONENT_OPENCOAP,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! +! void timers_coap_fired() { +! //do something here if necessary +! } +! +! //===== from CoAP resources +! +! void opencoap_writeLinks(OpenQueueEntry_t* msg) { +! coap_resource_desc_t* temp_resource; +! +! temp_resource = opencoap_vars.resources; +! while (temp_resource!=NULL) { +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '>'; +! if (temp_resource->path1len>0) { +! packetfunctions_reserveHeaderSize(msg,temp_resource->path1len); +! memcpy(&msg->payload[0],temp_resource->path1val,temp_resource->path1len); +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '/'; +! } +! packetfunctions_reserveHeaderSize(msg,temp_resource->path0len); +! memcpy(msg->payload,temp_resource->path0val,temp_resource->path0len); +! packetfunctions_reserveHeaderSize(msg,2); +! msg->payload[1] = '/'; +! msg->payload[0] = '<'; +! if (temp_resource->next!=NULL) { +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = ','; +! } +! temp_resource = temp_resource->next; +! } +! } +! +! void opencoap_register(coap_resource_desc_t* desc) { +! coap_resource_desc_t* last_elem; +! +! if (opencoap_vars.resources==NULL) { +! opencoap_vars.resources = desc; +! return; +! } +! +! // add to the end of the resource linked list +! last_elem = opencoap_vars.resources; +! while (last_elem->next!=NULL) { +! last_elem = last_elem->next; +! } +! last_elem->next = desc; +! } +! +! error_t opencoap_send(OpenQueueEntry_t* msg, +! coap_type_t type, +! coap_code_t code, +! uint8_t numOptions, +! coap_resource_desc_t* descSender) { +! // change the global messageID +! opencoap_vars.messageID = openrandom_get16b(); +! // take ownership +! msg->owner = COMPONENT_OPENCOAP; +! // metadata +! msg->l4_sourcePortORicmpv6Type = WKP_UDP_COAP; +! // fill in CoAP header +! packetfunctions_reserveHeaderSize(msg,4); +! msg->payload[0] = (COAP_VERSION << 6) | +! (type << 4) | +! (numOptions << 0); +! msg->payload[1] = code; +! msg->payload[2] = (opencoap_vars.messageID>>8) & 0xff; +! msg->payload[3] = (opencoap_vars.messageID>>0) & 0xff; +! // record the messageID with this sender +! descSender->messageID = opencoap_vars.messageID; +! return openudp_send(msg); +! } +! +! //=========================== private ========================================= +! +! void icmpv6coap_timer_cb() { +! scheduler_push_task(timers_coap_fired,TASKPRIO_COAP); + } +\ No newline at end of file +--- 1,364 ---- +! #include "openwsn.h" +! #include "opencoap.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "packetfunctions.h" +! #include "idmanager.h" +! #include "opentimers.h" +! #include "scheduler.h" +! +! #include "thread.h" +! +! //=========================== variables ======================================= +! +! opencoap_vars_t opencoap_vars; +! //static char openwsn_coap_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! +! //=========================== prototype ======================================= +! +! void icmpv6coap_timer_cb(void); +! +! //=========================== public ========================================== +! +! //===== from stack +! +! void opencoap_init(void) { +! // initialize the resource linked list +! opencoap_vars.resources = NULL; +! +! // initialize the messageID +! opencoap_vars.messageID = openrandom_get16b(); +! +! // start the timer +! if (idmanager_getIsDAGroot()==FALSE) { +! opencoap_vars.timerId = opentimers_start(1000, +! TIMER_PERIODIC,TIME_MS, +! icmpv6coap_timer_cb); +! } +! } +! +! void opencoap_receive(OpenQueueEntry_t* msg) { +! uint16_t temp_l4_destination_port; +! uint8_t i; +! uint8_t index; +! coap_option_t last_option; +! coap_resource_desc_t* temp_desc; +! bool found; +! owerror_t outcome = 0; +! // local variables passed to the handlers (with msg) +! coap_header_iht coap_header; +! coap_option_iht coap_options[MAX_COAP_OPTIONS]; +! +! // take ownership over the received packet +! msg->owner = COMPONENT_OPENCOAP; +! +! //=== step 1. parse the packet +! +! // parse the CoAP header and remove from packet +! index = 0; +! coap_header.Ver = (msg->payload[index] & 0xc0) >> 6; +! coap_header.T = (coap_type_t)((msg->payload[index] & 0x30) >> 4); +! coap_header.TKL = (msg->payload[index] & 0x0f); +! index++; +! coap_header.Code = (coap_code_t)(msg->payload[index]); +! index++; +! coap_header.messageID = msg->payload[index]*256+msg->payload[index+1]; +! index+=2; +! +! //poipoi xv. TKL tells us the length of the token. If we want to support tokens longer +! //than one token needs to be converted to an array and memcopy here for the length of TKL +! coap_header.token = (msg->payload[index]); +! index+=coap_header.TKL; +! +! +! // reject unsupported header +! if (coap_header.Ver!=COAP_VERSION || coap_header.TKL>8) { +! openserial_printError(COMPONENT_OPENCOAP,ERR_WRONG_TRAN_PROTOCOL, +! (errorparameter_t)0, +! (errorparameter_t)coap_header.Ver); +! openqueue_freePacketBuffer(msg); +! return; +! } +! // initialize the coap_options +! for (i=0;ipayload[index]==0xFF){ +! //found the payload spacer, options are already parsed. +! index++; //skip it and break. +! break; +! } +! coap_options[i].type = (coap_option_t)((uint8_t)last_option+(uint8_t)((msg->payload[index] & 0xf0) >> 4)); +! last_option = coap_options[i].type; +! coap_options[i].length = (msg->payload[index] & 0x0f); +! index++; +! coap_options[i].pValue = &(msg->payload[index]); +! index += coap_options[i].length; //includes length as well +! } +! +! // remove the CoAP header+options +! packetfunctions_tossHeader(msg,index); +! +! //=== step 2. find the resource to handle the packet +! +! // find the resource this applies to +! found = FALSE; +! if (coap_header.Code>=COAP_CODE_REQ_GET && +! coap_header.Code<=COAP_CODE_REQ_DELETE) { +! // this is a request: target resource is indicated as COAP_OPTION_LOCATIONPATH option(s) +! +! // find the resource which matches +! temp_desc = opencoap_vars.resources; +! while (found==FALSE) { +! if ( +! coap_options[0].type==COAP_OPTION_NUM_URIPATH && +! coap_options[1].type==COAP_OPTION_NUM_URIPATH && +! temp_desc->path0len>0 && +! temp_desc->path0val!=NULL && +! temp_desc->path1len>0 && +! temp_desc->path1val!=NULL +! ) { +! // resource has a path of form path0/path1 +! +! if ( +! coap_options[0].length==temp_desc->path0len && +! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 && +! coap_options[1].length==temp_desc->path1len && +! memcmp(coap_options[1].pValue,temp_desc->path1val,temp_desc->path1len)==0 +! ) { +! found = TRUE; +! }; +! } else if ( +! coap_options[0].type==COAP_OPTION_NUM_URIPATH && +! temp_desc->path0len>0 && +! temp_desc->path0val!=NULL +! ) { +! // resource has a path of form path0 +! +! if ( +! coap_options[0].length==temp_desc->path0len && +! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 +! ) { +! found = TRUE; +! }; +! }; +! // iterate to next resource +! if (found==FALSE) { +! if (temp_desc->next!=NULL) { +! temp_desc = temp_desc->next; +! } else { +! break; +! } +! } +! }; +! } else { +! // this is a response: target resource is indicated by message ID +! +! // find the resource which matches +! temp_desc = opencoap_vars.resources; +! while (found==FALSE) { +! if (coap_header.messageID==temp_desc->messageID) { +! found=TRUE; +! if (temp_desc->callbackRx!=NULL) { +! temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); +! } +! } +! // iterate to next resource +! if (found==FALSE) { +! if (temp_desc->next!=NULL) { +! temp_desc = temp_desc->next; +! } else { +! break; +! } +! } +! }; +! openqueue_freePacketBuffer(msg); +! // stop here: will will not respond to a response +! return; +! } +! +! //=== step 3. ask the resource to prepare response +! +! if (found==TRUE) { +! outcome = temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); +! } else { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! // set the CoAP header +! coap_header.TKL = 0; +! coap_header.Code = COAP_CODE_RESP_NOTFOUND; +! } +! +! if (outcome==E_FAIL) { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! // set the CoAP header +! coap_header.TKL = 0; +! coap_header.Code = COAP_CODE_RESP_METHODNOTALLOWED; +! } +! +! //=== step 4. send that packet back +! +! // fill in packet metadata +! if (found==TRUE) { +! msg->creator = temp_desc->componentID; +! } else { +! msg->creator = COMPONENT_OPENCOAP; +! } +! msg->l4_protocol = IANA_UDP; +! temp_l4_destination_port = msg->l4_destination_port; +! msg->l4_destination_port = msg->l4_sourcePortORicmpv6Type; +! msg->l4_sourcePortORicmpv6Type = temp_l4_destination_port; +! +! //set destination address as the current source. +! msg->l3_destinationAdd.type = ADDR_128B; +! memcpy(&msg->l3_destinationAdd.addr_128b[0],&msg->l3_sourceAdd.addr_128b[0],LENGTH_ADDR128b); +! +! +! // fill in CoAP header +! packetfunctions_reserveHeaderSize(msg,5); +! msg->payload[0] = (COAP_VERSION << 6) | +! (COAP_TYPE_ACK << 4) | +! (coap_header.TKL << 0); +! msg->payload[1] = coap_header.Code; +! msg->payload[2] = coap_header.messageID/256; +! msg->payload[3] = coap_header.messageID%256; +! msg->payload[4] = coap_header.token; //this will be a memcopy for TKL size +! +! if ((openudp_send(msg))==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } +! +! void opencoap_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! coap_resource_desc_t* temp_resource; +! +! // take ownership over that packet +! msg->owner = COMPONENT_OPENCOAP; +! +! // indicate sendDone to creator of that packet +! //=== mine +! if (msg->creator==COMPONENT_OPENCOAP) { +! openqueue_freePacketBuffer(msg); +! return; +! } +! //=== someone else's +! temp_resource = opencoap_vars.resources; +! while (temp_resource!=NULL) { +! if (temp_resource->componentID==msg->creator && +! temp_resource->callbackSendDone!=NULL) { +! temp_resource->callbackSendDone(msg,error); +! return; +! } +! temp_resource = temp_resource->next; +! } +! +! openserial_printError(COMPONENT_OPENCOAP,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! +! void timers_coap_fired(void) { +! //do something here if necessary +! } +! +! //===== from CoAP resources +! +! void opencoap_writeLinks(OpenQueueEntry_t* msg) { +! coap_resource_desc_t* temp_resource; +! +! temp_resource = opencoap_vars.resources; +! while (temp_resource!=NULL) { +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '>'; +! if (temp_resource->path1len>0) { +! packetfunctions_reserveHeaderSize(msg,temp_resource->path1len); +! memcpy(&msg->payload[0],temp_resource->path1val,temp_resource->path1len); +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '/'; +! } +! packetfunctions_reserveHeaderSize(msg,temp_resource->path0len); +! memcpy(msg->payload,temp_resource->path0val,temp_resource->path0len); +! packetfunctions_reserveHeaderSize(msg,2); +! msg->payload[1] = '/'; +! msg->payload[0] = '<'; +! if (temp_resource->next!=NULL) { +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = ','; +! } +! temp_resource = temp_resource->next; +! } +! } +! +! /** +! \brief Register a new CoAP resource. +! +! Registration consists in adding a new resource at the end of the linked list +! of resources. +! */ +! void opencoap_register(coap_resource_desc_t* desc) { +! coap_resource_desc_t* last_elem; +! +! // since this CoAP resource will be at the end of the list, its next element +! // should point to NULL, indicating the end of the linked list. +! desc->next = NULL; +! +! if (opencoap_vars.resources==NULL) { +! opencoap_vars.resources = desc; +! return; +! } +! +! // add to the end of the resource linked list +! last_elem = opencoap_vars.resources; +! while (last_elem->next!=NULL) { +! last_elem = last_elem->next; +! } +! last_elem->next = desc; +! } +! +! owerror_t opencoap_send(OpenQueueEntry_t* msg, +! coap_type_t type, +! coap_code_t code, +! uint8_t TKL, +! coap_resource_desc_t* descSender) { +! // change the global messageID +! opencoap_vars.messageID = openrandom_get16b(); +! // take ownership +! msg->owner = COMPONENT_OPENCOAP; +! // metadata +! msg->l4_sourcePortORicmpv6Type = WKP_UDP_COAP; +! // fill in CoAP header +! packetfunctions_reserveHeaderSize(msg,5); +! msg->payload[0] = (COAP_VERSION << 6) | +! (type << 4) | +! (TKL << 0); +! msg->payload[1] = code; +! msg->payload[2] = (opencoap_vars.messageID>>8) & 0xff; +! msg->payload[3] = (opencoap_vars.messageID>>0) & 0xff; +! //poipoi xv token needs to be defined by the app or here +! #define TOKEN 123 +! msg->payload[4] = TOKEN; //this will be a memcopy for TKL size +! +! // record the messageID with this sender +! descSender->messageID = opencoap_vars.messageID; +! descSender->token = TOKEN; +! +! return openudp_send(msg); +! } +! +! //=========================== private ========================================= +! +! void icmpv6coap_timer_cb(void) { +! scheduler_push_task(timers_coap_fired,TASKPRIO_COAP); +! /*thread_create(openwsn_coap_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_COAP, CREATE_STACKTEST, +! timers_coap_fired, "timers coap fired");*/ + } +\ No newline at end of file +diff -crB openwsn/04-TRAN/opencoap.h ../../../sys/net/openwsn/04-TRAN/opencoap.h +*** openwsn/04-TRAN/opencoap.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/opencoap.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,161 **** +! #ifndef __OPENCOAP_H +! #define __OPENCOAP_H +! +! /** +! \addtogroup Transport +! \{ +! \addtogroup openCoap +! \{ +! */ +! +! //=========================== define ========================================== +! +! // IPv6 addresses of servers on the Internet +! static const uint8_t ipAddr_ipsoRD[] = {0x26, 0x07, 0xf7, 0x40, 0x00, 0x00, 0x00, 0x3f, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x29}; +! static const uint8_t ipAddr_motesEecs[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x19, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +! //static const uint8_t ipAddr_local[] = {0x20, 0x02, 0x80, 0x20, 0x21, 0x47, 0x00, 0x0c, \ +! 0x10, 0xcb, 0xc6, 0x52, 0x44, 0x17, 0xd4, 0x18}; +! // 2607:f140:400:1036:688e:fa3b:444:6211 +! //static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ +! // 0x68, 0x8e, 0xfa, 0x3b, 0x04, 0x44, 0x62, 0x11}; +! +! static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ +! 0x4d, 0xcd, 0xab, 0x54, 0x81, 0x99, 0xc1, 0xf7}; +! +! static const uint8_t ipAddr_motedata[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x17, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +! +! /// the maximum number of options in a RX'ed CoAP message +! #define MAX_COAP_OPTIONS 3 +! +! #define COAP_VERSION 1 +! +! typedef enum { +! COAP_TYPE_CON = 0, +! COAP_TYPE_NON = 1, +! COAP_TYPE_ACK = 2, +! COAP_TYPE_RES = 3, +! } coap_type_t; +! +! typedef enum { +! COAP_CODE_EMPTY = 0, +! // request +! COAP_CODE_REQ_GET = 1, +! COAP_CODE_REQ_POST = 2, +! COAP_CODE_REQ_PUT = 3, +! COAP_CODE_REQ_DELETE = 4, +! // response +! // - OK +! COAP_CODE_RESP_CREATED = 65, +! COAP_CODE_RESP_DELETED = 66, +! COAP_CODE_RESP_VALID = 67, +! COAP_CODE_RESP_CHANGED = 68, +! COAP_CODE_RESP_CONTENT = 69, +! // - not OK +! COAP_CODE_RESP_BADREQ = 128, +! COAP_CODE_RESP_UNAUTHORIZED = 129, +! COAP_CODE_RESP_BADOPTION = 130, +! COAP_CODE_RESP_FORBIDDEN = 131, +! COAP_CODE_RESP_NOTFOUND = 132, +! COAP_CODE_RESP_METHODNOTALLOWED = 133, +! COAP_CODE_RESP_PRECONDFAILED = 140, +! COAP_CODE_RESP_REQTOOLARGE = 141, +! COAP_CODE_RESP_UNSUPPMEDIATYPE = 143, +! // - error +! COAP_CODE_RESP_SERVERERROR = 160, +! COAP_CODE_RESP_NOTIMPLEMENTED = 161, +! COAP_CODE_RESP_BADGATEWAY = 162, +! COAP_CODE_RESP_UNAVAILABLE = 163, +! COAP_CODE_RESP_GWTIMEOUT = 164, +! COAP_CODE_RESP_PROXYINGNOTSUPP = 165, +! } coap_code_t; +! +! typedef enum { +! COAP_OPTION_NONE = 0, +! COAP_OPTION_CONTENTTYPE = 1, +! COAP_OPTION_MAXAGE = 2, +! COAP_OPTION_PROXYURI = 3, +! COAP_OPTION_ETAG = 4, +! COAP_OPTION_URIHOST = 5, +! COAP_OPTION_LOCATIONPATH = 6, +! COAP_OPTION_URIPORT = 7, +! COAP_OPTION_LOCATIONQUERY = 8, +! COAP_OPTION_URIPATH = 9, +! COAP_OPTION_TOKEN = 11, +! COAP_OPTION_ACCEPT = 12, +! COAP_OPTION_IFMATCH = 13, +! COAP_OPTION_URIQUERY = 15, +! COAP_OPTION_IFNONEMATCH = 21, +! } coap_option_t; +! +! typedef enum { +! COAP_MEDTYPE_TEXTPLAIN = 0, +! COAP_MEDTYPE_APPLINKFORMAT = 40, +! COAP_MEDTYPE_APPXML = 41, +! COAP_MEDTYPE_APPOCTETSTREAM = 42, +! COAP_MEDTYPE_APPEXI = 47, +! COAP_MEDTYPE_APPJSON = 50, +! } coap_media_type_t; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t Ver; +! coap_type_t T; +! uint8_t OC; +! coap_code_t Code; +! uint16_t messageID; +! } coap_header_iht; +! +! typedef struct { +! coap_option_t type; +! uint8_t length; +! uint8_t* pValue; +! } coap_option_iht; +! +! typedef error_t (*callbackRx_t)(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! typedef void (*callbackTimer_t)(void); +! typedef void (*callbackSendDone_t)(OpenQueueEntry_t* msg, error_t error); +! +! typedef struct coap_resource_desc_t coap_resource_desc_t; +! +! struct coap_resource_desc_t { +! uint8_t path0len; +! uint8_t* path0val; +! uint8_t path1len; +! uint8_t* path1val; +! uint8_t componentID; +! uint16_t messageID; +! callbackRx_t callbackRx; +! callbackSendDone_t callbackSendDone; +! coap_resource_desc_t* next; +! }; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // from stack +! void opencoap_init(); +! void opencoap_receive(OpenQueueEntry_t* msg); +! void opencoap_sendDone(OpenQueueEntry_t* msg, error_t error); +! +! // from CoAP resources +! void opencoap_writeLinks(OpenQueueEntry_t* msg); +! void opencoap_register(coap_resource_desc_t* desc); +! error_t opencoap_send(OpenQueueEntry_t* msg, +! coap_type_t type, +! coap_code_t code, +! uint8_t numOptions, +! coap_resource_desc_t* descSender); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,175 ---- +! #ifndef __OPENCOAP_H +! #define __OPENCOAP_H +! +! /** +! \addtogroup Transport +! \{ +! \addtogroup openCoap +! \{ +! */ +! +! #include "opentimers.h" +! +! //=========================== define ========================================== +! +! // IPv6 addresses of servers on the Internet +! static const uint8_t ipAddr_ipsoRD[] = {0x26, 0x07, 0xf7, 0x40, 0x00, 0x00, 0x00, 0x3f, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x29}; +! static const uint8_t ipAddr_motesEecs[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x19, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +! /*static const uint8_t ipAddr_local[] = {0x20, 0x02, 0x80, 0x20, 0x21, 0x47, 0x00, 0x0c, \ +! 0x10, 0xcb, 0xc6, 0x52, 0x44, 0x17, 0xd4, 0x18}; +! // 2607:f140:400:1036:688e:fa3b:444:6211 +! //static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ +! // 0x68, 0x8e, 0xfa, 0x3b, 0x04, 0x44, 0x62, 0x11}; +! */ +! static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ +! 0x4d, 0xcd, 0xab, 0x54, 0x81, 0x99, 0xc1, 0xf7}; +! +! static const uint8_t ipAddr_motedata[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x17, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; +! +! /// the maximum number of options in a RX'ed CoAP message +! #define MAX_COAP_OPTIONS 10 //3 before but we want gets with more options +! +! #define COAP_VERSION 1 +! +! typedef enum { +! COAP_TYPE_CON = 0, +! COAP_TYPE_NON = 1, +! COAP_TYPE_ACK = 2, +! COAP_TYPE_RES = 3, +! } coap_type_t; +! +! typedef enum { +! COAP_CODE_EMPTY = 0, +! // request +! COAP_CODE_REQ_GET = 1, +! COAP_CODE_REQ_POST = 2, +! COAP_CODE_REQ_PUT = 3, +! COAP_CODE_REQ_DELETE = 4, +! // response +! // - OK +! COAP_CODE_RESP_CREATED = 65, +! COAP_CODE_RESP_DELETED = 66, +! COAP_CODE_RESP_VALID = 67, +! COAP_CODE_RESP_CHANGED = 68, +! COAP_CODE_RESP_CONTENT = 69, +! // - not OK +! COAP_CODE_RESP_BADREQ = 128, +! COAP_CODE_RESP_UNAUTHORIZED = 129, +! COAP_CODE_RESP_BADOPTION = 130, +! COAP_CODE_RESP_FORBIDDEN = 131, +! COAP_CODE_RESP_NOTFOUND = 132, +! COAP_CODE_RESP_METHODNOTALLOWED = 133, +! COAP_CODE_RESP_PRECONDFAILED = 140, +! COAP_CODE_RESP_REQTOOLARGE = 141, +! COAP_CODE_RESP_UNSUPPMEDIATYPE = 143, +! // - error +! COAP_CODE_RESP_SERVERERROR = 160, +! COAP_CODE_RESP_NOTIMPLEMENTED = 161, +! COAP_CODE_RESP_BADGATEWAY = 162, +! COAP_CODE_RESP_UNAVAILABLE = 163, +! COAP_CODE_RESP_GWTIMEOUT = 164, +! COAP_CODE_RESP_PROXYINGNOTSUPP = 165, +! } coap_code_t; +! +! typedef enum { +! COAP_OPTION_NONE = 0, +! COAP_OPTION_NUM_IFMATCH = 1, +! COAP_OPTION_NUM_URIHOST = 3, +! COAP_OPTION_NUM_ETAG = 4, +! COAP_OPTION_NUM_IFNONEMATCH = 5, +! COAP_OPTION_NUM_URIPORT = 7, +! COAP_OPTION_NUM_LOCATIONPATH = 8, +! COAP_OPTION_NUM_URIPATH = 11, +! COAP_OPTION_NUM_CONTENTFORMAT = 12, +! COAP_OPTION_NUM_MAXAGE = 14, +! COAP_OPTION_NUM_URIQUERY = 15, +! COAP_OPTION_NUM_ACCEPT = 16, +! COAP_OPTION_NUM_LOCATIONQUERY = 20, +! COAP_OPTION_NUM_PROXYURI = 35, +! COAP_OPTION_NUM_PROXYSCHEME = 39, +! } coap_option_t; +! +! +! +! typedef enum { +! COAP_MEDTYPE_TEXTPLAIN = 0, +! COAP_MEDTYPE_APPLINKFORMAT = 40, +! COAP_MEDTYPE_APPXML = 41, +! COAP_MEDTYPE_APPOCTETSTREAM = 42, +! COAP_MEDTYPE_APPEXI = 47, +! COAP_MEDTYPE_APPJSON = 50, +! } coap_media_type_t; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t Ver; +! coap_type_t T; +! uint8_t TKL; +! coap_code_t Code; +! uint16_t messageID; +! uint8_t token; //this might be an array of 8 as tkl can be 8 +! } coap_header_iht; +! +! typedef struct { +! coap_option_t type; +! uint8_t length; +! uint8_t* pValue; +! } coap_option_iht; +! +! typedef owerror_t (*callbackRx_cbt)(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! typedef void (*callbackSendDone_cbt)(OpenQueueEntry_t* msg, +! owerror_t error); +! +! typedef struct coap_resource_desc_t coap_resource_desc_t; +! +! struct coap_resource_desc_t { +! uint8_t path0len; +! uint8_t* path0val; +! uint8_t path1len; +! uint8_t* path1val; +! uint8_t componentID; +! uint16_t messageID; +! uint8_t token; //should be 8bytes +! callbackRx_cbt callbackRx; +! callbackSendDone_cbt callbackSendDone; +! coap_resource_desc_t* next; +! }; +! +! //=========================== module variables ================================ +! +! typedef struct { +! coap_resource_desc_t* resources; +! bool busySending; +! uint8_t delayCounter; +! uint16_t messageID; +! opentimer_id_t timerId; +! } opencoap_vars_t; +! +! //=========================== prototypes ====================================== +! +! // from stack +! void opencoap_init(void); +! void opencoap_receive(OpenQueueEntry_t* msg); +! void opencoap_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! +! // from CoAP resources +! void opencoap_writeLinks(OpenQueueEntry_t* msg); +! void opencoap_register(coap_resource_desc_t* desc); +! owerror_t opencoap_send(OpenQueueEntry_t* msg, +! coap_type_t type, +! coap_code_t code, +! uint8_t numOptions, +! coap_resource_desc_t* descSender); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/04-TRAN/opentcp.c ../../../sys/net/openwsn/04-TRAN/opentcp.c +*** openwsn/04-TRAN/opentcp.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/opentcp.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,760 **** +! #include "openwsn.h" +! #include "opentcp.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "forwarding.h" +! #include "packetfunctions.h" +! #include "bsp_timer.h" +! #include "scheduler.h" +! #include "opentimers.h" +! //TCP applications +! #include "ohlone.h" +! #include "tcpecho.h" +! #include "tcpinject.h" +! #include "tcpprint.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! uint8_t state; +! uint32_t mySeqNum; +! uint16_t myPort; +! uint32_t hisNextSeqNum; +! uint16_t hisPort; +! open_addr_t hisIPv6Address; +! OpenQueueEntry_t* dataToSend; +! OpenQueueEntry_t* dataReceived; +! bool timerStarted; +! opentimer_id_t timerId; +! } tcp_vars_t; +! +! tcp_vars_t tcp_vars; +! +! //=========================== prototypes ====================================== +! +! void prependTCPHeader(OpenQueueEntry_t* msg, bool ack, bool push, bool rst, bool syn, bool fin); +! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin); +! void tcp_change_state(uint8_t new_state); +! void reset(); +! void opentcp_timer_cb(); +! +! //=========================== public ========================================== +! +! void opentcp_init() { +! // reset local variables +! memset(&tcp_vars,0,sizeof(tcp_vars_t)); +! // reset state machine +! reset(); +! } +! +! error_t opentcp_connect(open_addr_t* dest, uint16_t param_tcp_hisPort, uint16_t param_tcp_myPort) { +! //[command] establishment +! OpenQueueEntry_t* tempPkt; +! if (tcp_vars.state!=TCP_STATE_CLOSED) { +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)0); +! return E_FAIL; +! } +! tcp_vars.myPort = param_tcp_myPort; +! tcp_vars.hisPort = param_tcp_hisPort; +! memcpy(&tcp_vars.hisIPv6Address,dest,sizeof(open_addr_t)); +! //I receive command 'connect', I send SYNC +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; +! prependTCPHeader(tempPkt, +! TCP_ACK_NO, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_YES, +! TCP_FIN_NO); +! tcp_change_state(TCP_STATE_ALMOST_SYN_SENT); +! return forwarding_send(tempPkt); +! } +! +! error_t opentcp_send(OpenQueueEntry_t* msg) { //[command] data +! msg->owner = COMPONENT_OPENTCP; +! if (tcp_vars.state!=TCP_STATE_ESTABLISHED) { +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)2); +! return E_FAIL; +! } +! if (tcp_vars.dataToSend!=NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_BUSY_SENDING, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! //I receive command 'send', I send data +! msg->l4_protocol = IANA_TCP; +! msg->l4_sourcePortORicmpv6Type = tcp_vars.myPort; +! msg->l4_destination_port = tcp_vars.hisPort; +! msg->l4_payload = msg->payload; +! msg->l4_length = msg->length; +! memcpy(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! tcp_vars.dataToSend = msg; +! prependTCPHeader(tcp_vars.dataToSend, +! TCP_ACK_YES, +! TCP_PSH_YES, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! tcp_vars.mySeqNum += tcp_vars.dataToSend->l4_length; +! tcp_change_state(TCP_STATE_ALMOST_DATA_SENT); +! return forwarding_send(tcp_vars.dataToSend); +! } +! +! void opentcp_sendDone(OpenQueueEntry_t* msg, error_t error) { +! OpenQueueEntry_t* tempPkt; +! msg->owner = COMPONENT_OPENTCP; +! switch (tcp_vars.state) { +! case TCP_STATE_ALMOST_SYN_SENT: //[sendDone] establishement +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_SYN_SENT); +! break; +! +! case TCP_STATE_ALMOST_SYN_RECEIVED: //[sendDone] establishement +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_SYN_RECEIVED); +! break; +! +! case TCP_STATE_ALMOST_ESTABLISHED: //[sendDone] establishement +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_ESTABLISHED); +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_connectDone(E_SUCCESS); +! break; +! case WKP_TCP_ECHO: +! tcpecho_connectDone(E_SUCCESS); +! break; +! case WKP_TCP_INJECT: +! tcpinject_connectDone(E_SUCCESS); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_connectDone(E_SUCCESS); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)0); +! break; +! } +! break; +! +! case TCP_STATE_ALMOST_DATA_SENT: //[sendDone] data +! tcp_change_state(TCP_STATE_DATA_SENT); +! break; +! +! case TCP_STATE_ALMOST_DATA_RECEIVED: //[sendDone] data +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_ESTABLISHED); +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_receive(tcp_vars.dataReceived); +! break; +! case WKP_TCP_ECHO: +! tcpecho_receive(tcp_vars.dataReceived); +! break; +! case WKP_TCP_INJECT: +! tcpinject_receive(tcp_vars.dataReceived); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_receive(tcp_vars.dataReceived); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)1); +! openqueue_freePacketBuffer(msg); +! tcp_vars.dataReceived = NULL; +! break; +! } +! break; +! +! case TCP_STATE_ALMOST_FIN_WAIT_1: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_FIN_WAIT_1); +! break; +! +! case TCP_STATE_ALMOST_CLOSING: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_CLOSING); +! break; +! +! case TCP_STATE_ALMOST_TIME_WAIT: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_TIME_WAIT); +! //TODO implement waiting timer +! reset(); +! break; +! +! case TCP_STATE_ALMOST_CLOSE_WAIT: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_CLOSE_WAIT); +! //I send FIN+ACK +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_YES); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_LAST_ACK); +! break; +! +! case TCP_STATE_ALMOST_LAST_ACK: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_LAST_ACK); +! break; +! +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)3); +! break; +! } +! } +! +! void opentcp_receive(OpenQueueEntry_t* msg) { +! OpenQueueEntry_t* tempPkt; +! bool shouldIlisten; +! msg->owner = COMPONENT_OPENTCP; +! msg->l4_protocol = IANA_TCP; +! msg->l4_payload = msg->payload; +! msg->l4_length = msg->length; +! msg->l4_sourcePortORicmpv6Type = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); +! msg->l4_destination_port = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); +! if ( +! tcp_vars.state!=TCP_STATE_CLOSED && +! ( +! msg->l4_destination_port != tcp_vars.myPort || +! msg->l4_sourcePortORicmpv6Type != tcp_vars.hisPort || +! packetfunctions_sameAddress(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address)==FALSE +! ) +! ) { +! openqueue_freePacketBuffer(msg); +! return; +! } +! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_YES,TCP_SYN_WHATEVER,TCP_FIN_WHATEVER)) { +! //I receive RST[+*], I reset +! reset(); +! openqueue_freePacketBuffer(msg); +! } +! switch (tcp_vars.state) { +! case TCP_STATE_CLOSED: //[receive] establishement +! switch(msg->l4_destination_port) { +! case WKP_TCP_HTTP: +! shouldIlisten = ohlone_shouldIlisten(); +! break; +! case WKP_TCP_ECHO: +! shouldIlisten = tcpecho_shouldIlisten(); +! break; +! case WKP_TCP_INJECT: +! shouldIlisten = tcpinject_shouldIlisten(); +! break; +! case WKP_TCP_DISCARD: +! shouldIlisten = tcpprint_shouldIlisten(); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)2); +! shouldIlisten = FALSE; +! break; +! } +! if ( containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO) && shouldIlisten==TRUE ) { +! tcp_vars.myPort = msg->l4_destination_port; +! //I receive SYN, I send SYN+ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tcp_vars.hisPort = msg->l4_sourcePortORicmpv6Type; +! memcpy(&tcp_vars.hisIPv6Address,&(msg->l3_destinationAdd),sizeof(open_addr_t)); +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_YES, +! TCP_FIN_NO); +! tcp_vars.mySeqNum++; +! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); +! forwarding_send(tempPkt); +! } else { +! reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_SYN_SENT: //[receive] establishement +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { +! //I receive SYN+ACK, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! tcp_change_state(TCP_STATE_ALMOST_ESTABLISHED); +! forwarding_send(tempPkt); +! } else if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { +! //I receive SYN, I send SYN+ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_YES, +! TCP_FIN_NO); +! tcp_vars.mySeqNum++; +! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); +! forwarding_send(tempPkt); +! } else { +! reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)1); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_SYN_RECEIVED: //[receive] establishement +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, the virtual circuit is established +! tcp_change_state(TCP_STATE_ESTABLISHED); +! } else { +! reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)2); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_ESTABLISHED: //[receive] data/teardown +! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN[+ACK], I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); +! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive data, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht); +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! packetfunctions_tossHeader(msg,sizeof(tcp_ht)); +! tcp_vars.dataReceived = msg; +! tcp_change_state(TCP_STATE_ALMOST_DATA_RECEIVED); +! } else { +! reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)3); +! openqueue_freePacketBuffer(msg); +! } +! break; +! +! case TCP_STATE_DATA_SENT: //[receive] data +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, data message sent +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_ECHO: +! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_INJECT: +! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)3); +! break; +! } +! tcp_vars.dataToSend = NULL; +! tcp_change_state(TCP_STATE_ESTABLISHED); +! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN[+ACK], I send ACK +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_ECHO: +! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_INJECT: +! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)4); +! break; +! } +! tcp_vars.dataToSend = NULL; +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); +! } else { +! reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)4); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_FIN_WAIT_1: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_CLOSING); +! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN+ACK, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); +! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, I will receive FIN later +! tcp_change_state(TCP_STATE_FIN_WAIT_2); +! } else { +! reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)5); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_FIN_WAIT_2: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN[+ACK], I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_CLOSING: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, I do nothing +! tcp_change_state(TCP_STATE_TIME_WAIT); +! //TODO implement waiting timer +! reset(); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_LAST_ACK: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, I reset +! reset(); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)4); +! break; +! } +! } +! +! error_t opentcp_close() { //[command] teardown +! OpenQueueEntry_t* tempPkt; +! if ( tcp_vars.state==TCP_STATE_ALMOST_CLOSE_WAIT || +! tcp_vars.state==TCP_STATE_CLOSE_WAIT || +! tcp_vars.state==TCP_STATE_ALMOST_LAST_ACK || +! tcp_vars.state==TCP_STATE_LAST_ACK || +! tcp_vars.state==TCP_STATE_CLOSED) { +! //not an error, can happen when distant node has already started tearing down +! return E_SUCCESS; +! } +! //I receive command 'close', I send FIN+ACK +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_YES); +! tcp_vars.mySeqNum++; +! tcp_change_state(TCP_STATE_ALMOST_FIN_WAIT_1); +! return forwarding_send(tempPkt); +! } +! +! bool tcp_debugPrint() { +! return FALSE; +! } +! +! //======= timer +! +! //timer used to reset state when TCP state machine is stuck +! void timers_tcp_fired() { +! reset(); +! } +! +! //=========================== private ========================================= +! +! void prependTCPHeader(OpenQueueEntry_t* msg, +! bool ack, +! bool push, +! bool rst, +! bool syn, +! bool fin) { +! msg->l4_protocol = IANA_TCP; +! packetfunctions_reserveHeaderSize(msg,sizeof(tcp_ht)); +! packetfunctions_htons(tcp_vars.myPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); +! packetfunctions_htons(tcp_vars.hisPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); +! packetfunctions_htonl(tcp_vars.mySeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)); +! packetfunctions_htonl(tcp_vars.hisNextSeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); +! ((tcp_ht*)msg->payload)->data_offset = TCP_DEFAULT_DATA_OFFSET; +! ((tcp_ht*)msg->payload)->control_bits = 0; +! if (ack==TCP_ACK_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_ACK; +! } else { +! packetfunctions_htonl(0,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); +! } +! if (push==TCP_PSH_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_PSH; +! } +! if (rst==TCP_RST_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_RST; +! } +! if (syn==TCP_SYN_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_SYN; +! } +! if (fin==TCP_FIN_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_FIN; +! } +! packetfunctions_htons(TCP_DEFAULT_WINDOW_SIZE ,(uint8_t*)&(((tcp_ht*)msg->payload)->window_size)); +! packetfunctions_htons(TCP_DEFAULT_URGENT_POINTER ,(uint8_t*)&(((tcp_ht*)msg->payload)->urgent_pointer)); +! //calculate checksum last to take all header fields into account +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((tcp_ht*)msg->payload)->checksum)); +! } +! +! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin) { +! bool return_value = TRUE; +! if (ack!=TCP_ACK_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_ACK) & 0x01) == ack); +! } +! if (rst!=TCP_RST_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_RST) & 0x01) == rst); +! } +! if (syn!=TCP_SYN_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_SYN) & 0x01) == syn); +! } +! if (fin!=TCP_FIN_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_FIN) & 0x01) == fin); +! } +! return return_value; +! } +! +! void reset() { +! tcp_change_state(TCP_STATE_CLOSED); +! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; +! tcp_vars.hisNextSeqNum = 0; +! tcp_vars.hisPort = 0; +! tcp_vars.hisIPv6Address.type = ADDR_NONE; +! tcp_vars.dataToSend = NULL; +! tcp_vars.dataReceived = NULL; +! openqueue_removeAllOwnedBy(COMPONENT_OPENTCP); +! } +! +! void tcp_change_state(uint8_t new_tcp_state) { +! tcp_vars.state = new_tcp_state; +! if (tcp_vars.state==TCP_STATE_CLOSED) { +! if (tcp_vars.timerStarted==TRUE) { +! opentimers_stop(tcp_vars.timerId); +! } +! } else { +! if (tcp_vars.timerStarted==FALSE) { +! tcp_vars.timerId = opentimers_start(TCP_TIMEOUT, +! TIMER_ONESHOT,TIME_MS, +! opentcp_timer_cb); +! tcp_vars.timerStarted=TRUE; +! } +! +! } +! } +! +! void opentcp_timer_cb() { +! scheduler_push_task(timers_tcp_fired,TASKPRIO_TCP_TIMEOUT); + } +\ No newline at end of file +--- 1,753 ---- +! #include "openwsn.h" +! #include "opentcp.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "forwarding.h" +! #include "packetfunctions.h" +! //#include "bsp_timer.h" +! #include "scheduler.h" +! #include "opentimers.h" +! //TCP applications +! #include "ohlone.h" +! #include "tcpecho.h" +! #include "tcpinject.h" +! #include "tcpprint.h" +! +! #include "thread.h" +! +! //=========================== variables ======================================= +! +! tcp_vars_t tcp_vars; +! //static char openwsn_opentcp_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! +! //=========================== prototypes ====================================== +! +! void prependTCPHeader(OpenQueueEntry_t* msg, bool ack, bool push, bool rst, bool syn, bool fin); +! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin); +! void tcp_change_state(uint8_t new_state); +! void opentcp_reset(void); +! void opentcp_timer_cb(void); +! +! //=========================== public ========================================== +! +! void opentcp_init(void) { +! // reset local variables +! memset(&tcp_vars,0,sizeof(tcp_vars_t)); +! // reset state machine +! opentcp_reset(); +! } +! +! owerror_t opentcp_connect(open_addr_t* dest, uint16_t param_tcp_hisPort, uint16_t param_tcp_myPort) { +! //[command] establishment +! OpenQueueEntry_t* tempPkt; +! if (tcp_vars.state!=TCP_STATE_CLOSED) { +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)0); +! return E_FAIL; +! } +! tcp_vars.myPort = param_tcp_myPort; +! tcp_vars.hisPort = param_tcp_hisPort; +! memcpy(&tcp_vars.hisIPv6Address,dest,sizeof(open_addr_t)); +! //I receive command 'connect', I send SYNC +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; +! prependTCPHeader(tempPkt, +! TCP_ACK_NO, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_YES, +! TCP_FIN_NO); +! tcp_change_state(TCP_STATE_ALMOST_SYN_SENT); +! return forwarding_send(tempPkt); +! } +! +! owerror_t opentcp_send(OpenQueueEntry_t* msg) { //[command] data +! msg->owner = COMPONENT_OPENTCP; +! if (tcp_vars.state!=TCP_STATE_ESTABLISHED) { +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)2); +! return E_FAIL; +! } +! if (tcp_vars.dataToSend!=NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_BUSY_SENDING, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! //I receive command 'send', I send data +! msg->l4_protocol = IANA_TCP; +! msg->l4_sourcePortORicmpv6Type = tcp_vars.myPort; +! msg->l4_destination_port = tcp_vars.hisPort; +! msg->l4_payload = msg->payload; +! msg->l4_length = msg->length; +! memcpy(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! tcp_vars.dataToSend = msg; +! prependTCPHeader(tcp_vars.dataToSend, +! TCP_ACK_YES, +! TCP_PSH_YES, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! tcp_vars.mySeqNum += tcp_vars.dataToSend->l4_length; +! tcp_change_state(TCP_STATE_ALMOST_DATA_SENT); +! return forwarding_send(tcp_vars.dataToSend); +! } +! +! void opentcp_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! OpenQueueEntry_t* tempPkt; +! msg->owner = COMPONENT_OPENTCP; +! switch (tcp_vars.state) { +! case TCP_STATE_ALMOST_SYN_SENT: //[sendDone] establishement +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_SYN_SENT); +! break; +! +! case TCP_STATE_ALMOST_SYN_RECEIVED: //[sendDone] establishement +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_SYN_RECEIVED); +! break; +! +! case TCP_STATE_ALMOST_ESTABLISHED: //[sendDone] establishement +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_ESTABLISHED); +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_connectDone(E_SUCCESS); +! break; +! case WKP_TCP_ECHO: +! tcpecho_connectDone(E_SUCCESS); +! break; +! case WKP_TCP_INJECT: +! tcpinject_connectDone(E_SUCCESS); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_connectDone(E_SUCCESS); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)0); +! break; +! } +! break; +! +! case TCP_STATE_ALMOST_DATA_SENT: //[sendDone] data +! tcp_change_state(TCP_STATE_DATA_SENT); +! break; +! +! case TCP_STATE_ALMOST_DATA_RECEIVED: //[sendDone] data +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_ESTABLISHED); +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_receive(tcp_vars.dataReceived); +! break; +! case WKP_TCP_ECHO: +! tcpecho_receive(tcp_vars.dataReceived); +! break; +! case WKP_TCP_INJECT: +! tcpinject_receive(tcp_vars.dataReceived); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_receive(tcp_vars.dataReceived); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)1); +! openqueue_freePacketBuffer(msg); +! tcp_vars.dataReceived = NULL; +! break; +! } +! break; +! +! case TCP_STATE_ALMOST_FIN_WAIT_1: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_FIN_WAIT_1); +! break; +! +! case TCP_STATE_ALMOST_CLOSING: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_CLOSING); +! break; +! +! case TCP_STATE_ALMOST_TIME_WAIT: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_TIME_WAIT); +! //TODO implement waiting timer +! opentcp_reset(); +! break; +! +! case TCP_STATE_ALMOST_CLOSE_WAIT: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_CLOSE_WAIT); +! //I send FIN+ACK +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_YES); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_LAST_ACK); +! break; +! +! case TCP_STATE_ALMOST_LAST_ACK: //[sendDone] teardown +! openqueue_freePacketBuffer(msg); +! tcp_change_state(TCP_STATE_LAST_ACK); +! break; +! +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)3); +! break; +! } +! } +! +! void opentcp_receive(OpenQueueEntry_t* msg) { +! OpenQueueEntry_t* tempPkt; +! bool shouldIlisten; +! msg->owner = COMPONENT_OPENTCP; +! msg->l4_protocol = IANA_TCP; +! msg->l4_payload = msg->payload; +! msg->l4_length = msg->length; +! msg->l4_sourcePortORicmpv6Type = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); +! msg->l4_destination_port = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); +! if ( +! tcp_vars.state!=TCP_STATE_CLOSED && +! ( +! msg->l4_destination_port != tcp_vars.myPort || +! msg->l4_sourcePortORicmpv6Type != tcp_vars.hisPort || +! packetfunctions_sameAddress(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address)==FALSE +! ) +! ) { +! openqueue_freePacketBuffer(msg); +! return; +! } +! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_YES,TCP_SYN_WHATEVER,TCP_FIN_WHATEVER)) { +! //I receive RST[+*], I reset +! opentcp_reset(); +! openqueue_freePacketBuffer(msg); +! } +! switch (tcp_vars.state) { +! case TCP_STATE_CLOSED: //[receive] establishement +! switch(msg->l4_destination_port) { +! case WKP_TCP_HTTP: +! shouldIlisten = ohlone_shouldIlisten(); +! break; +! case WKP_TCP_ECHO: +! shouldIlisten = tcpecho_shouldIlisten(); +! break; +! case WKP_TCP_INJECT: +! shouldIlisten = tcpinject_shouldIlisten(); +! break; +! case WKP_TCP_DISCARD: +! shouldIlisten = tcpprint_shouldIlisten(); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)2); +! shouldIlisten = FALSE; +! break; +! } +! if ( containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO) && shouldIlisten==TRUE ) { +! tcp_vars.myPort = msg->l4_destination_port; +! //I receive SYN, I send SYN+ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tcp_vars.hisPort = msg->l4_sourcePortORicmpv6Type; +! memcpy(&tcp_vars.hisIPv6Address,&(msg->l3_destinationAdd),sizeof(open_addr_t)); +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_YES, +! TCP_FIN_NO); +! tcp_vars.mySeqNum++; +! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); +! forwarding_send(tempPkt); +! } else { +! opentcp_reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_SYN_SENT: //[receive] establishement +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { +! //I receive SYN+ACK, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! tcp_change_state(TCP_STATE_ALMOST_ESTABLISHED); +! forwarding_send(tempPkt); +! } else if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { +! //I receive SYN, I send SYN+ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_YES, +! TCP_FIN_NO); +! tcp_vars.mySeqNum++; +! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); +! forwarding_send(tempPkt); +! } else { +! opentcp_reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)1); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_SYN_RECEIVED: //[receive] establishement +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, the virtual circuit is established +! tcp_change_state(TCP_STATE_ESTABLISHED); +! } else { +! opentcp_reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)2); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_ESTABLISHED: //[receive] data/teardown +! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN[+ACK], I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); +! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive data, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht); +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! packetfunctions_tossHeader(msg,sizeof(tcp_ht)); +! tcp_vars.dataReceived = msg; +! tcp_change_state(TCP_STATE_ALMOST_DATA_RECEIVED); +! } else { +! opentcp_reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)3); +! openqueue_freePacketBuffer(msg); +! } +! break; +! +! case TCP_STATE_DATA_SENT: //[receive] data +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, data message sent +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_ECHO: +! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_INJECT: +! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)3); +! break; +! } +! tcp_vars.dataToSend = NULL; +! tcp_change_state(TCP_STATE_ESTABLISHED); +! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN[+ACK], I send ACK +! switch(tcp_vars.myPort) { +! case WKP_TCP_HTTP: +! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_ECHO: +! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_INJECT: +! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! case WKP_TCP_DISCARD: +! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); +! break; +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)tcp_vars.myPort, +! (errorparameter_t)4); +! break; +! } +! tcp_vars.dataToSend = NULL; +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); +! } else { +! opentcp_reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)4); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_FIN_WAIT_1: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_CLOSING); +! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN+ACK, I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); +! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, I will receive FIN later +! tcp_change_state(TCP_STATE_FIN_WAIT_2); +! } else { +! opentcp_reset(); +! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)5); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_FIN_WAIT_2: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { +! //I receive FIN[+ACK], I send ACK +! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! return; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_NO); +! forwarding_send(tempPkt); +! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_CLOSING: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, I do nothing +! tcp_change_state(TCP_STATE_TIME_WAIT); +! //TODO implement waiting timer +! opentcp_reset(); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! case TCP_STATE_LAST_ACK: //[receive] teardown +! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { +! //I receive ACK, I reset +! opentcp_reset(); +! } +! openqueue_freePacketBuffer(msg); +! break; +! +! default: +! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, +! (errorparameter_t)tcp_vars.state, +! (errorparameter_t)4); +! break; +! } +! } +! +! owerror_t opentcp_close(void) { //[command] teardown +! OpenQueueEntry_t* tempPkt; +! if ( tcp_vars.state==TCP_STATE_ALMOST_CLOSE_WAIT || +! tcp_vars.state==TCP_STATE_CLOSE_WAIT || +! tcp_vars.state==TCP_STATE_ALMOST_LAST_ACK || +! tcp_vars.state==TCP_STATE_LAST_ACK || +! tcp_vars.state==TCP_STATE_CLOSED) { +! //not an error, can happen when distant node has already started tearing down +! return E_SUCCESS; +! } +! //I receive command 'close', I send FIN+ACK +! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); +! if (tempPkt==NULL) { +! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return E_FAIL; +! } +! tempPkt->creator = COMPONENT_OPENTCP; +! tempPkt->owner = COMPONENT_OPENTCP; +! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); +! prependTCPHeader(tempPkt, +! TCP_ACK_YES, +! TCP_PSH_NO, +! TCP_RST_NO, +! TCP_SYN_NO, +! TCP_FIN_YES); +! tcp_vars.mySeqNum++; +! tcp_change_state(TCP_STATE_ALMOST_FIN_WAIT_1); +! return forwarding_send(tempPkt); +! } +! +! bool tcp_debugPrint(void) { +! return FALSE; +! } +! +! //======= timer +! +! //timer used to reset state when TCP state machine is stuck +! void timers_tcp_fired(void) { +! opentcp_reset(); +! } +! +! //=========================== private ========================================= +! +! void prependTCPHeader(OpenQueueEntry_t* msg, +! bool ack, +! bool push, +! bool rst, +! bool syn, +! bool fin) { +! msg->l4_protocol = IANA_TCP; +! packetfunctions_reserveHeaderSize(msg,sizeof(tcp_ht)); +! packetfunctions_htons(tcp_vars.myPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); +! packetfunctions_htons(tcp_vars.hisPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); +! packetfunctions_htonl(tcp_vars.mySeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)); +! packetfunctions_htonl(tcp_vars.hisNextSeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); +! ((tcp_ht*)msg->payload)->data_offset = TCP_DEFAULT_DATA_OFFSET; +! ((tcp_ht*)msg->payload)->control_bits = 0; +! if (ack==TCP_ACK_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_ACK; +! } else { +! packetfunctions_htonl(0,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); +! } +! if (push==TCP_PSH_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_PSH; +! } +! if (rst==TCP_RST_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_RST; +! } +! if (syn==TCP_SYN_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_SYN; +! } +! if (fin==TCP_FIN_YES) { +! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_FIN; +! } +! packetfunctions_htons(TCP_DEFAULT_WINDOW_SIZE ,(uint8_t*)&(((tcp_ht*)msg->payload)->window_size)); +! packetfunctions_htons(TCP_DEFAULT_URGENT_POINTER ,(uint8_t*)&(((tcp_ht*)msg->payload)->urgent_pointer)); +! //calculate checksum last to take all header fields into account +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((tcp_ht*)msg->payload)->checksum)); +! } +! +! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin) { +! bool return_value = TRUE; +! if (ack!=TCP_ACK_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_ACK) & 0x01) == ack); +! } +! if (rst!=TCP_RST_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_RST) & 0x01) == rst); +! } +! if (syn!=TCP_SYN_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_SYN) & 0x01) == syn); +! } +! if (fin!=TCP_FIN_WHATEVER){ +! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_FIN) & 0x01) == fin); +! } +! return return_value; +! } +! +! void opentcp_reset(void) { +! tcp_change_state(TCP_STATE_CLOSED); +! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; +! tcp_vars.hisNextSeqNum = 0; +! tcp_vars.hisPort = 0; +! tcp_vars.hisIPv6Address.type = ADDR_NONE; +! tcp_vars.dataToSend = NULL; +! tcp_vars.dataReceived = NULL; +! openqueue_removeAllOwnedBy(COMPONENT_OPENTCP); +! } +! +! void tcp_change_state(uint8_t new_tcp_state) { +! tcp_vars.state = new_tcp_state; +! if (tcp_vars.state==TCP_STATE_CLOSED) { +! if (tcp_vars.timerStarted==TRUE) { +! opentimers_stop(tcp_vars.timerId); +! } +! } else { +! if (tcp_vars.timerStarted==FALSE) { +! tcp_vars.timerId = opentimers_start(TCP_TIMEOUT, +! TIMER_ONESHOT,TIME_MS, +! opentcp_timer_cb); +! tcp_vars.timerStarted=TRUE; +! } +! +! } +! } +! +! void opentcp_timer_cb(void) { +! scheduler_push_task(timers_tcp_fired,TASKPRIO_TCP_TIMEOUT); +! /*thread_create(openwsn_opentcp_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_OPENTCP, CREATE_STACKTEST, +! timers_tcp_fired, "timers tcp fired");*/ + } +\ No newline at end of file +diff -crB openwsn/04-TRAN/opentcp.h ../../../sys/net/openwsn/04-TRAN/opentcp.h +*** openwsn/04-TRAN/opentcp.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/opentcp.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,118 **** +! #ifndef __OPENTCP_H +! #define __OPENTCP_H +! +! /** +! \addtogroup Transport +! \{ +! \addtogroup TCP +! \{ +! */ +! +! //=========================== define ========================================== +! +! enum { +! TCP_INITIAL_SEQNUM = 100, +! TCP_TIMEOUT = 1500, //in ms +! }; +! +! enum TCP_STATE_enums { +! //listen state is not declared but emulated by a closed state with shouldIlisten==TRUE +! TCP_STATE_CLOSED = 0, +! TCP_STATE_ALMOST_SYN_RECEIVED = 1, +! TCP_STATE_SYN_RECEIVED = 2, +! TCP_STATE_ALMOST_SYN_SENT = 3, +! TCP_STATE_SYN_SENT = 4, +! TCP_STATE_ALMOST_ESTABLISHED = 5, +! TCP_STATE_ESTABLISHED = 6, +! TCP_STATE_ALMOST_DATA_SENT = 7, +! TCP_STATE_DATA_SENT = 8, +! TCP_STATE_ALMOST_DATA_RECEIVED = 9, +! TCP_STATE_ALMOST_FIN_WAIT_1 = 10, +! TCP_STATE_FIN_WAIT_1 = 11, +! TCP_STATE_ALMOST_CLOSING = 12, +! TCP_STATE_CLOSING = 13, +! TCP_STATE_FIN_WAIT_2 = 14, +! TCP_STATE_ALMOST_TIME_WAIT = 15, +! TCP_STATE_TIME_WAIT = 16, +! TCP_STATE_ALMOST_CLOSE_WAIT = 17, +! TCP_STATE_CLOSE_WAIT = 18, +! TCP_STATE_ALMOST_LAST_ACK = 19, +! TCP_STATE_LAST_ACK = 20, +! }; +! +! enum TCP_DEFAULTS_enum{ +! TCP_DEFAULT_DATA_OFFSET = 0x50, +! TCP_DEFAULT_WINDOW_SIZE = 48, +! TCP_DEFAULT_URGENT_POINTER = 0x0000, +! }; +! +! enum TCP_ACK_FLAG_enum { +! TCP_ACK_WHATEVER = 2, +! TCP_ACK_YES = 1, +! TCP_ACK_NO = 0, +! }; +! +! enum TCP_PSH_FLAG_enum { +! TCP_PSH_WHATEVER = 2, +! TCP_PSH_YES = 1, +! TCP_PSH_NO = 0, +! }; +! +! enum TCP_RST_FLAG_enum { +! TCP_RST_WHATEVER = 2, +! TCP_RST_YES = 1, +! TCP_RST_NO = 0, +! }; +! +! enum TCP_SYN_FLAG_enum { +! TCP_SYN_WHATEVER = 2, +! TCP_SYN_YES = 1, +! TCP_SYN_NO = 0, +! }; +! +! enum TCP_FIN_FLAG_enum { +! TCP_FIN_WHATEVER = 2, +! TCP_FIN_YES = 1, +! TCP_FIN_NO = 0, +! }; +! +! enum TCP_FLAG_POSITIONS_enum { +! TCP_ACK = 4, +! TCP_PSH = 3, +! TCP_RST = 2, +! TCP_SYN = 1, +! TCP_FIN = 0, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint16_t source_port; +! uint16_t destination_port; +! uint32_t sequence_number; +! uint32_t ack_number; +! uint8_t data_offset; +! uint8_t control_bits; +! uint16_t window_size; +! uint16_t checksum; +! uint16_t urgent_pointer; +! } tcp_ht; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void opentcp_init(); +! error_t opentcp_connect(open_addr_t* dest, uint16_t param_hisPort, uint16_t param_myPort); +! error_t opentcp_send(OpenQueueEntry_t* msg); +! void opentcp_sendDone(OpenQueueEntry_t* msg, error_t error); +! void opentcp_receive(OpenQueueEntry_t* msg); +! error_t opentcp_close(); +! bool opentcp_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,133 ---- +! #ifndef __OPENTCP_H +! #define __OPENTCP_H +! +! /** +! \addtogroup Transport +! \{ +! \addtogroup OpenTcp +! \{ +! */ +! +! #include "opentimers.h" +! +! //=========================== define ========================================== +! +! enum { +! TCP_INITIAL_SEQNUM = 100, +! TCP_TIMEOUT = 1500, //in ms +! }; +! +! enum TCP_STATE_enums { +! //listen state is not declared but emulated by a closed state with shouldIlisten==TRUE +! TCP_STATE_CLOSED = 0, +! TCP_STATE_ALMOST_SYN_RECEIVED = 1, +! TCP_STATE_SYN_RECEIVED = 2, +! TCP_STATE_ALMOST_SYN_SENT = 3, +! TCP_STATE_SYN_SENT = 4, +! TCP_STATE_ALMOST_ESTABLISHED = 5, +! TCP_STATE_ESTABLISHED = 6, +! TCP_STATE_ALMOST_DATA_SENT = 7, +! TCP_STATE_DATA_SENT = 8, +! TCP_STATE_ALMOST_DATA_RECEIVED = 9, +! TCP_STATE_ALMOST_FIN_WAIT_1 = 10, +! TCP_STATE_FIN_WAIT_1 = 11, +! TCP_STATE_ALMOST_CLOSING = 12, +! TCP_STATE_CLOSING = 13, +! TCP_STATE_FIN_WAIT_2 = 14, +! TCP_STATE_ALMOST_TIME_WAIT = 15, +! TCP_STATE_TIME_WAIT = 16, +! TCP_STATE_ALMOST_CLOSE_WAIT = 17, +! TCP_STATE_CLOSE_WAIT = 18, +! TCP_STATE_ALMOST_LAST_ACK = 19, +! TCP_STATE_LAST_ACK = 20, +! }; +! +! enum TCP_DEFAULTS_enum{ +! TCP_DEFAULT_DATA_OFFSET = 0x50, +! TCP_DEFAULT_WINDOW_SIZE = 48, +! TCP_DEFAULT_URGENT_POINTER = 0x0000, +! }; +! +! enum TCP_ACK_FLAG_enum { +! TCP_ACK_WHATEVER = 2, +! TCP_ACK_YES = 1, +! TCP_ACK_NO = 0, +! }; +! +! enum TCP_PSH_FLAG_enum { +! TCP_PSH_WHATEVER = 2, +! TCP_PSH_YES = 1, +! TCP_PSH_NO = 0, +! }; +! +! enum TCP_RST_FLAG_enum { +! TCP_RST_WHATEVER = 2, +! TCP_RST_YES = 1, +! TCP_RST_NO = 0, +! }; +! +! enum TCP_SYN_FLAG_enum { +! TCP_SYN_WHATEVER = 2, +! TCP_SYN_YES = 1, +! TCP_SYN_NO = 0, +! }; +! +! enum TCP_FIN_FLAG_enum { +! TCP_FIN_WHATEVER = 2, +! TCP_FIN_YES = 1, +! TCP_FIN_NO = 0, +! }; +! +! enum TCP_FLAG_POSITIONS_enum { +! TCP_ACK = 4, +! TCP_PSH = 3, +! TCP_RST = 2, +! TCP_SYN = 1, +! TCP_FIN = 0, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint16_t source_port; +! uint16_t destination_port; +! uint32_t sequence_number; +! uint32_t ack_number; +! uint8_t data_offset; +! uint8_t control_bits; +! uint16_t window_size; +! uint16_t checksum; +! uint16_t urgent_pointer; +! } tcp_ht; +! +! //=========================== module variables ================================ +! +! typedef struct { +! uint8_t state; +! uint32_t mySeqNum; +! uint16_t myPort; +! uint32_t hisNextSeqNum; +! uint16_t hisPort; +! open_addr_t hisIPv6Address; +! OpenQueueEntry_t* dataToSend; +! OpenQueueEntry_t* dataReceived; +! bool timerStarted; +! opentimer_id_t timerId; +! } tcp_vars_t; +! +! //=========================== prototypes ====================================== +! +! void opentcp_init(void); +! owerror_t opentcp_connect(open_addr_t* dest, uint16_t param_hisPort, uint16_t param_myPort); +! owerror_t opentcp_send(OpenQueueEntry_t* msg); +! void opentcp_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void opentcp_receive(OpenQueueEntry_t* msg); +! owerror_t opentcp_close(void); +! bool opentcp_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/04-TRAN/openudp.c ../../../sys/net/openwsn/04-TRAN/openudp.c +*** openwsn/04-TRAN/openudp.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/openudp.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,158 **** +! #include "openwsn.h" +! #include "openudp.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "forwarding.h" +! #include "openqueue.h" +! //UDP applications +! #include "opencoap.h" +! #include "udpecho.h" +! #include "udpinject.h" +! #include "udpprint.h" +! #include "udprand.h" +! #include "udpstorm.h" +! #include "udplatency.h" +! //#include "heli.h" +! //#include "imu.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void openudp_init() { +! } +! +! error_t openudp_send(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_OPENUDP; +! msg->l4_protocol = IANA_UDP; +! msg->l4_payload = msg->payload; +! msg->l4_length = msg->length; +! packetfunctions_reserveHeaderSize(msg,sizeof(udp_ht)); +! packetfunctions_htons(msg->l4_sourcePortORicmpv6Type,&(msg->payload[0])); +! packetfunctions_htons(msg->l4_destination_port,&(msg->payload[2])); +! packetfunctions_htons(msg->length,&(msg->payload[4])); +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((udp_ht*)msg->payload)->checksum)); +! return forwarding_send(msg); +! } +! +! void openudp_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_OPENUDP; +! switch(msg->l4_sourcePortORicmpv6Type) { +! case WKP_UDP_COAP: +! opencoap_sendDone(msg,error); +! break; +! /* +! case WKP_UDP_HELI: +! appudpheli_sendDone(msg,error); +! break; +! case WKP_UDP_IMU: +! appudpgina_sendDone(msg,error); +! break; +! */ +! case WKP_UDP_ECHO: +! udpecho_sendDone(msg,error); +! break; +! case WKP_UDP_INJECT: +! udpinject_sendDone(msg,error); +! break; +! case WKP_UDP_DISCARD: +! udpprint_sendDone(msg,error); +! break; +! case WKP_UDP_RAND: +! udprand_sendDone(msg,error); +! break; +! case WKP_UDP_LATENCY: +! udplatency_sendDone(msg,error); +! break; +! +! default: +! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)5); +! openqueue_freePacketBuffer(msg); +! } +! } +! +! void openudp_receive(OpenQueueEntry_t* msg) { +! uint8_t temp_8b; +! +! msg->owner = COMPONENT_OPENUDP; +! if (msg->l4_protocol_compressed==TRUE) { +! // get the UDP header encoding byte +! temp_8b = *((uint8_t*)(msg->payload)); +! packetfunctions_tossHeader(msg,sizeof(temp_8b)); +! switch (temp_8b & NHC_UDP_PORTS_MASK) { +! case NHC_UDP_PORTS_INLINE: +! // source port: 16 bits in-line +! // dest port: 16 bits in-line +! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; +! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; +! packetfunctions_tossHeader(msg,2+2); +! break; +! case NHC_UDP_PORTS_16S_8D: +! // source port: 16 bits in-line +! // dest port: 0xf0 + 8 bits in-line +! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; +! msg->l4_destination_port = 0xf000 + msg->payload[2]; +! packetfunctions_tossHeader(msg,2+1); +! break; +! case NHC_UDP_PORTS_8S_8D: +! // source port: 0xf0 + 8 bits in-line +! // dest port: 0xf0 + 8 bits in-line +! msg->l4_sourcePortORicmpv6Type = 0xf000 + msg->payload[0]; +! msg->l4_destination_port = 0xf000 + msg->payload[1]; +! packetfunctions_tossHeader(msg,1+1); +! break; +! case NHC_UDP_PORTS_4S_4D: +! // source port: 0xf0b + 4 bits in-line +! // dest port: 0xf0b + 4 bits in-line +! msg->l4_sourcePortORicmpv6Type = 0xf0b0 + (msg->payload[0] >> 4) & 0x0f; +! msg->l4_destination_port = 0xf0b0 + (msg->payload[0] >> 0) & 0x0f; +! packetfunctions_tossHeader(msg,1); +! break; +! } +! } else { +! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; +! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; +! packetfunctions_tossHeader(msg,sizeof(udp_ht)); +! } +! +! switch(msg->l4_destination_port) { +! case WKP_UDP_COAP: +! opencoap_receive(msg); +! break; +! /* +! case WKP_UDP_HELI: +! appudpheli_receive(msg); +! break; +! case WKP_UDP_IMU: +! imu_receive(msg); +! break; +! */ +! case WKP_UDP_ECHO: +! udpecho_receive(msg); +! break; +! case WKP_UDP_INJECT: +! udpinject_receive(msg); +! break; +! case WKP_UDP_DISCARD: +! udpprint_receive(msg); +! break; +! case WKP_UDP_RAND: +! udprand_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)msg->l4_destination_port, +! (errorparameter_t)6); +! openqueue_freePacketBuffer(msg); +! } +! } +! +! bool openudp_debugPrint() { +! return FALSE; +! } +! +! //=========================== private ========================================= +--- 1,158 ---- +! #include "openwsn.h" +! #include "openudp.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "forwarding.h" +! #include "openqueue.h" +! //UDP applications +! #include "opencoap.h" +! #include "udpecho.h" +! #include "udpinject.h" +! #include "udpprint.h" +! #include "udprand.h" +! #include "udpstorm.h" +! #include "udplatency.h" +! //#include "heli.h" +! //#include "imu.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void openudp_init(void) { +! } +! +! owerror_t openudp_send(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_OPENUDP; +! msg->l4_protocol = IANA_UDP; +! msg->l4_payload = msg->payload; +! msg->l4_length = msg->length; +! packetfunctions_reserveHeaderSize(msg,sizeof(udp_ht)); +! packetfunctions_htons(msg->l4_sourcePortORicmpv6Type,&(msg->payload[0])); +! packetfunctions_htons(msg->l4_destination_port,&(msg->payload[2])); +! packetfunctions_htons(msg->length,&(msg->payload[4])); +! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((udp_ht*)msg->payload)->checksum)); +! return forwarding_send(msg); +! } +! +! void openudp_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_OPENUDP; +! switch(msg->l4_sourcePortORicmpv6Type) { +! case WKP_UDP_COAP: +! opencoap_sendDone(msg,error); +! break; +! /* +! case WKP_UDP_HELI: +! appudpheli_sendDone(msg,error); +! break; +! case WKP_UDP_IMU: +! appudpgina_sendDone(msg,error); +! break; +! */ +! case WKP_UDP_ECHO: +! udpecho_sendDone(msg,error); +! break; +! case WKP_UDP_INJECT: +! udpinject_sendDone(msg,error); +! break; +! case WKP_UDP_DISCARD: +! udpprint_sendDone(msg,error); +! break; +! case WKP_UDP_RAND: +! udprand_sendDone(msg,error); +! break; +! case WKP_UDP_LATENCY: +! udplatency_sendDone(msg,error); +! break; +! +! default: +! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, +! (errorparameter_t)5); +! openqueue_freePacketBuffer(msg); +! } +! } +! +! void openudp_receive(OpenQueueEntry_t* msg) { +! uint8_t temp_8b; +! +! msg->owner = COMPONENT_OPENUDP; +! if (msg->l4_protocol_compressed==TRUE) { +! // get the UDP header encoding byte +! temp_8b = *((uint8_t*)(msg->payload)); +! packetfunctions_tossHeader(msg,sizeof(temp_8b)); +! switch (temp_8b & NHC_UDP_PORTS_MASK) { +! case NHC_UDP_PORTS_INLINE: +! // source port: 16 bits in-line +! // dest port: 16 bits in-line +! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; +! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; +! packetfunctions_tossHeader(msg,2+2); +! break; +! case NHC_UDP_PORTS_16S_8D: +! // source port: 16 bits in-line +! // dest port: 0xf0 + 8 bits in-line +! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; +! msg->l4_destination_port = 0xf000 + msg->payload[2]; +! packetfunctions_tossHeader(msg,2+1); +! break; +! case NHC_UDP_PORTS_8S_8D: +! // source port: 0xf0 + 8 bits in-line +! // dest port: 0xf0 + 8 bits in-line +! msg->l4_sourcePortORicmpv6Type = 0xf000 + msg->payload[0]; +! msg->l4_destination_port = 0xf000 + msg->payload[1]; +! packetfunctions_tossHeader(msg,1+1); +! break; +! case NHC_UDP_PORTS_4S_4D: +! // source port: 0xf0b + 4 bits in-line +! // dest port: 0xf0b + 4 bits in-line +! msg->l4_sourcePortORicmpv6Type = 0xf0b0 + ((msg->payload[0] >> 4) & 0x0f); +! msg->l4_destination_port = 0xf0b0 + ((msg->payload[0] >> 0) & 0x0f); +! packetfunctions_tossHeader(msg,1); +! break; +! } +! } else { +! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; +! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; +! packetfunctions_tossHeader(msg,sizeof(udp_ht)); +! } +! +! switch(msg->l4_destination_port) { +! case WKP_UDP_COAP: +! opencoap_receive(msg); +! break; +! /* +! case WKP_UDP_HELI: +! appudpheli_receive(msg); +! break; +! case WKP_UDP_IMU: +! imu_receive(msg); +! break; +! */ +! case WKP_UDP_ECHO: +! udpecho_receive(msg); +! break; +! case WKP_UDP_INJECT: +! udpinject_receive(msg); +! break; +! case WKP_UDP_DISCARD: +! udpprint_receive(msg); +! break; +! case WKP_UDP_RAND: +! udprand_receive(msg); +! break; +! default: +! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, +! (errorparameter_t)msg->l4_destination_port, +! (errorparameter_t)6); +! openqueue_freePacketBuffer(msg); +! } +! } +! +! bool openudp_debugPrint(void) { +! return FALSE; +! } +! +! //=========================== private ========================================= +diff -crB openwsn/04-TRAN/openudp.h ../../../sys/net/openwsn/04-TRAN/openudp.h +*** openwsn/04-TRAN/openudp.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/openudp.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,59 **** +! #ifndef __OPENUDP_H +! #define __OPENUDP_H +! +! /** +! \addtogroup Transport +! \{ +! \addtogroup UDP +! \{ +! */ +! +! //=========================== define ========================================== +! +! enum UDP_enums { +! UDP_ID = 3, +! UDP_CHECKSUM = 2, +! UDP_PORTS = 0, +! }; +! +! enum UDP_ID_enums { +! UDP_ID_DEFAULT = 0x1E, +! }; +! +! enum UDP_CHECKSUM_enums { +! UDP_CHECKSUM_INLINE = 0, +! UDP_CHECKSUM_ELIDED = 1, +! }; +! +! enum UDP_PORTS_enums { +! UDP_PORTS_16b_SRC_16b_DEST_INLINE = 0, +! UDP_PORTS_16b_SRC_8b_DEST_INLINE = 1, +! UDP_PORTS_8b_SRC_16b_DEST_INLINE = 2, +! UDP_PORTS_4b_SRC_4b_DEST_INLINE = 3, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint16_t port_src; +! uint16_t port_dest; +! uint16_t length; +! uint16_t checksum; +! } udp_ht; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openudp_init(); +! error_t openudp_send(OpenQueueEntry_t* msg); +! void openudp_sendDone(OpenQueueEntry_t* msg, error_t error); +! void openudp_receive(OpenQueueEntry_t* msg); +! bool openudp_debugPrint(); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,59 ---- +! #ifndef __OPENUDP_H +! #define __OPENUDP_H +! +! /** +! \addtogroup Transport +! \{ +! \addtogroup OpenUdp +! \{ +! */ +! +! //=========================== define ========================================== +! +! enum UDP_enums { +! UDP_ID = 3, +! UDP_CHECKSUM = 2, +! UDP_PORTS = 0, +! }; +! +! enum UDP_ID_enums { +! UDP_ID_DEFAULT = 0x1E, +! }; +! +! enum UDP_CHECKSUM_enums { +! UDP_CHECKSUM_INLINE = 0, +! UDP_CHECKSUM_ELIDED = 1, +! }; +! +! enum UDP_PORTS_enums { +! UDP_PORTS_16b_SRC_16b_DEST_INLINE = 0, +! UDP_PORTS_16b_SRC_8b_DEST_INLINE = 1, +! UDP_PORTS_8b_SRC_16b_DEST_INLINE = 2, +! UDP_PORTS_4b_SRC_4b_DEST_INLINE = 3, +! }; +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint16_t port_src; +! uint16_t port_dest; +! uint16_t length; +! uint16_t checksum; +! } udp_ht; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openudp_init(void); +! owerror_t openudp_send(OpenQueueEntry_t* msg); +! void openudp_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void openudp_receive(OpenQueueEntry_t* msg); +! bool openudp_debugPrint(void); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/04-TRAN/rsvp.c ../../../sys/net/openwsn/04-TRAN/rsvp.c +*** openwsn/04-TRAN/rsvp.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/rsvp.c Wed Jan 15 13:48:27 2014 +*************** +*** 17,27 **** + uint8_t rsvp_timer_id; + }rsvp_vars_t; + +! void rsvp_timer_cb(); + + rsvp_vars_t rsvp_vars; + +! void rsvp_init(){ + rsvp_vars.rsvp_period = 0; + rsvp_vars.rsvp_timer_id = 0; + } +--- 17,27 ---- + uint8_t rsvp_timer_id; + }rsvp_vars_t; + +! void rsvp_timer_cb(void); + + rsvp_vars_t rsvp_vars; + +! void rsvp_init(void){ + rsvp_vars.rsvp_period = 0; + rsvp_vars.rsvp_timer_id = 0; + } +*************** +*** 35,42 **** + void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period, open_addr_t dest){ + + OpenQueueEntry_t* pkt; +! error_t outcome; + uint8_t i,j; + + pkt = openqueue_getFreePacketBuffer(COMPONENT_RSVP); + if (pkt==NULL) { +--- 35,46 ---- + void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period, open_addr_t dest){ + + OpenQueueEntry_t* pkt; +! owerror_t outcome; + uint8_t i,j; ++ ++ (void)outcome; ++ (void)i; ++ (void)j; + + pkt = openqueue_getFreePacketBuffer(COMPONENT_RSVP); + if (pkt==NULL) { +diff -crB openwsn/04-TRAN/rsvp.h ../../../sys/net/openwsn/04-TRAN/rsvp.h +*** openwsn/04-TRAN/rsvp.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/04-TRAN/rsvp.h Wed Jan 15 13:48:27 2014 +*************** +*** 157,163 **** + + + +! void rsvp_init(); + void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period,open_addr_t dest); + + #endif +--- 157,163 ---- + + + +! void rsvp_init(void); + void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period,open_addr_t dest); + + #endif +diff -crB openwsn/07-App/Makefile ../../../sys/net/openwsn/07-App/Makefile +*** openwsn/07-App/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,49 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/07-APP/ohlone ++ INCLUDES += -I$(CURDIR)/07-APP/tcpecho ++ INCLUDES += -I$(CURDIR)/07-APP/tcpinject ++ INCLUDES += -I$(CURDIR)/07-APP/tcpprint ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ DIRS += rinfo ++ DIRS += rwellknown ++ DIRS += ohlone ++ DIRS += tcpecho ++ DIRS += tcpinject ++ DIRS += tcpprint ++ DIRS += udpecho ++ DIRS += udpinject ++ DIRS += udplatency ++ DIRS += udpprint ++ DIRS += udprand ++ DIRS += udpstorm ++ ++ all: $(BINDIR)$(SUBMOD) ++ @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ mkdir -p $(BINDIR) ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ clean:: ++ @for i in $(DIRS) ; do "$(MAKE)" -C $$i clean ; done ; +diff -crB openwsn/07-App/heli/heli.c ../../../sys/net/openwsn/07-App/heli/heli.c +*** openwsn/07-App/heli/heli.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/heli/heli.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,87 **** +! #include "openwsn.h" +! #include "heli.h" +! //openwsn stack +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! +! #define MOTORPERIOD 100 +! #define MOTORMAX MOTORPERIOD +! #define MOTORMIN 0 +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void heli_setmotor(uint8_t which, uint16_t value); +! uint16_t heli_threshold(uint16_t value); +! +! //=========================== public ========================================== +! +! void heli_init() { +! P1DIR |= 0x0C; // P1.2,3 output +! P1SEL |= 0x0C; // P1.2,3 in PWM mode +! TACTL = TBSSEL_1 + ID_3 + MC_1; // ACLK, count up to TACCR0 +! TACCR0 = MOTORPERIOD; // ~320 Hz frequency +! TACCTL1 = OUTMOD_7; +! TACCR1 = MOTORMIN; +! TACCTL2 = OUTMOD_7; +! TACCR2 = MOTORMIN; +! } +! +! //this is called when the corresponding button is pressed on the OpenVisualizer interface +! void heli_trigger() { +! } +! +! uint16_t heli_threshold(uint16_t value) { +! /*if (value < MOTORMIN) { //causes warning because set to zero +! return MOTORMIN; +! }*/ +! if (value > MOTORMAX) { +! return MOTORMAX; +! } +! return value; +! } +! +! //I just received a request +! void heli_receive(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_HELI; +! if (msg->length==4) { +! heli_setmotor(1,heli_threshold(packetfunctions_ntohs(&(msg->payload[0])))); +! heli_setmotor(2,heli_threshold(packetfunctions_ntohs(&(msg->payload[2])))); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! //I just sent a IMU packet, check I need to resend one +! void heli_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_HELI; +! if (msg->creator!=COMPONENT_HELI) { +! openserial_printError(COMPONENT_HELI,ERR_SENDDONE_FOR_MSG_I_DID_NOT_SEND,0,0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! bool heli_debugPrint() { +! return FALSE; +! } +! +! //=========================== private ========================================= +! +! void heli_setmotor(uint8_t which, uint16_t value) { +! /*if (value < MOTORMIN) { +! value = MOTORMIN; +! }*/ +! if (value > MOTORMAX) { +! value = MOTORMAX; +! } +! switch (which) { +! case 1: +! TACCR1 = value; +! break; +! case 2: +! TACCR2 = value; +! break; +! } +! } +--- 1,87 ---- +! #include "openwsn.h" +! #include "heli.h" +! //openwsn stack +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! +! #define MOTORPERIOD 100 +! #define MOTORMAX MOTORPERIOD +! #define MOTORMIN 0 +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void heli_setmotor(uint8_t which, uint16_t value); +! uint16_t heli_threshold(uint16_t value); +! +! //=========================== public ========================================== +! +! void heli_init() { +! P1DIR |= 0x0C; // P1.2,3 output +! P1SEL |= 0x0C; // P1.2,3 in PWM mode +! TACTL = TBSSEL_1 + ID_3 + MC_1; // ACLK, count up to TACCR0 +! TACCR0 = MOTORPERIOD; // ~320 Hz frequency +! TACCTL1 = OUTMOD_7; +! TACCR1 = MOTORMIN; +! TACCTL2 = OUTMOD_7; +! TACCR2 = MOTORMIN; +! } +! +! //this is called when the corresponding button is pressed on the OpenVisualizer interface +! void heli_trigger() { +! } +! +! uint16_t heli_threshold(uint16_t value) { +! /*if (value < MOTORMIN) { //causes warning because set to zero +! return MOTORMIN; +! }*/ +! if (value > MOTORMAX) { +! return MOTORMAX; +! } +! return value; +! } +! +! //I just received a request +! void heli_receive(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_HELI; +! if (msg->length==4) { +! heli_setmotor(1,heli_threshold(packetfunctions_ntohs(&(msg->payload[0])))); +! heli_setmotor(2,heli_threshold(packetfunctions_ntohs(&(msg->payload[2])))); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! //I just sent a IMU packet, check I need to resend one +! void heli_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_HELI; +! if (msg->creator!=COMPONENT_HELI) { +! openserial_printError(COMPONENT_HELI,ERR_SENDDONE_FOR_MSG_I_DID_NOT_SEND,0,0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! bool heli_debugPrint() { +! return FALSE; +! } +! +! //=========================== private ========================================= +! +! void heli_setmotor(uint8_t which, uint16_t value) { +! /*if (value < MOTORMIN) { +! value = MOTORMIN; +! }*/ +! if (value > MOTORMAX) { +! value = MOTORMAX; +! } +! switch (which) { +! case 1: +! TACCR1 = value; +! break; +! case 2: +! TACCR2 = value; +! break; +! } +! } +diff -crB openwsn/07-App/heli/heli.h ../../../sys/net/openwsn/07-App/heli/heli.h +*** openwsn/07-App/heli/heli.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/heli/heli.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,30 **** +! #ifndef __HELI_H +! #define __HELI_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup Heli +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void heli_init(); +! void heli_trigger(); +! void heli_sendDone(OpenQueueEntry_t* msg, error_t error); +! void heli_receive(OpenQueueEntry_t* msg); +! bool heli_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,32 ---- +! #ifndef __HELI_H +! #define __HELI_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup Heli +! \{ +! */ +! +! +! #include "openwsn.h" +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void heli_init(); +! void heli_trigger(); +! void heli_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void heli_receive(OpenQueueEntry_t* msg); +! bool heli_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/heli/heli.py ../../../sys/net/openwsn/07-App/heli/heli.py +*** openwsn/07-App/heli/heli.py Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/heli/heli.py Wed Jan 15 13:48:27 2014 +*************** +*** 1,185 **** +! import socket +! import binascii +! import time +! import os +! import Tkinter +! import sys +! +! MOTOR_MAX = 800 +! MOTOR_MIN = 0 +! MOTOR_STEP = 10 +! +! myAddress = '' # means 'any suitable interface' +! myPort = 2158 +! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' +! hisPort = 2192 +! +! motor1_command = 0 +! motor2_command = 0 +! +! print "Testing heli..." +! +! def heli_up(): +! global motor1_command, motor2_command +! if (motor1_command+MOTOR_STEP<=MOTOR_MAX and motor2_command+MOTOR_STEP<=MOTOR_MAX): +! motor1_command += MOTOR_STEP +! motor2_command += MOTOR_STEP +! sendCommand() +! +! def heli_down(): +! global motor1_command, motor2_command +! if (motor1_command-MOTOR_STEP>=MOTOR_MIN and motor2_command-MOTOR_STEP>=MOTOR_MIN): +! motor1_command -= MOTOR_STEP +! motor2_command -= MOTOR_STEP +! sendCommand() +! +! def heli_left(): +! global motor1_command +! if (motor1_command+MOTOR_STEP<=MOTOR_MAX): +! motor1_command += MOTOR_STEP +! sendCommand() +! +! def heli_right(): +! global motor1_command +! if (motor1_command-MOTOR_STEP>=MOTOR_MIN): +! motor1_command -= MOTOR_STEP +! sendCommand() +! +! def heli_stop(): +! global motor1_command, motor2_command +! motor1_command = 0 +! motor2_command = 0 +! sendCommand() +! +! def heli_takeoff(): +! global motor1_command, motor2_command +! motor1_command = 0x0260 +! motor2_command = 0x0260 +! sendCommand() +! +! def heli_land(): +! global motor1_command, motor2_command +! motor1_command = 0x0200 +! motor2_command = 0x0200 +! sendCommand() +! +! def key_pressed(event): +! if (event.char=='i'): +! heli_up() +! if (event.char=='j'): +! heli_left() +! if (event.char=='l'): +! heli_right() +! if (event.char=='k'): +! heli_down() +! if (event.char==' '): +! heli_stop() +! if (event.char=='a'): +! heli_takeoff() +! if (event.char=='q'): +! heli_land() +! +! def gui_clicked(event): +! global motor1_command, motor2_command +! if (event.x>100 and event.x<200 and event.y>0 and event.y<100): +! heli_up() +! if (event.x>0 and event.x<100 and event.y>100 and event.y<200): +! heli_left() +! if (event.x>200 and event.x<300 and event.y>100 and event.y<200): +! heli_right() +! if (event.x>100 and event.x<200 and event.y>200 and event.y<300): +! heli_down() +! if (event.x>100 and event.x<200 and event.y>100 and event.y<200): +! heli_stop() +! if (event.x>200 and event.x<300 and event.y>0 and event.y<100): +! heli_takeoff() +! if (event.x>200 and event.x<300 and event.y>200 and event.y<300): +! heli_land() +! if (event.y>310 and event.y<340): +! motor1_command = event.x/300.0*800.0 +! sendCommand() +! if (event.y>340 and event.y<360): +! motor_diff = motor1_command-motor2_command +! motor1_command = (event.x/300.0*800.0)+(motor_diff/2.0) +! if motor1_command>800: +! motor1_command=800 +! motor2_command = (event.x/300.0*800.0)-(motor_diff/2.0) +! if motor2_command>800: +! motor2_command=800 +! sendCommand() +! if (event.y>360 and event.y<390): +! motor2_command = event.x/300.0*800.0 +! sendCommand() +! +! def sendCommand(): +! #update the sliders +! buttonCanvas.delete("temp_slider") +! buttonCanvas.create_rectangle(0 ,310,(motor1_command/800.0)*300.0,340,fill="yellow",tag="temp_slider") +! buttonCanvas.create_rectangle(0 ,360,(motor2_command/800.0)*300.0,390,fill="yellow",tag="temp_slider") +! #send the command over UDP +! request = [] +! request.append(chr(int(motor1_command/256))) +! request.append(chr(int(motor1_command%256))) +! request.append(chr(int(motor2_command/256))) +! request.append(chr(int(motor2_command%256))) +! request = ''.join(request) +! hisAddress = addressText.get(1.0,Tkinter.END) +! hisAddress = hisAddress[0:len(hisAddress)-1] +! try: +! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) +! socket_handler.settimeout(5) +! socket_handler.bind((myAddress,myPort)) +! socket_handler.sendto(request,(hisAddress,hisPort)) +! except: +! addressText.config(background="red") +! else: +! addressText.config(background="green") +! +! #================================= GUI functions ==================== +! +! def releaseAndQuit(): +! root.quit() +! sys.exit() +! +! #================================= GUI definition =================== +! +! root=Tkinter.Tk() +! root.title("OpenHelicopter") +! root.protocol("WM_DELETE_WINDOW",releaseAndQuit) +! root.resizable(0,0) +! +! root.bind("",key_pressed) +! +! addressText = Tkinter.Text(root,width=50,height=1) +! #displayElements[motePort]["cellTable"]["TextField"].delete("1.0",Tkinter.END) +! addressText.insert(Tkinter.END,'2001:470:1f05:dff:1415:9209:22b:51') +! addressText.grid(row=0,column=0) +! +! buttonCanvas=Tkinter.Canvas(root,width=300,height=400) +! buttonCanvas.bind("",gui_clicked) +! buttonCanvas.bind("",gui_clicked) +! buttonCanvas.bind("",gui_clicked) +! buttonCanvas.create_rectangle(100, 0,200,100,fill="blue") +! buttonCanvas.create_text(150,50,text="up ") +! buttonCanvas.create_rectangle( 0,100,100,200,fill="blue") +! buttonCanvas.create_text(50,150,text="left ") +! buttonCanvas.create_rectangle(200,100,300,200,fill="blue") +! buttonCanvas.create_text(250,150,text="right ") +! buttonCanvas.create_rectangle(100,200,200,300,fill="blue") +! buttonCanvas.create_text(150,250,text="down ") +! buttonCanvas.create_oval(120,120,180,180,fill="red") +! buttonCanvas.create_text(150,150,text="stop!\n") +! buttonCanvas.create_oval(220, 20,280, 80,fill="green") +! buttonCanvas.create_text(250, 50,text="takeoff ") +! buttonCanvas.create_oval(220,220,280,280,fill="green") +! buttonCanvas.create_text(250,250,text="land ") +! +! buttonCanvas.create_rectangle(0 ,310,300,340) +! buttonCanvas.create_text(150,325,text="motor 1") +! buttonCanvas.create_rectangle(0 ,360,300,390) +! buttonCanvas.create_text(150,375,text="motor 2") +! buttonCanvas.grid(row=1,column=0) +! +! #================================= main ============================= +! +! root.mainloop() +--- 1,185 ---- +! import socket +! import binascii +! import time +! import os +! import Tkinter +! import sys +! +! MOTOR_MAX = 800 +! MOTOR_MIN = 0 +! MOTOR_STEP = 10 +! +! myAddress = '' # means 'any suitable interface' +! myPort = 2158 +! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' +! hisPort = 2192 +! +! motor1_command = 0 +! motor2_command = 0 +! +! print "Testing heli..." +! +! def heli_up(): +! global motor1_command, motor2_command +! if (motor1_command+MOTOR_STEP<=MOTOR_MAX and motor2_command+MOTOR_STEP<=MOTOR_MAX): +! motor1_command += MOTOR_STEP +! motor2_command += MOTOR_STEP +! sendCommand() +! +! def heli_down(): +! global motor1_command, motor2_command +! if (motor1_command-MOTOR_STEP>=MOTOR_MIN and motor2_command-MOTOR_STEP>=MOTOR_MIN): +! motor1_command -= MOTOR_STEP +! motor2_command -= MOTOR_STEP +! sendCommand() +! +! def heli_left(): +! global motor1_command +! if (motor1_command+MOTOR_STEP<=MOTOR_MAX): +! motor1_command += MOTOR_STEP +! sendCommand() +! +! def heli_right(): +! global motor1_command +! if (motor1_command-MOTOR_STEP>=MOTOR_MIN): +! motor1_command -= MOTOR_STEP +! sendCommand() +! +! def heli_stop(): +! global motor1_command, motor2_command +! motor1_command = 0 +! motor2_command = 0 +! sendCommand() +! +! def heli_takeoff(): +! global motor1_command, motor2_command +! motor1_command = 0x0260 +! motor2_command = 0x0260 +! sendCommand() +! +! def heli_land(): +! global motor1_command, motor2_command +! motor1_command = 0x0200 +! motor2_command = 0x0200 +! sendCommand() +! +! def key_pressed(event): +! if (event.char=='i'): +! heli_up() +! if (event.char=='j'): +! heli_left() +! if (event.char=='l'): +! heli_right() +! if (event.char=='k'): +! heli_down() +! if (event.char==' '): +! heli_stop() +! if (event.char=='a'): +! heli_takeoff() +! if (event.char=='q'): +! heli_land() +! +! def gui_clicked(event): +! global motor1_command, motor2_command +! if (event.x>100 and event.x<200 and event.y>0 and event.y<100): +! heli_up() +! if (event.x>0 and event.x<100 and event.y>100 and event.y<200): +! heli_left() +! if (event.x>200 and event.x<300 and event.y>100 and event.y<200): +! heli_right() +! if (event.x>100 and event.x<200 and event.y>200 and event.y<300): +! heli_down() +! if (event.x>100 and event.x<200 and event.y>100 and event.y<200): +! heli_stop() +! if (event.x>200 and event.x<300 and event.y>0 and event.y<100): +! heli_takeoff() +! if (event.x>200 and event.x<300 and event.y>200 and event.y<300): +! heli_land() +! if (event.y>310 and event.y<340): +! motor1_command = event.x/300.0*800.0 +! sendCommand() +! if (event.y>340 and event.y<360): +! motor_diff = motor1_command-motor2_command +! motor1_command = (event.x/300.0*800.0)+(motor_diff/2.0) +! if motor1_command>800: +! motor1_command=800 +! motor2_command = (event.x/300.0*800.0)-(motor_diff/2.0) +! if motor2_command>800: +! motor2_command=800 +! sendCommand() +! if (event.y>360 and event.y<390): +! motor2_command = event.x/300.0*800.0 +! sendCommand() +! +! def sendCommand(): +! #update the sliders +! buttonCanvas.delete("temp_slider") +! buttonCanvas.create_rectangle(0 ,310,(motor1_command/800.0)*300.0,340,fill="yellow",tag="temp_slider") +! buttonCanvas.create_rectangle(0 ,360,(motor2_command/800.0)*300.0,390,fill="yellow",tag="temp_slider") +! #send the command over UDP +! request = [] +! request.append(chr(int(motor1_command/256))) +! request.append(chr(int(motor1_command%256))) +! request.append(chr(int(motor2_command/256))) +! request.append(chr(int(motor2_command%256))) +! request = ''.join(request) +! hisAddress = addressText.get(1.0,Tkinter.END) +! hisAddress = hisAddress[0:len(hisAddress)-1] +! try: +! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) +! socket_handler.settimeout(5) +! socket_handler.bind((myAddress,myPort)) +! socket_handler.sendto(request,(hisAddress,hisPort)) +! except: +! addressText.config(background="red") +! else: +! addressText.config(background="green") +! +! #================================= GUI functions ==================== +! +! def releaseAndQuit(): +! root.quit() +! sys.exit() +! +! #================================= GUI definition =================== +! +! root=Tkinter.Tk() +! root.title("OpenHelicopter") +! root.protocol("WM_DELETE_WINDOW",releaseAndQuit) +! root.resizable(0,0) +! +! root.bind("",key_pressed) +! +! addressText = Tkinter.Text(root,width=50,height=1) +! #displayElements[motePort]["cellTable"]["TextField"].delete("1.0",Tkinter.END) +! addressText.insert(Tkinter.END,'2001:470:1f05:dff:1415:9209:22b:51') +! addressText.grid(row=0,column=0) +! +! buttonCanvas=Tkinter.Canvas(root,width=300,height=400) +! buttonCanvas.bind("",gui_clicked) +! buttonCanvas.bind("",gui_clicked) +! buttonCanvas.bind("",gui_clicked) +! buttonCanvas.create_rectangle(100, 0,200,100,fill="blue") +! buttonCanvas.create_text(150,50,text="up ") +! buttonCanvas.create_rectangle( 0,100,100,200,fill="blue") +! buttonCanvas.create_text(50,150,text="left ") +! buttonCanvas.create_rectangle(200,100,300,200,fill="blue") +! buttonCanvas.create_text(250,150,text="right ") +! buttonCanvas.create_rectangle(100,200,200,300,fill="blue") +! buttonCanvas.create_text(150,250,text="down ") +! buttonCanvas.create_oval(120,120,180,180,fill="red") +! buttonCanvas.create_text(150,150,text="stop!\n") +! buttonCanvas.create_oval(220, 20,280, 80,fill="green") +! buttonCanvas.create_text(250, 50,text="takeoff ") +! buttonCanvas.create_oval(220,220,280,280,fill="green") +! buttonCanvas.create_text(250,250,text="land ") +! +! buttonCanvas.create_rectangle(0 ,310,300,340) +! buttonCanvas.create_text(150,325,text="motor 1") +! buttonCanvas.create_rectangle(0 ,360,300,390) +! buttonCanvas.create_text(150,375,text="motor 2") +! buttonCanvas.grid(row=1,column=0) +! +! #================================= main ============================= +! +! root.mainloop() +diff -crB openwsn/07-App/imu/imu.c ../../../sys/net/openwsn/07-App/imu/imu.c +*** openwsn/07-App/imu/imu.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/imu/imu.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,123 **** +! #include "openwsn.h" +! #include "imu.h" +! //drivers +! #include "gyro.h" +! #include "large_range_accel.h" +! #include "magnetometer.h" +! #include "sensitive_accel_temperature.h" +! //openwsn stack +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! uint8_t mesurements_left; +! OpenQueueEntry_t* pktReceived; +! } imu_vars_t; +! +! imu_vars_t imu_vars; +! +! //=========================== prototypes ====================================== +! +! void imu_send(); +! void imu_reset(); +! +! //=========================== public ========================================== +! +! void imu_init() { +! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) +! gyro_init(); +! large_range_accel_init(); +! magnetometer_init(); +! sensitive_accel_temperature_init(); +! } +! imu_vars.mesurements_left = 0; +! } +! +! //this is called when the UdpGina button is pressed on the OpenVisualizer interface +! void imu_trigger() { +! } +! +! //I just received a request, send a packet with IMU data +! void imu_receive(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_IMU; +! if (imu_vars.pktReceived==NULL) { +! imu_vars.pktReceived = msg; +! imu_vars.mesurements_left = imu_vars.pktReceived->payload[0]; +! imu_send(); +! } else { +! openqueue_freePacketBuffer(msg); +! } +! } +! +! //I just sent a IMU packet, check I need to resend one +! void imu_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_IMU; +! if (msg->creator!=COMPONENT_IMU) { +! openserial_printError(COMPONENT_IMU,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! if (imu_vars.mesurements_left>0) { +! imu_send(); +! } else { +! imu_reset(); +! } +! } +! +! bool imu_debugPrint() { +! return FALSE; +! } +! +! //=========================== private ========================================= +! +! void imu_send() { +! OpenQueueEntry_t* packetToSend; +! packetToSend = openqueue_getFreePacketBuffer(); +! if (packetToSend==NULL) { +! openserial_printError(COMPONENT_IMU,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! imu_reset(); +! return; +! } +! packetToSend->creator = COMPONENT_IMU; +! packetToSend->owner = COMPONENT_IMU; +! packetToSend->l4_protocol = IANA_UDP; +! packetToSend->l4_sourcePortORicmpv6Type = imu_vars.pktReceived->l4_destination_port; +! packetToSend->l4_destination_port = imu_vars.pktReceived->l4_sourcePortORicmpv6Type; +! packetToSend->l3_destinationORsource.type = ADDR_128B; +! memcpy(&(packetToSend->l3_destinationORsource.addr_128b[0]), +! &(imu_vars.pktReceived->l3_destinationORsource.addr_128b[0]), +! 16); +! //payload, gyro data +! packetfunctions_reserveHeaderSize(packetToSend,8); +! gyro_get_measurement(&(packetToSend->payload[0])); +! //payload, large_range_accel data +! packetfunctions_reserveHeaderSize(packetToSend,6); +! large_range_accel_get_measurement(&(packetToSend->payload[0])); +! //payload, magnetometer data +! packetfunctions_reserveHeaderSize(packetToSend,6); +! magnetometer_get_measurement(&(packetToSend->payload[0])); +! //payload, sensitive_accel_temperature data +! packetfunctions_reserveHeaderSize(packetToSend,10); +! sensitive_accel_temperature_get_measurement(&(packetToSend->payload[0])); +! //send packet +! if ((openudp_send(packetToSend))==E_FAIL) { +! openqueue_freePacketBuffer(packetToSend); +! imu_reset(); +! } +! imu_vars.mesurements_left--; +! } +! +! void imu_reset() { +! imu_vars.mesurements_left=0; +! if (imu_vars.pktReceived!=NULL) { +! openqueue_freePacketBuffer(imu_vars.pktReceived); +! imu_vars.pktReceived = NULL; +! } +! } +--- 1,123 ---- +! #include "openwsn.h" +! #include "imu.h" +! //drivers +! #include "gyro.h" +! #include "large_range_accel.h" +! #include "magnetometer.h" +! #include "sensitive_accel_temperature.h" +! //openwsn stack +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! uint8_t mesurements_left; +! OpenQueueEntry_t* pktReceived; +! } imu_vars_t; +! +! imu_vars_t imu_vars; +! +! //=========================== prototypes ====================================== +! +! void imu_send(); +! void imu_reset(); +! +! //=========================== public ========================================== +! +! void imu_init() { +! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) +! gyro_init(); +! large_range_accel_init(); +! magnetometer_init(); +! sensitive_accel_temperature_init(); +! } +! imu_vars.mesurements_left = 0; +! } +! +! //this is called when the UdpGina button is pressed on the OpenVisualizer interface +! void imu_trigger() { +! } +! +! //I just received a request, send a packet with IMU data +! void imu_receive(OpenQueueEntry_t* msg) { +! msg->owner = COMPONENT_IMU; +! if (imu_vars.pktReceived==NULL) { +! imu_vars.pktReceived = msg; +! imu_vars.mesurements_left = imu_vars.pktReceived->payload[0]; +! imu_send(); +! } else { +! openqueue_freePacketBuffer(msg); +! } +! } +! +! //I just sent a IMU packet, check I need to resend one +! void imu_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_IMU; +! if (msg->creator!=COMPONENT_IMU) { +! openserial_printError(COMPONENT_IMU,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! if (imu_vars.mesurements_left>0) { +! imu_send(); +! } else { +! imu_reset(); +! } +! } +! +! bool imu_debugPrint() { +! return FALSE; +! } +! +! //=========================== private ========================================= +! +! void imu_send() { +! OpenQueueEntry_t* packetToSend; +! packetToSend = openqueue_getFreePacketBuffer(); +! if (packetToSend==NULL) { +! openserial_printError(COMPONENT_IMU,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! imu_reset(); +! return; +! } +! packetToSend->creator = COMPONENT_IMU; +! packetToSend->owner = COMPONENT_IMU; +! packetToSend->l4_protocol = IANA_UDP; +! packetToSend->l4_sourcePortORicmpv6Type = imu_vars.pktReceived->l4_destination_port; +! packetToSend->l4_destination_port = imu_vars.pktReceived->l4_sourcePortORicmpv6Type; +! packetToSend->l3_destinationORsource.type = ADDR_128B; +! memcpy(&(packetToSend->l3_destinationORsource.addr_128b[0]), +! &(imu_vars.pktReceived->l3_destinationORsource.addr_128b[0]), +! 16); +! //payload, gyro data +! packetfunctions_reserveHeaderSize(packetToSend,8); +! gyro_get_measurement(&(packetToSend->payload[0])); +! //payload, large_range_accel data +! packetfunctions_reserveHeaderSize(packetToSend,6); +! large_range_accel_get_measurement(&(packetToSend->payload[0])); +! //payload, magnetometer data +! packetfunctions_reserveHeaderSize(packetToSend,6); +! magnetometer_get_measurement(&(packetToSend->payload[0])); +! //payload, sensitive_accel_temperature data +! packetfunctions_reserveHeaderSize(packetToSend,10); +! sensitive_accel_temperature_get_measurement(&(packetToSend->payload[0])); +! //send packet +! if ((openudp_send(packetToSend))==E_FAIL) { +! openqueue_freePacketBuffer(packetToSend); +! imu_reset(); +! } +! imu_vars.mesurements_left--; +! } +! +! void imu_reset() { +! imu_vars.mesurements_left=0; +! if (imu_vars.pktReceived!=NULL) { +! openqueue_freePacketBuffer(imu_vars.pktReceived); +! imu_vars.pktReceived = NULL; +! } +! } +diff -crB openwsn/07-App/imu/imu.h ../../../sys/net/openwsn/07-App/imu/imu.h +*** openwsn/07-App/imu/imu.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/imu/imu.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,30 **** +! #ifndef __IMU_H +! #define __IMU_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup imu +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void imu_init(); +! void imu_trigger(); +! void imu_sendDone(OpenQueueEntry_t* msg, error_t error); +! void imu_receive(OpenQueueEntry_t* msg); +! bool imu_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,30 ---- +! #ifndef __IMU_H +! #define __IMU_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup imu +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void imu_init(); +! void imu_trigger(); +! void imu_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void imu_receive(OpenQueueEntry_t* msg); +! bool imu_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/imu/imu.py ../../../sys/net/openwsn/07-App/imu/imu.py +*** openwsn/07-App/imu/imu.py Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/imu/imu.py Wed Jan 15 13:48:27 2014 +*************** +*** 1,62 **** +! import socket +! import binascii +! import time +! import os +! +! num_measurements = str(chr(0x64)) # (100)d +! myAddress = '' # means 'any suitable interface' +! myPort = 2158 +! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' +! hisPort = 2190 +! +! print "Testing imu..." +! +! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) +! socket_handler.settimeout(5) +! socket_handler.bind((myAddress,myPort)) +! socket_handler.sendto(num_measurements,(hisAddress,hisPort)) +! print "\nrequest "+myAddress+"%"+str(myPort)+" -> "+hisAddress+"%"+str(hisPort) +! print num_measurements+" ("+str(len(num_measurements))+" bytes)" +! +! time_first = time.time() +! replycounter = 0 +! while (1): +! try: +! reply,dist_addr = socket_handler.recvfrom(1024) +! except socket.timeout: +! print "\nno further replies, it seems\n" +! break +! else: +! time_last = time.time() +! os.system("CLS") +! print "\nreply "+str(replycounter)+": "+str(dist_addr[0])+"%"+str(dist_addr[1])+" -> "+myAddress+"%"+str(myPort)+" ("+str(len(reply))+" bytes)\n" +! replycounter += 1 +! +! print "sensitive_accel X : "+str(ord(reply[0])) +! print " Y : "+binascii.hexlify(reply[ 2: 4]) +! print " Z1 : "+binascii.hexlify(reply[ 4: 6]) +! print " Z3 : "+binascii.hexlify(reply[ 6: 8])+"\n" +! +! print "temperature : "+binascii.hexlify(reply[ 8:10])+"\n" +! +! print "magnetometer X : "+binascii.hexlify(reply[10:12]) +! print " Y : "+binascii.hexlify(reply[12:14]) +! print " Z : "+binascii.hexlify(reply[14:16])+"\n" +! +! print "large_range_accel X : "+binascii.hexlify(reply[16:18]) +! print " Y : "+binascii.hexlify(reply[18:20]) +! print " Z : "+binascii.hexlify(reply[20:22])+"\n" +! +! print "gyro_temperature : "+binascii.hexlify(reply[22:24]) +! print "gyro X : "+binascii.hexlify(reply[24:26]) +! print " Y : "+binascii.hexlify(reply[26:28]) +! print " Z : "+binascii.hexlify(reply[28:30]) +! +! socket_handler.close() +! +! try: +! print str(replycounter)+" replies in "+str(time_last-time_first)+"s (one every "+str((time_last-time_first)/(replycounter-1))+"s)" +! except: +! pass +! +! raw_input("\nPress return to close this window...") +--- 1,62 ---- +! import socket +! import binascii +! import time +! import os +! +! num_measurements = str(chr(0x64)) # (100)d +! myAddress = '' # means 'any suitable interface' +! myPort = 2158 +! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' +! hisPort = 2190 +! +! print "Testing imu..." +! +! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) +! socket_handler.settimeout(5) +! socket_handler.bind((myAddress,myPort)) +! socket_handler.sendto(num_measurements,(hisAddress,hisPort)) +! print "\nrequest "+myAddress+"%"+str(myPort)+" -> "+hisAddress+"%"+str(hisPort) +! print num_measurements+" ("+str(len(num_measurements))+" bytes)" +! +! time_first = time.time() +! replycounter = 0 +! while (1): +! try: +! reply,dist_addr = socket_handler.recvfrom(1024) +! except socket.timeout: +! print "\nno further replies, it seems\n" +! break +! else: +! time_last = time.time() +! os.system("CLS") +! print "\nreply "+str(replycounter)+": "+str(dist_addr[0])+"%"+str(dist_addr[1])+" -> "+myAddress+"%"+str(myPort)+" ("+str(len(reply))+" bytes)\n" +! replycounter += 1 +! +! print "sensitive_accel X : "+str(ord(reply[0])) +! print " Y : "+binascii.hexlify(reply[ 2: 4]) +! print " Z1 : "+binascii.hexlify(reply[ 4: 6]) +! print " Z3 : "+binascii.hexlify(reply[ 6: 8])+"\n" +! +! print "temperature : "+binascii.hexlify(reply[ 8:10])+"\n" +! +! print "magnetometer X : "+binascii.hexlify(reply[10:12]) +! print " Y : "+binascii.hexlify(reply[12:14]) +! print " Z : "+binascii.hexlify(reply[14:16])+"\n" +! +! print "large_range_accel X : "+binascii.hexlify(reply[16:18]) +! print " Y : "+binascii.hexlify(reply[18:20]) +! print " Z : "+binascii.hexlify(reply[20:22])+"\n" +! +! print "gyro_temperature : "+binascii.hexlify(reply[22:24]) +! print "gyro X : "+binascii.hexlify(reply[24:26]) +! print " Y : "+binascii.hexlify(reply[26:28]) +! print " Z : "+binascii.hexlify(reply[28:30]) +! +! socket_handler.close() +! +! try: +! print str(replycounter)+" replies in "+str(time_last-time_first)+"s (one every "+str((time_last-time_first)/(replycounter-1))+"s)" +! except: +! pass +! +! raw_input("\nPress return to close this window...") +diff -crB openwsn/07-App/layerdebug/layerdebug.c ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.c +*** openwsn/07-App/layerdebug/layerdebug.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,301 **** +! #include "openwsn.h" +! #include "layerdebug.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "scheduler.h" +! +! +! // include layer files to debug +! #include "neighbors.h" +! #include "schedule.h" +! //=========================== defines ========================================= +! +! /// inter-packet period (in ms) +! #define DEBUGPERIODNBS 11000 +! #define DEBUGPERIODSCH 7000 +! +! const uint8_t schedule_layerdebug_path0[] = "d_s"; // debug/scheduling +! const uint8_t neighbors_layerdebug_path0[] = "d_n"; // debug/neighbours +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t schdesc; ///< descriptor for shedule table +! coap_resource_desc_t nbsdesc; ///< descriptor for neigbour table +! opentimer_id_t schtimerId; ///< schedule timer +! opentimer_id_t nbstimerId; ///< neigbour timer +! } layerdebug_vars_t; +! +! layerdebug_vars_t layerdebug_vars; +! +! //=========================== prototypes ====================================== +! +! error_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! +! +! error_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! +! void layerdebug_timer_schedule_cb(); +! void layerdebug_timer_neighbors_cb(); +! +! void layerdebug_task_schedule_cb(); +! void layerdebug_task_neighbors_cb(); +! +! void layerdebug_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void layerdebug_init() { +! +! // prepare the resource descriptor for the scheduling path +! layerdebug_vars.schdesc.path0len = sizeof(schedule_layerdebug_path0)-1; +! layerdebug_vars.schdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); +! layerdebug_vars.schdesc.path1len = 0; +! layerdebug_vars.schdesc.path1val = NULL; +! layerdebug_vars.schdesc.componentID = COMPONENT_LAYERDEBUG; +! layerdebug_vars.schdesc.callbackRx = &layerdebug_schedule_receive; +! layerdebug_vars.schdesc.callbackSendDone = &layerdebug_sendDone; +! opencoap_register(&layerdebug_vars.schdesc); +! +! layerdebug_vars.schtimerId = opentimers_start(DEBUGPERIODSCH, +! TIMER_PERIODIC,TIME_MS, +! layerdebug_timer_schedule_cb); +! +! // prepare the resource descriptor for the neighbors path +! layerdebug_vars.nbsdesc.path0len = sizeof(schedule_layerdebug_path0)-1; +! layerdebug_vars.nbsdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); +! layerdebug_vars.nbsdesc.path1len = 0; +! layerdebug_vars.nbsdesc.path1val = NULL; +! layerdebug_vars.nbsdesc.componentID = COMPONENT_LAYERDEBUG; +! layerdebug_vars.nbsdesc.callbackRx = &layerdebug_neighbors_receive; +! layerdebug_vars.nbsdesc.callbackSendDone = &layerdebug_sendDone; +! opencoap_register(&layerdebug_vars.nbsdesc); +! +! layerdebug_vars.nbstimerId = opentimers_start(DEBUGPERIODNBS, +! TIMER_PERIODIC,TIME_MS, +! layerdebug_timer_neighbors_cb); +! } +! +! //=========================== private ========================================= +! +! //timer fired, but we don't want to execute task in ISR mode +! //instead, push task to scheduler with COAP priority, and let scheduler take care of it +! void layerdebug_timer_schedule_cb(){ +! scheduler_push_task(layerdebug_task_schedule_cb,TASKPRIO_COAP); +! } +! +! void layerdebug_timer_neighbors_cb(){ +! scheduler_push_task(layerdebug_task_neighbors_cb,TASKPRIO_COAP); +! } +! +! //schedule stats +! void layerdebug_task_schedule_cb() { +! OpenQueueEntry_t* pkt; +! error_t outcome; +! uint8_t numOptions; +! uint8_t size; +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_LAYERDEBUG; +! pkt->owner = COMPONENT_LAYERDEBUG; +! // CoAP payload +! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; +! packetfunctions_reserveHeaderSize(pkt,size);//reserve for some schedule entries +! //get the schedule information from the mac layer +! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)pkt->payload); +! +! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of schedule entries +! pkt->payload[0] = MAXACTIVESLOTS; +! +! +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(schedule_layerdebug_path0)-1); +! memcpy(&pkt->payload[0],&schedule_layerdebug_path0,sizeof(schedule_layerdebug_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! sizeof(schedule_layerdebug_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &layerdebug_vars.schdesc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! //neighbours stats +! void layerdebug_task_neighbors_cb() { +! +! OpenQueueEntry_t* pkt; +! error_t outcome; +! uint8_t numOptions; +! uint8_t size; +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_LAYERDEBUG; +! pkt->owner = COMPONENT_LAYERDEBUG; +! // CoAP payload +! +! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent +! packetfunctions_reserveHeaderSize(pkt,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries +! +! debugNetPrint_neighbors((netDebugNeigborEntry_t*) pkt->payload); +! +! //now we know the size of the neihbours. Put it on the packet. +! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of neighbours entries +! pkt->payload[0] = size; +! +! //coap options +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(neighbors_layerdebug_path0)-1); +! memcpy(&pkt->payload[0],&neighbors_layerdebug_path0,sizeof(neighbors_layerdebug_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! sizeof(neighbors_layerdebug_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &layerdebug_vars.nbsdesc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void layerdebug_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); +! } +! +! +! error_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! uint8_t size; +! +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current schedule value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; +! packetfunctions_reserveHeaderSize(msg,size);//reserve for some schedule entries +! //get the schedule information from the mac layer +! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)msg->payload); +! +! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of schedule entries +! msg->payload[0] = MAXACTIVESLOTS; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! error_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! uint8_t size; +! +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current schedule value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent +! packetfunctions_reserveHeaderSize(msg,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries +! +! debugNetPrint_neighbors((netDebugNeigborEntry_t*)msg->payload); +! +! //now we know the size of the neihbours. Put it on the packet. +! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of neighbours entries +! msg->payload[0] = size; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; + } +\ No newline at end of file +--- 1,310 ---- +! #include "openwsn.h" +! #include "layerdebug.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "scheduler.h" +! #include "IEEE802154E.h" +! #include "idmanager.h" +! +! // include layer files to debug +! #include "neighbors.h" +! #include "schedule.h" +! //=========================== defines ========================================= +! +! /// inter-packet period (in ms) +! #define DEBUGPERIODNBS 11000 +! #define DEBUGPERIODSCH 7000 +! +! const uint8_t schedule_layerdebug_path0[] = "d_s"; // debug/scheduling +! const uint8_t neighbors_layerdebug_path0[] = "d_n"; // debug/neighbours +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t schdesc; ///< descriptor for shedule table +! coap_resource_desc_t nbsdesc; ///< descriptor for neigbour table +! opentimer_id_t schtimerId; ///< schedule timer +! opentimer_id_t nbstimerId; ///< neigbour timer +! } layerdebug_vars_t; +! +! layerdebug_vars_t layerdebug_vars; +! +! //=========================== prototypes ====================================== +! +! owerror_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! +! +! owerror_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! +! void layerdebug_timer_schedule_cb(); +! void layerdebug_timer_neighbors_cb(); +! +! void layerdebug_task_schedule_cb(); +! void layerdebug_task_neighbors_cb(); +! +! void layerdebug_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void layerdebug_init() { +! +! // prepare the resource descriptor for the scheduling path +! layerdebug_vars.schdesc.path0len = sizeof(schedule_layerdebug_path0)-1; +! layerdebug_vars.schdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); +! layerdebug_vars.schdesc.path1len = 0; +! layerdebug_vars.schdesc.path1val = NULL; +! layerdebug_vars.schdesc.componentID = COMPONENT_LAYERDEBUG; +! layerdebug_vars.schdesc.callbackRx = &layerdebug_schedule_receive; +! layerdebug_vars.schdesc.callbackSendDone = &layerdebug_sendDone; +! opencoap_register(&layerdebug_vars.schdesc); +! +! layerdebug_vars.schtimerId = opentimers_start(DEBUGPERIODSCH, +! TIMER_PERIODIC,TIME_MS, +! layerdebug_timer_schedule_cb); +! +! // prepare the resource descriptor for the neighbors path +! layerdebug_vars.nbsdesc.path0len = sizeof(schedule_layerdebug_path0)-1; +! layerdebug_vars.nbsdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); +! layerdebug_vars.nbsdesc.path1len = 0; +! layerdebug_vars.nbsdesc.path1val = NULL; +! layerdebug_vars.nbsdesc.componentID = COMPONENT_LAYERDEBUG; +! layerdebug_vars.nbsdesc.callbackRx = &layerdebug_neighbors_receive; +! layerdebug_vars.nbsdesc.callbackSendDone = &layerdebug_sendDone; +! opencoap_register(&layerdebug_vars.nbsdesc); +! +! layerdebug_vars.nbstimerId = opentimers_start(DEBUGPERIODNBS, +! TIMER_PERIODIC,TIME_MS, +! layerdebug_timer_neighbors_cb); +! } +! +! //=========================== private ========================================= +! +! //timer fired, but we don't want to execute task in ISR mode +! //instead, push task to scheduler with COAP priority, and let scheduler take care of it +! void layerdebug_timer_schedule_cb(){ +! scheduler_push_task(layerdebug_task_schedule_cb,TASKPRIO_COAP); +! } +! +! void layerdebug_timer_neighbors_cb(){ +! scheduler_push_task(layerdebug_task_neighbors_cb,TASKPRIO_COAP); +! } +! +! //schedule stats +! void layerdebug_task_schedule_cb() { +! OpenQueueEntry_t* pkt; +! owerror_t outcome; +! uint8_t numOptions; +! uint8_t size; +! +! // don't run if not synch +! if (ieee154e_isSynch() == FALSE) return; +! +! // don't run on dagroot +! if (idmanager_getIsDAGroot()) { +! opentimers_stop( layerdebug_vars.schtimerId); +! opentimers_stop( layerdebug_vars.nbstimerId); +! return; +! } +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_LAYERDEBUG; +! pkt->owner = COMPONENT_LAYERDEBUG; +! // CoAP payload +! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; +! packetfunctions_reserveHeaderSize(pkt,size);//reserve for some schedule entries +! //get the schedule information from the mac layer +! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)pkt->payload); +! +! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of schedule entries +! pkt->payload[0] = MAXACTIVESLOTS; +! +! +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(schedule_layerdebug_path0)-1); +! memcpy(&pkt->payload[0],&schedule_layerdebug_path0,sizeof(schedule_layerdebug_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(schedule_layerdebug_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &layerdebug_vars.schdesc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! //neighbours stats +! void layerdebug_task_neighbors_cb() { +! +! OpenQueueEntry_t* pkt; +! owerror_t outcome; +! uint8_t numOptions; +! uint8_t size; +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_LAYERDEBUG; +! pkt->owner = COMPONENT_LAYERDEBUG; +! // CoAP payload +! +! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent +! packetfunctions_reserveHeaderSize(pkt,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries +! +! debugNetPrint_neighbors((netDebugNeigborEntry_t*) pkt->payload); +! +! //now we know the size of the neihbours. Put it on the packet. +! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of neighbours entries +! pkt->payload[0] = size; +! +! //coap options +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(neighbors_layerdebug_path0)-1); +! memcpy(&pkt->payload[0],&neighbors_layerdebug_path0,sizeof(neighbors_layerdebug_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(neighbors_layerdebug_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &layerdebug_vars.nbsdesc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void layerdebug_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); +! } +! +! +! owerror_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! uint8_t size; +! +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current schedule value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; +! packetfunctions_reserveHeaderSize(msg,size);//reserve for some schedule entries +! //get the schedule information from the mac layer +! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)msg->payload); +! +! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of schedule entries +! msg->payload[0] = MAXACTIVESLOTS; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! owerror_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! uint8_t size; +! +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current schedule value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent +! packetfunctions_reserveHeaderSize(msg,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries +! +! debugNetPrint_neighbors((netDebugNeigborEntry_t*)msg->payload); +! +! //now we know the size of the neihbours. Put it on the packet. +! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of neighbours entries +! msg->payload[0] = size; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; + } +\ No newline at end of file +diff -crB openwsn/07-App/layerdebug/layerdebug.h ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.h +*** openwsn/07-App/layerdebug/layerdebug.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __LAYERDEBUG_H +! #define __LAYERDEBUG_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rT +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void layerdebug_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __LAYERDEBUG_H +! #define __LAYERDEBUG_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rT +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void layerdebug_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/ohlone/Makefile ../../../sys/net/openwsn/07-App/ohlone/Makefile +*** openwsn/07-App/ohlone/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/ohlone/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/ohlone/ohlone.c ../../../sys/net/openwsn/07-App/ohlone/ohlone.c +*** openwsn/07-App/ohlone/ohlone.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/ohlone/ohlone.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,120 **** +! #include "openwsn.h" +! #include "ohlone.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "opentcp.h" +! +! #include "ohlone_webpages.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! OpenQueueEntry_t* pkt; +! bool sending; +! uint16_t httpChunk; +! uint8_t getRequest[TCP_DEFAULT_WINDOW_SIZE]; +! } ohlone_vars_t; +! +! ohlone_vars_t ohlone_vars; +! +! //=========================== prototypes ====================================== +! +! void ohlone_sendpkt(); +! bool ohlone_check4chars(uint8_t c1[4], uint8_t c2[4]); +! +! //=========================== public ========================================== +! +! void ohlone_init() { +! ohlone_vars.httpChunk = 0; +! ohlone_vars.getRequest[0] = '/'; +! ohlone_vars.getRequest[1] = ' '; +! ohlone_webpages_init(); +! } +! +! bool ohlone_shouldIlisten() { +! return TRUE; +! } +! +! void ohlone_sendpkt() { +! uint8_t buffer[TCP_DEFAULT_WINDOW_SIZE]; +! uint8_t buffer_len; +! +! buffer_len = ohlone_webpage(ohlone_vars.getRequest, ohlone_vars.httpChunk++, buffer); +! +! if (buffer_len == 0) { +! // No more to send +! // close TCP session, but keep listening +! ohlone_vars.getRequest[0] = '/'; +! ohlone_vars.getRequest[1] = ' '; +! opentcp_close(); +! return; +! } +! +! ohlone_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_OHLONE); +! if (ohlone_vars.pkt==NULL) { +! openserial_printError(COMPONENT_OHLONE,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! opentcp_close(); +! return; +! } +! ohlone_vars.pkt->creator = COMPONENT_OHLONE; +! ohlone_vars.pkt->owner = COMPONENT_OHLONE; +! +! packetfunctions_reserveHeaderSize(ohlone_vars.pkt, buffer_len); +! memcpy(ohlone_vars.pkt->payload, buffer, buffer_len); +! +! if ((opentcp_send(ohlone_vars.pkt))==E_FAIL) { +! openqueue_freePacketBuffer(ohlone_vars.pkt); +! opentcp_close(); +! } +! +! } +! +! bool ohlone_check4chars(uint8_t c1[4], uint8_t c2[4]) { +! return ((c1[0] == c2[0]) && +! (c1[1] == c2[1]) && +! (c1[2] == c2[2]) && +! (c1[3] == c2[3])); +! } +! +! void ohlone_receive(OpenQueueEntry_t* msg) { +! uint8_t payload_index; +! +! for (payload_index=0;payload_indexlength-3;payload_index++) { +! if (ohlone_check4chars(msg->payload+payload_index,(unsigned char *) "GET ")) +! memcpy(ohlone_vars.getRequest, +! msg->payload + payload_index + 4, +! msg->length - payload_index - 4); +! +! if (ohlone_check4chars(msg->payload+payload_index, (unsigned char *)"\r\n\r\n")) { +! ohlone_vars.httpChunk = 0; +! ohlone_sendpkt(); +! return; +! } +! } +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! openqueue_freePacketBuffer(msg); +! } +! +! void ohlone_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_OHLONE; +! if (msg->creator!=COMPONENT_OHLONE) { +! openserial_printError(COMPONENT_OHLONE,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! +! ohlone_sendpkt(); +! openqueue_freePacketBuffer(msg); +! } +! +! void ohlone_connectDone(error_t error) { +! } +! +! bool ohlone_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,113 ---- +! #include "openwsn.h" +! #include "ohlone.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "opentcp.h" +! +! #include "ohlone_webpages.h" +! +! //=========================== variables ======================================= +! +! ohlone_vars_t ohlone_vars; +! +! //=========================== prototypes ====================================== +! +! void ohlone_sendpkt(void); +! bool ohlone_check4chars(uint8_t c1[4], uint8_t c2[4]); +! +! //=========================== public ========================================== +! +! void ohlone_init(void) { +! ohlone_vars.httpChunk = 0; +! ohlone_vars.getRequest[0] = '/'; +! ohlone_vars.getRequest[1] = ' '; +! ohlone_webpages_init(); +! } +! +! bool ohlone_shouldIlisten(void) { +! return TRUE; +! } +! +! void ohlone_sendpkt(void) { +! uint8_t buffer[TCP_DEFAULT_WINDOW_SIZE]; +! uint8_t buffer_len; +! +! buffer_len = ohlone_webpage(ohlone_vars.getRequest, ohlone_vars.httpChunk++, buffer); +! +! if (buffer_len == 0) { +! // No more to send +! // close TCP session, but keep listening +! ohlone_vars.getRequest[0] = '/'; +! ohlone_vars.getRequest[1] = ' '; +! opentcp_close(); +! return; +! } +! +! ohlone_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_OHLONE); +! if (ohlone_vars.pkt==NULL) { +! openserial_printError(COMPONENT_OHLONE,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! opentcp_close(); +! return; +! } +! ohlone_vars.pkt->creator = COMPONENT_OHLONE; +! ohlone_vars.pkt->owner = COMPONENT_OHLONE; +! +! packetfunctions_reserveHeaderSize(ohlone_vars.pkt, buffer_len); +! memcpy(ohlone_vars.pkt->payload, buffer, buffer_len); +! +! if ((opentcp_send(ohlone_vars.pkt))==E_FAIL) { +! openqueue_freePacketBuffer(ohlone_vars.pkt); +! opentcp_close(); +! } +! +! } +! +! bool ohlone_check4chars(uint8_t c1[4], uint8_t c2[4]) { +! return ((c1[0] == c2[0]) && +! (c1[1] == c2[1]) && +! (c1[2] == c2[2]) && +! (c1[3] == c2[3])); +! } +! +! void ohlone_receive(OpenQueueEntry_t* msg) { +! uint8_t payload_index; +! +! for (payload_index=0;payload_indexlength-3;payload_index++) { +! if (ohlone_check4chars(msg->payload+payload_index,(unsigned char *) "GET ")) +! memcpy(ohlone_vars.getRequest, +! msg->payload + payload_index + 4, +! msg->length - payload_index - 4); +! +! if (ohlone_check4chars(msg->payload+payload_index, (unsigned char *)"\r\n\r\n")) { +! ohlone_vars.httpChunk = 0; +! ohlone_sendpkt(); +! return; +! } +! } +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! openqueue_freePacketBuffer(msg); +! } +! +! void ohlone_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_OHLONE; +! if (msg->creator!=COMPONENT_OHLONE) { +! openserial_printError(COMPONENT_OHLONE,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! +! ohlone_sendpkt(); +! openqueue_freePacketBuffer(msg); +! } +! +! void ohlone_connectDone(owerror_t error) { +! } +! +! bool ohlone_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/ohlone/ohlone.h ../../../sys/net/openwsn/07-App/ohlone/ohlone.h +*** openwsn/07-App/ohlone/ohlone.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/ohlone/ohlone.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,31 **** +! #ifndef __OHLONE_H +! #define __OHLONE_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup ohlone +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void ohlone_init(); +! bool ohlone_shouldIlisten(); +! void ohlone_receive(OpenQueueEntry_t* msg); +! void ohlone_sendDone(OpenQueueEntry_t* msg, error_t error); +! void ohlone_connectDone(error_t error); +! bool ohlone_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,40 ---- +! #ifndef __OHLONE_H +! #define __OHLONE_H +! +! /** +! \addtogroup AppTcp +! \{ +! \addtogroup ohlone +! \{ +! */ +! +! #include "opentcp.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== module variables ================================ +! +! typedef struct { +! OpenQueueEntry_t* pkt; +! bool sending; +! uint16_t httpChunk; +! uint8_t getRequest[TCP_DEFAULT_WINDOW_SIZE]; +! } ohlone_vars_t; +! +! //=========================== prototypes ====================================== +! +! void ohlone_init(void); +! bool ohlone_shouldIlisten(void); +! void ohlone_receive(OpenQueueEntry_t* msg); +! void ohlone_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void ohlone_connectDone(owerror_t error); +! bool ohlone_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/ohlone/ohlone_webpages.c ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.c +*** openwsn/07-App/ohlone/ohlone_webpages.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,94 **** +! /** +! \brief Webpgages for Ohlone +! +! \author Ankur Mehta , September 2010 +! */ +! +! #include "openwsn.h" +! #include "ohlone_webpages.h" +! +! /* +! #include "gyro.h" +! #include "large_range_accel.h" +! #include "magnetometer.h" +! #include "sensitive_accel_temperature.h" +! */ +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place); +! void ohlone_line_replace16(uint8_t *buffer, uint16_t value); +! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensors); +! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensors); +! +! //=========================== public ========================================== +! +! void ohlone_webpages_init() { +! /* +! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) +! gyro_init(); +! large_range_accel_init(); +! magnetometer_init(); +! sensitive_accel_temperature_init(); +! } +! */ +! } +! +! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet) { +! // TODO : enforce max of TCP_DEFAULT_WINDOW_SIZE +! uint8_t len = 0; +! uint8_t current_line = 0; +! current_line--; +! +! HTTP_LINE("HTTP/1.1 200 OK\r\n\r\n"); +! +! switch (*(getRequest + 1)) { +! +! default: +! memcpy(packet + len, ":)", 2); +! len += 2; +! } +! +! return len; +! } +! +! //=========================== private ========================================= +! +! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place) { +! uint8_t digit = '0'; +! while (value > place) { +! value -= place; +! digit++; +! } +! *buffer = digit; +! return value; +! } +! +! void ohlone_line_replace16(uint8_t *buffer, uint16_t value) { +! value = ohlone_replace_digit(buffer++, value, 10000); +! value = ohlone_replace_digit(buffer++, value, 1000); +! value = ohlone_replace_digit(buffer++, value, 100); +! value = ohlone_replace_digit(buffer++, value, 10); +! value = ohlone_replace_digit(buffer++, value, 1); +! } +! +! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensordata) { +! uint8_t len = 0; +! ohlone_line_replace16(buffer + len, (sensordata[0] << 8) + sensordata[1]); +! len += 5; buffer[len++] = ','; +! ohlone_line_replace16(buffer + len, (sensordata[2] << 8) + sensordata[3]); +! len += 5; buffer[len++] = ','; +! ohlone_line_replace16(buffer + len, (sensordata[4] << 8) + sensordata[5]); +! len += 5; +! return len; +! } +! +! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensordata) { +! uint8_t len = ohlone_insert3sensors(buffer, sensordata); +! buffer[len++] = ','; +! ohlone_line_replace16(buffer + len, (sensordata[6] << 8) + sensordata[7]); +! len += 5; +! return len; + } +\ No newline at end of file +--- 1,94 ---- +! /** +! \brief Webpgages for Ohlone +! +! \author Ankur Mehta , September 2010 +! */ +! +! #include "openwsn.h" +! #include "ohlone_webpages.h" +! +! /* +! #include "gyro.h" +! #include "large_range_accel.h" +! #include "magnetometer.h" +! #include "sensitive_accel_temperature.h" +! */ +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place); +! void ohlone_line_replace16(uint8_t *buffer, uint16_t value); +! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensors); +! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensors); +! +! //=========================== public ========================================== +! +! void ohlone_webpages_init(void) { +! /* +! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) +! gyro_init(); +! large_range_accel_init(); +! magnetometer_init(); +! sensitive_accel_temperature_init(); +! } +! */ +! } +! +! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet) { +! // TODO : enforce max of TCP_DEFAULT_WINDOW_SIZE +! uint8_t len = 0; +! uint8_t current_line = 0; +! current_line--; +! +! HTTP_LINE("HTTP/1.1 200 OK\r\n\r\n"); +! +! switch (*(getRequest + 1)) { +! +! default: +! memcpy(packet + len, ":)", 2); +! len += 2; +! } +! +! return len; +! } +! +! //=========================== private ========================================= +! +! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place) { +! uint8_t digit = '0'; +! while (value > place) { +! value -= place; +! digit++; +! } +! *buffer = digit; +! return value; +! } +! +! void ohlone_line_replace16(uint8_t *buffer, uint16_t value) { +! value = ohlone_replace_digit(buffer++, value, 10000); +! value = ohlone_replace_digit(buffer++, value, 1000); +! value = ohlone_replace_digit(buffer++, value, 100); +! value = ohlone_replace_digit(buffer++, value, 10); +! value = ohlone_replace_digit(buffer++, value, 1); +! } +! +! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensordata) { +! uint8_t len = 0; +! ohlone_line_replace16(buffer + len, (sensordata[0] << 8) + sensordata[1]); +! len += 5; buffer[len++] = ','; +! ohlone_line_replace16(buffer + len, (sensordata[2] << 8) + sensordata[3]); +! len += 5; buffer[len++] = ','; +! ohlone_line_replace16(buffer + len, (sensordata[4] << 8) + sensordata[5]); +! len += 5; +! return len; +! } +! +! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensordata) { +! uint8_t len = ohlone_insert3sensors(buffer, sensordata); +! buffer[len++] = ','; +! ohlone_line_replace16(buffer + len, (sensordata[6] << 8) + sensordata[7]); +! len += 5; +! return len; + } +\ No newline at end of file +diff -crB openwsn/07-App/ohlone/ohlone_webpages.h ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.h +*** openwsn/07-App/ohlone/ohlone_webpages.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,33 **** +! /** +! \brief Webpages for Ohlone +! +! \author Ankur Mehta , September 2010 +! */ +! +! #ifndef __OHLONEWEBPAGES_H +! #define __OHLONEWEBPAGES_H +! +! //=========================== define ========================================== +! +! #define HTTP_LINE(str) { \ +! if (chunk == ++current_line) { \ +! memcpy(packet, str, sizeof(str)-1); \ +! len = sizeof(str)-1; \ +! } \ +! } +! +! #define HTTP_LINE_REPLACE16(offset, value) { \ +! if (chunk == current_line) \ +! ohlone_line_replace16(packet+offset, value); \ +! } +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void ohlone_webpages_init(); +! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet); +! + #endif +\ No newline at end of file +--- 1,33 ---- +! /** +! \brief Webpages for Ohlone +! +! \author Ankur Mehta , September 2010 +! */ +! +! #ifndef __OHLONEWEBPAGES_H +! #define __OHLONEWEBPAGES_H +! +! //=========================== define ========================================== +! +! #define HTTP_LINE(str) { \ +! if (chunk == ++current_line) { \ +! memcpy(packet, str, sizeof(str)-1); \ +! len = sizeof(str)-1; \ +! } \ +! } +! +! #define HTTP_LINE_REPLACE16(offset, value) { \ +! if (chunk == current_line) \ +! ohlone_line_replace16(packet+offset, value); \ +! } +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void ohlone_webpages_init(void); +! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet); +! + #endif +\ No newline at end of file +diff -crB openwsn/07-App/r6tus/r6tus.c ../../../sys/net/openwsn/07-App/r6tus/r6tus.c +*** openwsn/07-App/r6tus/r6tus.c Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/r6tus/r6tus.c Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,211 ---- ++ /** ++ \brief CoAP schedule manager application. ++ ++ \author Xavi Vilajosana , Feb. 2013. ++ ++ */ ++ ++ #include "openwsn.h" ++ #include "r6tus.h" ++ #include "opentimers.h" ++ #include "openqueue.h" ++ #include "packetfunctions.h" ++ #include "openserial.h" ++ #include "scheduler.h" ++ #include "schedule.h" ++ #include "idmanager.h" ++ ++ //=========================== defines ========================================= ++ ++ #define TSCH_GET_OPTIONS 4 //how many params in a get request. ++ ++ const uint8_t r6tus_path0[] = "6tus"; ++ ++ //=========================== variables ======================================= ++ ++ r6tus_vars_t r6tus_vars; ++ ++ //=========================== prototypes ====================================== ++ ++ owerror_t r6tus_receive(OpenQueueEntry_t* msg, ++ coap_header_iht* coap_header, ++ coap_option_iht* coap_options); ++ ++ void r6tus_sendDone(OpenQueueEntry_t* msg, ++ owerror_t error); ++ ++ //=========================== public ========================================== ++ ++ void r6tus_init() { ++ ++ if(idmanager_getIsDAGroot()==TRUE) return; ++ // prepare the resource descriptor for the /r6tus path ++ r6tus_vars.desc.path0len = sizeof(r6tus_path0)-1; ++ r6tus_vars.desc.path0val = (uint8_t*)(&r6tus_path0); ++ r6tus_vars.desc.path1len = 0; ++ r6tus_vars.desc.path1val = NULL; ++ r6tus_vars.desc.componentID = COMPONENT_R6TUS; ++ r6tus_vars.desc.callbackRx = &r6tus_receive; ++ r6tus_vars.desc.callbackSendDone = &r6tus_sendDone; ++ ++ opencoap_register(&r6tus_vars.desc); ++ } ++ ++ //=========================== private ========================================= ++ ++ /** ++ \brief Receives a command and a list of items to be used by the command. ++ ++ the coap payload contains, command_type (CREATE,READ,UPDATE,DELETE) number of ++ items to be processed. ++ A tuple including address,slotoffset,choffset,whether is shared or not and link ++ type. ++ ++ According to the command it returns the list of responses or the required ++ information. ++ */ ++ owerror_t r6tus_receive(OpenQueueEntry_t* msg, ++ coap_header_iht* coap_header, ++ coap_option_iht* coap_options) { ++ ++ uint8_t i; ++ owerror_t outcome; ++ r6tus_command_t* link_command; ++ r6tus_command_t getResponse; ++ slotinfo_element_t* link_element; ++ slotinfo_element_t getLink_elementResponse; ++ open_addr_t temp_addr; ++ owerror_t responses[R6TUS_MAXRESPONSES]; ++ //assuming data comes in binary format. ++ ++ if (coap_header->Code==COAP_CODE_REQ_GET) { ++ outcome = E_SUCCESS; ++ // parsing the options from header ++ // assuming the following header: /6tus/LinkComandType/targetSlot/targetAddress ++ // if (coap_header->OC != TSCH_GET_OPTIONS) { ++ //option[0] is 6tus ++ getResponse.type=(link_command_t)coap_options[1].pValue[0]; ++ if (getResponse.type != READ_LINK){ ++ //fail if this is not a READ REQUEST ++ outcome = E_FAIL; ++ coap_header->Code = COAP_CODE_RESP_CONTENT; ++ //return as this is not the right request. ++ return outcome; ++ } ++ ++ getResponse.numelem = 1; //get is always for 1 element. ++ getLink_elementResponse.slotOffset=coap_options[2].pValue[0]; ++ ++ switch (coap_options[3].length){ ++ case ADDR_16B: ++ temp_addr.type=ADDR_16B; ++ memcpy(&(temp_addr.addr_16b[0]), &(coap_options[3].pValue[0]),LENGTH_ADDR16b); ++ schedule_getSlotInfo(getLink_elementResponse.slotOffset, &temp_addr, &getLink_elementResponse); ++ outcome = E_SUCCESS; ++ break; ++ case ADDR_64B: ++ temp_addr.type=ADDR_64B; ++ memcpy(&(temp_addr.addr_64b[0]), &(coap_options[3].pValue[0]),LENGTH_ADDR64b); ++ schedule_getSlotInfo(getLink_elementResponse.slotOffset, &temp_addr, &getLink_elementResponse); ++ outcome = E_SUCCESS; ++ break; ++ case ADDR_128B: ++ // not supported ++ outcome = E_FAIL; ++ break; ++ default: ++ outcome = E_FAIL; ++ break; ++ } ++ ++ coap_header->Code = COAP_CODE_RESP_CONTENT; ++ // By using the same link_element we don't need to write the packet. ++ // It returns the same payload but with the correct values. ++ if (outcome==E_SUCCESS) { ++ // write the payload in the response. ++ packetfunctions_reserveHeaderSize(msg,sizeof(slotinfo_element_t)); ++ memcpy(&msg->payload[0],&getLink_elementResponse,sizeof(slotinfo_element_t)); ++ } ++ } else if (coap_header->Code==COAP_CODE_REQ_PUT) { ++ link_command = (r6tus_command_t*) msg->payload; ++ //parsing all cases at post as we want params. once tested we can decide. GET does not accept params ++ //so params should be encoded in the url. ++ switch (link_command->type){ ++ case READ_LINK: ++ outcome=E_FAIL; ++ //cannot put READ operation ++ break; ++ case CREATE_LINK: ++ case UPDATE_LINK: //update should be post according to REST architecture. ++ outcome=E_FAIL; ++ if (link_command->numelemnumelem;i++) { ++ link_element=(slotinfo_element_t*) &(msg->payload[sizeof(r6tus_command_t)+i*sizeof(slotinfo_element_t)]); ++ temp_addr.type=ADDR_64B; ++ memcpy(&(temp_addr.addr_64b[0]), &(link_element->address[0]),LENGTH_ADDR64b); ++ responses[i]=schedule_addActiveSlot(link_element->slotOffset,link_element->link_type,link_element->shared,link_element->channelOffset,&temp_addr,(link_command->type==UPDATE_LINK)); ++ } ++ outcome=E_SUCCESS; ++ } ++ break; ++ case DELETE_LINK: ++ outcome=E_FAIL; ++ //cannot delete with PUT/POST ++ break; ++ default: ++ openserial_printError(COMPONENT_R6TUS,ERR_COMMAND_NOT_ALLOWED, ++ (errorparameter_t)0, ++ (errorparameter_t)0 ++ ); ++ //who clears the packet?? ++ //error. Print error and send error msg. ++ outcome = E_FAIL; ++ break; ++ } ++ //response of the post ++ if (outcome==E_SUCCESS){ ++ ++ // reset packet payload ++ msg->payload = &(msg->packet[127]); ++ msg->length = 0; ++ //copy the response. ++ ++ //packetfunctions_reserveHeaderSize(msg,link_command->numelem); ++ //memcpy(&(msg->payload[0]), &(responses[0]),link_command->numelem); ++ ++ // set the CoAP header ++ coap_header->Code = COAP_CODE_RESP_CONTENT; ++ } ++ } else if (coap_header->Code==COAP_CODE_REQ_DELETE) { ++ link_command = (r6tus_command_t*) msg->payload; ++ switch (link_command->type){ ++ case DELETE_LINK: ++ outcome=E_FAIL; ++ if (link_command->numelemnumelem;i++) { ++ link_element=(slotinfo_element_t*) &(msg->payload[sizeof(r6tus_command_t)+i*sizeof(slotinfo_element_t)]); ++ temp_addr.type=ADDR_64B; ++ memcpy(&(temp_addr.addr_64b[0]), &(link_element->address[0]),LENGTH_ADDR64b); ++ //remove the required links. ++ responses[i]=schedule_removeActiveSlot(link_element->slotOffset,&temp_addr); ++ } ++ outcome=E_SUCCESS; ++ } ++ break; ++ default: ++ openserial_printError(COMPONENT_R6TUS,ERR_COMMAND_NOT_ALLOWED, ++ (errorparameter_t)0, ++ (errorparameter_t)0); ++ //who clears the packet?? ++ //error. Print error and send error msg. ++ outcome = E_FAIL; ++ break; ++ } ++ } ++ return outcome; ++ } ++ ++ ++ void r6tus_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ++ openqueue_freePacketBuffer(msg); ++ } +diff -crB openwsn/07-App/r6tus/r6tus.h ../../../sys/net/openwsn/07-App/r6tus/r6tus.h +*** openwsn/07-App/r6tus/r6tus.h Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/r6tus/r6tus.h Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,60 ---- ++ /** ++ \brief CoAP schedule manager application. ++ ++ \author Xavi Vilajosana , Feb. 2013. ++ ++ */ ++ ++ ++ #ifndef __RSCHED_H ++ #define __RSCHED_H ++ ++ /** ++ \addtogroup AppCoAP ++ \{ ++ \addtogroup rsched ++ \{ ++ */ ++ ++ #include "openwsn.h" ++ #include "opencoap.h" ++ #include "schedule.h" ++ ++ //=========================== define ========================================== ++ ++ #define R6TUS_MAXRESPONSES 20 //max number of elements to be processed by a command. ++ ++ //=========================== typedef ========================================= ++ ++ //CRUD OPERATIONS FOR LINKS. ++ typedef enum { ++ CREATE_LINK = 0, ++ READ_LINK = 1, ++ UPDATE_LINK = 2, ++ DELETE_LINK = 3, ++ }link_command_t; ++ ++ //header ++ PRAGMA(pack(1)); //elements for slot info ++ typedef struct { ++ link_command_t type; ++ uint8_t numelem;//number of elements ++ }r6tus_command_t; ++ PRAGMA(pack()); ++ ++ //=========================== variables ======================================= ++ ++ typedef struct { ++ coap_resource_desc_t desc; ++ } r6tus_vars_t; ++ ++ //=========================== prototypes ====================================== ++ ++ void r6tus_init(); ++ ++ /** ++ \} ++ \} ++ */ ++ ++ #endif +diff -crB openwsn/07-App/rex/rex.c ../../../sys/net/openwsn/07-App/rex/rex.c +*** openwsn/07-App/rex/rex.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rex/rex.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,149 **** +! #include "openwsn.h" +! #include "rex.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "scheduler.h" +! //#include "ADC_Channel.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in ms) +! #define REXPERIOD 10000 +! #define PAYLOADLEN 62 +! +! const uint8_t rex_path0[] = "rex"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rex_vars_t; +! +! rex_vars_t rex_vars; +! +! //=========================== prototypes ====================================== +! +! error_t rex_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rex_timer_cb(); +! void rex_task_cb(); +! void rex_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rex_init() { +! +! // prepare the resource descriptor for the /rex path +! rex_vars.desc.path0len = sizeof(rex_path0)-1; +! rex_vars.desc.path0val = (uint8_t*)(&rex_path0); +! rex_vars.desc.path1len = 0; +! rex_vars.desc.path1val = NULL; +! rex_vars.desc.componentID = COMPONENT_REX; +! rex_vars.desc.callbackRx = &rex_receive; +! rex_vars.desc.callbackSendDone = &rex_sendDone; +! +! +! opencoap_register(&rex_vars.desc); +! rex_vars.timerId = opentimers_start(REXPERIOD, +! TIMER_PERIODIC,TIME_MS, +! rex_timer_cb); +! } +! +! //=========================== private ========================================= +! +! error_t rex_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! return E_FAIL; +! } +! +! //timer fired, but we don't want to execute task in ISR mode +! //instead, push task to scheduler with COAP priority, and let scheduler take care of it +! void rex_timer_cb(){ +! scheduler_push_task(rex_task_cb,TASKPRIO_COAP); +! } +! +! void rex_task_cb() { +! OpenQueueEntry_t* pkt; +! error_t outcome; +! uint8_t numOptions; +! uint8_t i; +! +! uint16_t x_int = 0; +! //uint16_t* p_x_int = &x_int; +! uint16_t sum = 0; +! uint16_t avg = 0; +! uint8_t N_avg = 10; +! +! for (int i = 0; i < N_avg; i++) +! { +! //ADC_getvoltage(p_x_int); +! +! sum += x_int; +! } +! avg = sum/N_avg; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_REX); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_REX,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_REX; +! pkt->owner = COMPONENT_REX; +! // CoAP payload +! packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); +! for (i=0;ipayload[i] = i; +! } +! avg = openrandom_get16b(); +! pkt->payload[0] = (avg>>8)&0xff; +! pkt->payload[1] = (avg>>0)&0xff; +! +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(rex_path0)-1); +! memcpy(&pkt->payload[0],&rex_path0,sizeof(rex_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! sizeof(rex_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rex_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void rex_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); +! } +--- 1,159 ---- +! #include "openwsn.h" +! #include "rex.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "scheduler.h" +! //#include "ADC_Channel.h" +! #include "idmanager.h" +! #include "IEEE802154E.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in ms) +! #define REXPERIOD 10000 +! #define PAYLOADLEN 62 +! +! const uint8_t rex_path0[] = "rex"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rex_vars_t; +! +! rex_vars_t rex_vars; +! +! //=========================== prototypes ====================================== +! +! owerror_t rex_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rex_timer_cb(); +! void rex_task_cb(); +! void rex_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rex_init() { +! +! // prepare the resource descriptor for the /rex path +! rex_vars.desc.path0len = sizeof(rex_path0)-1; +! rex_vars.desc.path0val = (uint8_t*)(&rex_path0); +! rex_vars.desc.path1len = 0; +! rex_vars.desc.path1val = NULL; +! rex_vars.desc.componentID = COMPONENT_REX; +! rex_vars.desc.callbackRx = &rex_receive; +! rex_vars.desc.callbackSendDone = &rex_sendDone; +! +! +! opencoap_register(&rex_vars.desc); +! rex_vars.timerId = opentimers_start(REXPERIOD, +! TIMER_PERIODIC,TIME_MS, +! rex_timer_cb); +! } +! +! //=========================== private ========================================= +! +! owerror_t rex_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! return E_FAIL; +! } +! +! //timer fired, but we don't want to execute task in ISR mode +! //instead, push task to scheduler with COAP priority, and let scheduler take care of it +! void rex_timer_cb(){ +! scheduler_push_task(rex_task_cb,TASKPRIO_COAP); +! } +! +! void rex_task_cb() { +! OpenQueueEntry_t* pkt; +! owerror_t outcome; +! uint8_t numOptions; +! uint8_t i; +! +! uint16_t x_int = 0; +! //uint16_t* p_x_int = &x_int; +! uint16_t sum = 0; +! uint16_t avg = 0; +! uint8_t N_avg = 10; +! +! // don't run if not synch +! if (ieee154e_isSynch() == FALSE) return; +! +! // don't run on dagroot +! if (idmanager_getIsDAGroot()) { +! opentimers_stop(rex_vars.timerId); +! return; +! } +! +! +! for (i = 0; i < N_avg; i++) { +! //ADC_getvoltage(p_x_int); +! sum += x_int; +! } +! avg = sum/N_avg; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_REX); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_REX,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_REX; +! pkt->owner = COMPONENT_REX; +! // CoAP payload +! packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); +! for (i=0;ipayload[i] = i; +! } +! avg = openrandom_get16b(); +! pkt->payload[0] = (avg>>8)&0xff; +! pkt->payload[1] = (avg>>0)&0xff; +! +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(rex_path0)-1); +! memcpy(&pkt->payload[0],&rex_path0,sizeof(rex_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(rex_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rex_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void rex_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); +! } +diff -crB openwsn/07-App/rex/rex.h ../../../sys/net/openwsn/07-App/rex/rex.h +*** openwsn/07-App/rex/rex.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rex/rex.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __REX_H +! #define __REX_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rT +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rex_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __REX_H +! #define __REX_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup rT +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rex_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rheli/rheli.c ../../../sys/net/openwsn/07-App/rheli/rheli.c +*** openwsn/07-App/rheli/rheli.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rheli/rheli.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,84 **** +! #include "openwsn.h" +! #include "rheli.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "packetfunctions.h" +! #include "heli.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rheli_vars_t; +! +! rheli_vars_t rheli_vars; +! +! const uint8_t rheli_path0[] = "h"; +! +! //=========================== prototypes ====================================== +! +! error_t rheli_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rheli_timer(); +! void rheli_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rheli_init() { +! // initialize the heli drivers +! heli_init(); +! +! // prepare the resource descriptor +! rheli_vars.desc.path0len = sizeof(rheli_path0)-1; +! rheli_vars.desc.path0val = (uint8_t*)(&rheli_path0); +! rheli_vars.desc.path1len = 0; +! rheli_vars.desc.path1val = NULL; +! rheli_vars.desc.componentID = COMPONENT_RHELI; +! rheli_vars.desc.callbackRx = &rheli_receive; +! rheli_vars.desc.callbackSendDone = &rheli_sendDone; +! +! opencoap_register(&rheli_vars.desc); +! rheli_vars.timerId = opentimers_start(1000, +! TIMER_PERIODIC,TIME_MS, +! rheli_timer); +! } +! +! //=========================== private ========================================= +! +! error_t rheli_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! +! // switch on the heli +! heli_on(); +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CHANGED; +! +! outcome = E_SUCCESS; +! } else { +! outcome = E_FAIL; +! } +! return outcome; +! } +! +! void rheli_timer() { +! // switch off the heli +! heli_off(); +! } +! +! void rheli_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,83 ---- +! #include "openwsn.h" +! #include "rheli.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "packetfunctions.h" +! #include "heli.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rheli_vars_t; +! +! rheli_vars_t rheli_vars; +! +! const uint8_t rheli_path0[] = "h"; +! +! //=========================== prototypes ====================================== +! +! owerror_t rheli_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rheli_timer(); +! void rheli_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rheli_init() { +! // initialize the heli drivers +! heli_init(); +! +! // prepare the resource descriptor +! rheli_vars.desc.path0len = sizeof(rheli_path0)-1; +! rheli_vars.desc.path0val = (uint8_t*)(&rheli_path0); +! rheli_vars.desc.path1len = 0; +! rheli_vars.desc.path1val = NULL; +! rheli_vars.desc.componentID = COMPONENT_RHELI; +! rheli_vars.desc.callbackRx = &rheli_receive; +! rheli_vars.desc.callbackSendDone = &rheli_sendDone; +! +! opencoap_register(&rheli_vars.desc); +! rheli_vars.timerId = opentimers_start(1000, +! TIMER_PERIODIC,TIME_MS, +! rheli_timer); +! } +! +! //=========================== private ========================================= +! +! owerror_t rheli_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! +! // switch on the heli +! heli_on(); +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CHANGED; +! +! outcome = E_SUCCESS; +! } else { +! outcome = E_FAIL; +! } +! return outcome; +! } +! +! void rheli_timer() { +! // switch off the heli +! heli_off(); +! } +! +! void rheli_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/rheli/rheli.h ../../../sys/net/openwsn/07-App/rheli/rheli.h +*** openwsn/07-App/rheli/rheli.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rheli/rheli.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RHELI_H +! #define __RHELI_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rHeli +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rheli_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RHELI_H +! #define __RHELI_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rHeli +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rheli_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rinfo/Makefile ../../../sys/net/openwsn/07-App/rinfo/Makefile +*** openwsn/07-App/rinfo/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/rinfo/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/rinfo/rinfo.c ../../../sys/net/openwsn/07-App/rinfo/rinfo.c +*** openwsn/07-App/rinfo/rinfo.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rinfo/rinfo.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,99 **** +! #include "openwsn.h" +! #include "rinfo.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "board.h" +! +! //=========================== defines ========================================= +! +! const uint8_t rinfo_path0[] = "i"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! } rinfo_vars_t; +! +! rinfo_vars_t rinfo_vars; +! +! //=========================== prototypes ====================================== +! +! error_t rinfo_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rinfo_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rinfo_init() { +! // prepare the resource descriptor for the /temp path +! rinfo_vars.desc.path0len = sizeof(rinfo_path0)-1; +! rinfo_vars.desc.path0val = (uint8_t*)(&rinfo_path0); +! rinfo_vars.desc.path1len = 0; +! rinfo_vars.desc.path1val = NULL; +! rinfo_vars.desc.componentID = COMPONENT_RINFO; +! rinfo_vars.desc.callbackRx = &rinfo_receive; +! rinfo_vars.desc.callbackSendDone = &rinfo_sendDone; +! +! opencoap_register(&rinfo_vars.desc); +! } +! +! //=========================== private ========================================= +! +! error_t rinfo_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP payload +! //==radio name +! packetfunctions_reserveHeaderSize(msg,sizeof(infoRadioName)-1); +! memcpy(&msg->payload[0],&infoRadioName,sizeof(infoRadioName)-1); +! //==uC name +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '\n'; +! packetfunctions_reserveHeaderSize(msg,sizeof(infouCName)-1); +! memcpy(&msg->payload[0],&infouCName,sizeof(infouCName)-1); +! //==board name +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '\n'; +! packetfunctions_reserveHeaderSize(msg,sizeof(infoBoardname)-1); +! memcpy(&msg->payload[0],&infoBoardname,sizeof(infoBoardname)-1); +! //==stackname +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '\n'; +! packetfunctions_reserveHeaderSize(msg,sizeof(infoStackName)-1+5); +! memcpy(&msg->payload[0],&infoStackName,sizeof(infoStackName)-1); +! msg->payload[sizeof(infoStackName)-1+5-5] = '0'+OPENWSN_VERSION_MAJOR; +! msg->payload[sizeof(infoStackName)-1+5-4] = '.'; +! msg->payload[sizeof(infoStackName)-1+5-3] = '0'+OPENWSN_VERSION_MINOR; +! msg->payload[sizeof(infoStackName)-1+5-2] = '.'; +! msg->payload[sizeof(infoStackName)-1+5-1] = '0'+OPENWSN_VERSION_PATCH; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rinfo_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,102 ---- +! #include "openwsn.h" +! #include "rinfo.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "board.h" +! #include "idmanager.h" +! +! //=========================== defines ========================================= +! +! const uint8_t rinfo_path0[] = "i"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! } rinfo_vars_t; +! +! rinfo_vars_t rinfo_vars; +! +! //=========================== prototypes ====================================== +! +! owerror_t rinfo_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rinfo_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rinfo_init(void) { +! +! +! if(idmanager_getIsDAGroot()==TRUE) return; +! // prepare the resource descriptor for the /temp path +! rinfo_vars.desc.path0len = sizeof(rinfo_path0)-1; +! rinfo_vars.desc.path0val = (uint8_t*)(&rinfo_path0); +! rinfo_vars.desc.path1len = 0; +! rinfo_vars.desc.path1val = NULL; +! rinfo_vars.desc.componentID = COMPONENT_RINFO; +! rinfo_vars.desc.callbackRx = &rinfo_receive; +! rinfo_vars.desc.callbackSendDone = &rinfo_sendDone; +! +! opencoap_register(&rinfo_vars.desc); +! } +! +! //=========================== private ========================================= +! +! owerror_t rinfo_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP payload +! //==radio name +! packetfunctions_reserveHeaderSize(msg,sizeof(infoRadioName)-1); +! memcpy(&msg->payload[0],&infoRadioName,sizeof(infoRadioName)-1); +! //==uC name +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '\n'; +! packetfunctions_reserveHeaderSize(msg,sizeof(infouCName)-1); +! memcpy(&msg->payload[0],&infouCName,sizeof(infouCName)-1); +! //==board name +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '\n'; +! packetfunctions_reserveHeaderSize(msg,sizeof(infoBoardname)-1); +! memcpy(&msg->payload[0],&infoBoardname,sizeof(infoBoardname)-1); +! //==stackname +! packetfunctions_reserveHeaderSize(msg,1); +! msg->payload[0] = '\n'; +! packetfunctions_reserveHeaderSize(msg,sizeof(infoStackName)-1+5); +! memcpy(&msg->payload[0],&infoStackName,sizeof(infoStackName)-1); +! msg->payload[sizeof(infoStackName)-1+5-5] = '0'+OPENWSN_VERSION_MAJOR; +! msg->payload[sizeof(infoStackName)-1+5-4] = '.'; +! msg->payload[sizeof(infoStackName)-1+5-3] = '0'+OPENWSN_VERSION_MINOR; +! msg->payload[sizeof(infoStackName)-1+5-2] = '.'; +! msg->payload[sizeof(infoStackName)-1+5-1] = '0'+OPENWSN_VERSION_PATCH; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rinfo_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/rinfo/rinfo.h ../../../sys/net/openwsn/07-App/rinfo/rinfo.h +*** openwsn/07-App/rinfo/rinfo.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rinfo/rinfo.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RINFO_H +! #define __RINFO_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rXL1 +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rinfo_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RINFO_H +! #define __RINFO_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rXL1 +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rinfo_init(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rleds/rleds.c ../../../sys/net/openwsn/07-App/rleds/rleds.c +*** openwsn/07-App/rleds/rleds.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rleds/rleds.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,94 **** +! #include "openwsn.h" +! #include "rleds.h" +! #include "opencoap.h" +! #include "packetfunctions.h" +! #include "leds.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! } rleds_vars_t; +! +! rleds_vars_t rleds_vars; +! +! const uint8_t rleds_path0[] = "l"; +! +! //=========================== prototypes ====================================== +! +! error_t rleds_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rleds_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rleds_init() { +! // prepare the resource descriptor for the /.well-known/core path +! rleds_vars.desc.path0len = sizeof(rleds_path0)-1; +! rleds_vars.desc.path0val = (uint8_t*)(&rleds_path0); +! rleds_vars.desc.path1len = 0; +! rleds_vars.desc.path1val = NULL; +! rleds_vars.desc.componentID = COMPONENT_RLEDS; +! rleds_vars.desc.callbackRx = &rleds_receive; +! rleds_vars.desc.callbackSendDone = &rleds_sendDone; +! +! opencoap_register(&rleds_vars.desc); +! } +! +! //=========================== private ========================================= +! +! error_t rleds_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // add CoAP payload +! packetfunctions_reserveHeaderSize(msg,1); +! if (leds_error_isOn()==1) { +! msg->payload[0] = '1'; +! } else { +! msg->payload[0] = '0'; +! } +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! } else if (coap_header->Code==COAP_CODE_REQ_PUT) { +! +! // change the LED's state +! if (msg->payload[0]=='1') { +! leds_debug_on(); +! } else if (msg->payload[0]=='2') { +! leds_debug_toggle(); +! } else { +! leds_debug_off(); +! } +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CHANGED; +! +! outcome = E_SUCCESS; +! } else { +! outcome = E_FAIL; +! } +! return outcome; +! } +! +! void rleds_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,92 ---- +! #include "openwsn.h" +! #include "rleds.h" +! #include "opencoap.h" +! #include "packetfunctions.h" +! #include "leds.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! } rleds_vars_t; +! +! rleds_vars_t rleds_vars; +! +! const uint8_t rleds_path0[] = "l"; +! +! //=========================== prototypes ====================================== +! +! owerror_t rleds_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rleds_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rleds__init() { +! // prepare the resource descriptor for the /.well-known/core path +! rleds_vars.desc.path0len = sizeof(rleds_path0)-1; +! rleds_vars.desc.path0val = (uint8_t*)(&rleds_path0); +! rleds_vars.desc.path1len = 0; +! rleds_vars.desc.path1val = NULL; +! rleds_vars.desc.componentID = COMPONENT_RLEDS; +! rleds_vars.desc.callbackRx = &rleds_receive; +! rleds_vars.desc.callbackSendDone = &rleds_sendDone; +! +! opencoap_register(&rleds_vars.desc); +! } +! +! //=========================== private ========================================= +! +! owerror_t rleds_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // add CoAP payload +! packetfunctions_reserveHeaderSize(msg,1); +! if (leds_error_isOn()==1) { +! msg->payload[0] = '1'; +! } else { +! msg->payload[0] = '0'; +! } +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! } else if (coap_header->Code==COAP_CODE_REQ_PUT) { +! +! // change the LED's state +! if (msg->payload[0]=='1') { +! leds_debug_on(); +! } else if (msg->payload[0]=='2') { +! leds_debug_toggle(); +! } else { +! leds_debug_off(); +! } +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CHANGED; +! +! outcome = E_SUCCESS; +! } else { +! outcome = E_FAIL; +! } +! return outcome; +! } +! +! void rleds_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/rleds/rleds.h ../../../sys/net/openwsn/07-App/rleds/rleds.h +*** openwsn/07-App/rleds/rleds.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rleds/rleds.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RLEDS_H +! #define __RLEDS_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup netLeds +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rleds_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RLEDS_H +! #define __RLEDS_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup netLeds +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rleds__init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rreg/rreg.c ../../../sys/net/openwsn/07-App/rreg/rreg.c +*** openwsn/07-App/rreg/rreg.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rreg/rreg.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,164 **** +! #include "openwsn.h" +! #include "rreg.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! #include "board.h" +! #include "scheduler.h" +! +! //=========================== variables ======================================= +! +! #define RREGPERIOD 30000 +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rreg_vars_t; +! +! rreg_vars_t rreg_vars; +! +! const uint8_t rreg_path0[] = "r"; +! +! //=========================== prototypes ====================================== +! +! error_t rreg_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rreg_timer(); +! void rreg_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! uint8_t hexToAscii(uint8_t hex); +! +! //=========================== public ========================================== +! +! void rreg_init() { +! // prepare the resource descriptor for the /.well-known/core path +! rreg_vars.desc.path0len = sizeof(rreg_path0)-1; +! rreg_vars.desc.path0val = (uint8_t*)(&rreg_path0); +! rreg_vars.desc.path1len = 0; +! rreg_vars.desc.path1val = NULL; +! rreg_vars.desc.componentID = COMPONENT_RREG; +! rreg_vars.desc.callbackRx = &rreg_receive; +! rreg_vars.desc.callbackSendDone = &rreg_sendDone; +! +! +! +! opencoap_register(&rreg_vars.desc); +! // register to the RD server every 30s +! rreg_vars.timerId = opentimers_start(RREGPERIOD, +! TIMER_PERIODIC,TIME_MS, +! rreg_timer); +! } +! +! //=========================== private ========================================= +! +! error_t rreg_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! +! error_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! // request to register received +! +! // triggered: schedule task to execute timer function next +! scheduler_push_task(rreg_timer,TASKPRIO_COAP); +! //call timer here, but reset timer after +! +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! outcome = E_SUCCESS; +! } else if (coap_header->T==COAP_TYPE_ACK) { +! // it worked! +! } else { +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rreg_timer() { +! OpenQueueEntry_t* pkt; +! uint8_t temp8b; +! error_t outcome; +! uint8_t numOptions; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RREG; +! pkt->owner = COMPONENT_RREG; +! // CoAP payload +! opencoap_writeLinks(pkt); +! numOptions = 0; +! // URI-query +! packetfunctions_reserveHeaderSize(pkt,sizeof(rreg_uriquery)-1+2); +! memcpy(&pkt->payload[0],&rreg_uriquery,sizeof(rreg_uriquery)-1); +! temp8b = idmanager_getMyID(ADDR_16B)->addr_16b[1]; +! pkt->payload[sizeof(rreg_uriquery)-1] = hexToAscii((temp8b>>4) & 0x0f); +! pkt->payload[sizeof(rreg_uriquery)-0] = hexToAscii((temp8b>>0) & 0x0f); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_URIQUERY-COAP_OPTION_URIPATH) << 4 | +! sizeof(rreg_uriquery)-1+2; +! numOptions++; +! // URI-path +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = 'r'; +! pkt->payload[1] = 'd'; +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_URIPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! 2; +! numOptions++; +! // add content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_ipsoRD,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_CON, +! COAP_CODE_REQ_POST, +! numOptions, +! &rreg_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void rreg_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); +! } +! +! port_INLINE uint8_t hexToAscii(uint8_t hex) { +! if (hex<0x0a) { +! return '0'+(hex-0x00); +! } else { +! return 'A'+(hex-0x0a); +! } + } +\ No newline at end of file +--- 1,166 ---- +! #include "openwsn.h" +! #include "rreg.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! #include "board.h" +! #include "scheduler.h" +! +! //=========================== variables ======================================= +! +! #define RREGPERIOD 30000 +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rreg_vars_t; +! +! rreg_vars_t rreg_vars; +! +! const uint8_t rreg_path0[] = "r"; +! +! //=========================== prototypes ====================================== +! +! owerror_t rreg_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rreg_timer(); +! void rreg_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! uint8_t hexToAscii(uint8_t hex); +! +! //=========================== public ========================================== +! +! void rreg_init() { +! //dagroot does not run upper layers. +! if(idmanager_getIsDAGroot()==TRUE) return; +! +! // prepare the resource descriptor for the /.well-known/core path +! rreg_vars.desc.path0len = sizeof(rreg_path0)-1; +! rreg_vars.desc.path0val = (uint8_t*)(&rreg_path0); +! rreg_vars.desc.path1len = 0; +! rreg_vars.desc.path1val = NULL; +! rreg_vars.desc.componentID = COMPONENT_RREG; +! rreg_vars.desc.callbackRx = &rreg_receive; +! rreg_vars.desc.callbackSendDone = &rreg_sendDone; +! +! +! +! opencoap_register(&rreg_vars.desc); +! // register to the RD server every 30s +! rreg_vars.timerId = opentimers_start(RREGPERIOD, +! TIMER_PERIODIC,TIME_MS, +! rreg_timer); +! } +! +! //=========================== private ========================================= +! +! owerror_t rreg_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! +! owerror_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! // request to register received +! +! // triggered: schedule task to execute timer function next +! scheduler_push_task(rreg_timer,TASKPRIO_COAP); +! //call timer here, but reset timer after +! +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! outcome = E_SUCCESS; +! } else if (coap_header->T==COAP_TYPE_ACK) { +! // it worked! +! } else { +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rreg_timer() { +! OpenQueueEntry_t* pkt; +! uint8_t temp8b; +! owerror_t outcome; +! uint8_t numOptions; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! //openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RREG; +! pkt->owner = COMPONENT_RREG; +! // CoAP payload +! opencoap_writeLinks(pkt); +! numOptions = 0; +! // URI-query +! packetfunctions_reserveHeaderSize(pkt,sizeof(rreg_uriquery)-1+2); +! memcpy(&pkt->payload[0],&rreg_uriquery,sizeof(rreg_uriquery)-1); +! temp8b = idmanager_getMyID(ADDR_16B)->addr_16b[1]; +! pkt->payload[sizeof(rreg_uriquery)-1] = hexToAscii((temp8b>>4) & 0x0f); +! pkt->payload[sizeof(rreg_uriquery)-0] = hexToAscii((temp8b>>0) & 0x0f); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIQUERY-COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(rreg_uriquery)-1+2; +! numOptions++; +! // URI-path +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = 'r'; +! pkt->payload[1] = 'd'; +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! 2; +! numOptions++; +! // add content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_ipsoRD,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_CON, +! COAP_CODE_REQ_POST, +! numOptions, +! &rreg_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void rreg_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); +! } +! +! port_INLINE uint8_t hexToAscii(uint8_t hex) { +! if (hex<0x0a) { +! return '0'+(hex-0x00); +! } else { +! return 'A'+(hex-0x0a); +! } + } +\ No newline at end of file +diff -crB openwsn/07-App/rreg/rreg.h ../../../sys/net/openwsn/07-App/rreg/rreg.h +*** openwsn/07-App/rreg/rreg.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rreg/rreg.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RREG_H +! #define __RREG_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rReg +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rreg_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RREG_H +! #define __RREG_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rReg +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rreg_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rrube/rrube.c ../../../sys/net/openwsn/07-App/rrube/rrube.c +*** openwsn/07-App/rrube/rrube.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rrube/rrube.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,243 **** +! #include "openwsn.h" +! #include "rrube.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! #include "board.h" +! #include "heli.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! static const uint8_t ipAddr_rubeServer[] = {0x24, 0x06, 0xa0, 0x00, 0xf0, 0xff, 0xff, 0xfe, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xbf}; +! +! typedef enum { +! RRUBE_ST_IDLE, +! RRUBE_ST_WAITTXPUT, +! RRUBE_ST_PUTRXD, +! RRUBE_ST_WAITACK, +! } rrube_state_t; +! +! //=========================== variables ======================================= +! +! typedef struct { +! rrube_state_t rrube_state; +! coap_resource_desc_t desc; +! open_addr_t nextHop; +! opentimer_id_t timerId; +! } rrube_vars_t; +! +! rrube_vars_t rrube_vars; +! +! const uint8_t rrube_path0[] = "g"; +! +! //=========================== prototypes ====================================== +! +! error_t rrube_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rrube_timer(); +! void rrube_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! uint8_t hexToAscii(uint8_t hex); +! +! //=========================== public ========================================== +! +! void rrube_init() { +! heli_init(); +! +! rrube_vars.nextHop.type = ADDR_128B; +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! +! // prepare the resource descriptor for the /.well-known/core path +! rrube_vars.desc.path0len = sizeof(rrube_path0)-1; +! rrube_vars.desc.path0val = (uint8_t*)(&rrube_path0); +! rrube_vars.desc.path1len = 0; +! rrube_vars.desc.path1val = NULL; +! rrube_vars.desc.componentID = COMPONENT_RRUBE; +! rrube_vars.desc.callbackRx = &rrube_receive; +! rrube_vars.desc.callbackSendDone = &rrube_sendDone; +! +! opencoap_register(&rrube_vars.desc); +! rrube_vars.timerId = opentimers_start(1000, +! TIMER_PERIODIC,TIME_MS, +! rrube_timer); +! } +! +! //=========================== private ========================================= +! +! error_t rrube_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! +! error_t outcome; +! +! if (rrube_vars.rrube_state==RRUBE_ST_IDLE && +! coap_header->Code==COAP_CODE_REQ_POST) { +! +! // turn on LED +! leds_debug_on(); +! +! // record the next hop's address +! memcpy(&rrube_vars.nextHop.addr_128b[0],&msg->payload[0],16); +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_WAITTXPUT; +! +! outcome = E_SUCCESS; +! +! } else if (rrube_vars.rrube_state==RRUBE_ST_IDLE && +! coap_header->Code==COAP_CODE_REQ_PUT) { +! +! // turn on LED +! leds_debug_on(); +! +! // turn heli on +! heli_on(); +! +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_PUTRXD; +! +! } else if (rrube_vars.rrube_state==RRUBE_ST_WAITACK && +! coap_header->T==COAP_TYPE_ACK) { +! // record the next hop's address +! memcpy(&rrube_vars.nextHop.addr_128b[0],&msg->payload[0],16); +! +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_WAITTXPUT; +! +! outcome = E_SUCCESS; +! +! } else { +! // didn't expect that packet +! +! // reset state machine +! outcome = E_FAIL; +! +! // turn off LED +! leds_debug_off(); +! } +! +! return outcome; +! } +! +! void rrube_timer() { +! OpenQueueEntry_t* pkt; +! uint8_t numOptions; +! error_t outcome; +! +! // turn off heli +! heli_off(); +! +! if (rrube_vars.rrube_state == RRUBE_ST_WAITTXPUT) { +! // I received a POST from the server, I need to send data to the next hop +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RRUBE; +! pkt->owner = COMPONENT_RRUBE; +! numOptions = 0; +! // URI-path +! packetfunctions_reserveHeaderSize(pkt,sizeof(rrube_path0)-1); +! memcpy(&pkt->payload[0],&rrube_path0,sizeof(rrube_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_URIPATH) << 4 | +! sizeof(rrube_path0)-1; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd,&rrube_vars.nextHop,sizeof(open_addr_t)); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rrube_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! openqueue_freePacketBuffer(pkt); +! } +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! +! // turn off LED +! leds_debug_off(); +! +! } else if (rrube_vars.rrube_state == RRUBE_ST_PUTRXD) { +! // I received a PUT from the previous hop, I need ask the server for the next address +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RRUBE; +! pkt->owner = COMPONENT_RRUBE; +! numOptions = 0; +! // URI-path +! packetfunctions_reserveHeaderSize(pkt,sizeof(rrube_path0)-1); +! memcpy(&pkt->payload[0],&rrube_path0,sizeof(rrube_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_URIPATH) << 4 | +! sizeof(rrube_path0)-1; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_rubeServer,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_CON, +! COAP_CODE_REQ_GET, +! numOptions, +! &rrube_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! openqueue_freePacketBuffer(pkt); +! } +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_WAITACK; +! +! } else { +! // timer expired while not in expected state +! +! // reset state machine +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! +! // turn off LED +! leds_debug_off(); +! } +! return; +! } +! +! void rrube_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,242 ---- +! #include "openwsn.h" +! #include "rrube.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! #include "board.h" +! #include "heli.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! static const uint8_t ipAddr_rubeServer[] = {0x24, 0x06, 0xa0, 0x00, 0xf0, 0xff, 0xff, 0xfe, \ +! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xbf}; +! +! typedef enum { +! RRUBE_ST_IDLE, +! RRUBE_ST_WAITTXPUT, +! RRUBE_ST_PUTRXD, +! RRUBE_ST_WAITACK, +! } rrube_state_t; +! +! //=========================== variables ======================================= +! +! typedef struct { +! rrube_state_t rrube_state; +! coap_resource_desc_t desc; +! open_addr_t nextHop; +! opentimer_id_t timerId; +! } rrube_vars_t; +! +! rrube_vars_t rrube_vars; +! +! const uint8_t rrube_path0[] = "g"; +! +! //=========================== prototypes ====================================== +! +! owerror_t rrube_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rrube_timer(); +! void rrube_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! uint8_t hexToAscii(uint8_t hex); +! +! //=========================== public ========================================== +! +! void rrube_init() { +! heli_init(); +! +! rrube_vars.nextHop.type = ADDR_128B; +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! +! // prepare the resource descriptor for the /.well-known/core path +! rrube_vars.desc.path0len = sizeof(rrube_path0)-1; +! rrube_vars.desc.path0val = (uint8_t*)(&rrube_path0); +! rrube_vars.desc.path1len = 0; +! rrube_vars.desc.path1val = NULL; +! rrube_vars.desc.componentID = COMPONENT_RRUBE; +! rrube_vars.desc.callbackRx = &rrube_receive; +! rrube_vars.desc.callbackSendDone = &rrube_sendDone; +! +! opencoap_register(&rrube_vars.desc); +! rrube_vars.timerId = opentimers_start(1000, +! TIMER_PERIODIC,TIME_MS, +! rrube_timer); +! } +! +! //=========================== private ========================================= +! +! owerror_t rrube_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! +! owerror_t outcome; +! +! if (rrube_vars.rrube_state==RRUBE_ST_IDLE && +! coap_header->Code==COAP_CODE_REQ_POST) { +! +! // turn on LED +! leds_debug_on(); +! +! // record the next hop's address +! memcpy(&rrube_vars.nextHop.addr_128b[0],&msg->payload[0],16); +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_WAITTXPUT; +! +! outcome = E_SUCCESS; +! +! } else if (rrube_vars.rrube_state==RRUBE_ST_IDLE && +! coap_header->Code==COAP_CODE_REQ_PUT) { +! +! // turn on LED +! leds_debug_on(); +! +! // turn heli on +! heli_on(); +! +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_PUTRXD; +! +! } else if (rrube_vars.rrube_state==RRUBE_ST_WAITACK && +! coap_header->T==COAP_TYPE_ACK) { +! // record the next hop's address +! memcpy(&rrube_vars.nextHop.addr_128b[0],&msg->payload[0],16); +! +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_WAITTXPUT; +! +! outcome = E_SUCCESS; +! +! } else { +! // didn't expect that packet +! +! // reset state machine +! outcome = E_FAIL; +! +! // turn off LED +! leds_debug_off(); +! } +! +! return outcome; +! } +! +! void rrube_timer() { +! OpenQueueEntry_t* pkt; +! uint8_t numOptions; +! owerror_t outcome; +! +! // turn off heli +! heli_off(); +! +! if (rrube_vars.rrube_state == RRUBE_ST_WAITTXPUT) { +! // I received a POST from the server, I need to send data to the next hop +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RRUBE; +! pkt->owner = COMPONENT_RRUBE; +! numOptions = 0; +! // URI-path +! packetfunctions_reserveHeaderSize(pkt,sizeof(rrube_path0)-1); +! memcpy(&pkt->payload[0],&rrube_path0,sizeof(rrube_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(rrube_path0)-1; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd,&rrube_vars.nextHop,sizeof(open_addr_t)); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rrube_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! openqueue_freePacketBuffer(pkt); +! } +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! +! // turn off LED +! leds_debug_off(); +! +! } else if (rrube_vars.rrube_state == RRUBE_ST_PUTRXD) { +! // I received a PUT from the previous hop, I need ask the server for the next address +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RREG); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RREG,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RRUBE; +! pkt->owner = COMPONENT_RRUBE; +! numOptions = 0; +! // URI-path +! packetfunctions_reserveHeaderSize(pkt,sizeof(rrube_path0)-1); +! memcpy(&pkt->payload[0],&rrube_path0,sizeof(rrube_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(rrube_path0)-1; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_rubeServer,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_CON, +! COAP_CODE_REQ_GET, +! numOptions, +! &rrube_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! openqueue_freePacketBuffer(pkt); +! } +! // advance state machine +! rrube_vars.rrube_state = RRUBE_ST_WAITACK; +! +! } else { +! // timer expired while not in expected state +! +! // reset state machine +! rrube_vars.rrube_state = RRUBE_ST_IDLE; +! +! // turn off LED +! leds_debug_off(); +! } +! return; +! } +! +! void rrube_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/rrube/rrube.h ../../../sys/net/openwsn/07-App/rrube/rrube.h +*** openwsn/07-App/rrube/rrube.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rrube/rrube.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RRUBE_H +! #define __RRUBE_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rRube +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rrube_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RRUBE_H +! #define __RRUBE_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rRube +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rrube_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rt/rt.c ../../../sys/net/openwsn/07-App/rt/rt.c +*** openwsn/07-App/rt/rt.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rt/rt.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,171 **** +! #include "openwsn.h" +! #include "rt.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "sensitive_accel_temperature.h" +! +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define RTPERIOD 20000 +! +! const uint8_t rt_path0[] = "t"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimer_id_t timerId; +! coap_resource_desc_t desc; +! } rt_vars_t; +! +! rt_vars_t rt_vars; +! +! //=========================== prototypes ====================================== +! +! error_t rt_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rt_timer(); +! void rt_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rt_init() { +! // startup the sensor +! sensitive_accel_temperature_init(); +! +! // prepare the resource descriptor for the /temp path +! rt_vars.desc.path0len = sizeof(rt_path0)-1; +! rt_vars.desc.path0val = (uint8_t*)(&rt_path0); +! rt_vars.desc.path1len = 0; +! rt_vars.desc.path1val = NULL; +! rt_vars.desc.componentID = COMPONENT_RT; +! rt_vars.desc.callbackRx = &rt_receive; +! rt_vars.desc.callbackSendDone = &rt_sendDone; +! +! +! rt_vars.timerId = opentimers_start(openrandom_get16b()%RTPERIOD, +! TIMER_PERIODIC,TIME_MS, +! rt_timer); +! opencoap_register(&rt_vars.desc); +! } +! +! //=========================== private ========================================= +! +! error_t rt_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! // start/stop the data generation to data server +! +! if (msg->payload[0]=='1') { +! opentimers_restart(rt_vars.timerId); +! } else { +! opentimers_stop(rt_vars.timerId); +! } +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! outcome = E_SUCCESS; +! +! } else if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current sensor value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP payload (2 bytes of temperature data) +! packetfunctions_reserveHeaderSize(msg,2); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! msg->payload[0] = rawdata[8]; +! msg->payload[1] = rawdata[9]; +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rt_timer() { +! OpenQueueEntry_t* pkt; +! error_t outcome; +! uint8_t numOptions; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RT); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RT,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RT; +! pkt->owner = COMPONENT_RT; +! // CoAP payload (2 bytes of temperature data) +! packetfunctions_reserveHeaderSize(pkt,2); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! pkt->payload[0] = rawdata[8]; +! pkt->payload[1] = rawdata[9]; +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(rt_path0)-1); +! memcpy(&pkt->payload[0],&rt_path0,sizeof(rt_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! sizeof(rt_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rt_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void rt_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,169 ---- +! #include "openwsn.h" +! #include "rt.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "sensitive_accel_temperature.h" +! +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define RTPERIOD 20000 +! +! const uint8_t rt_path0[] = "t"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimer_id_t timerId; +! coap_resource_desc_t desc; +! } rt_vars_t; +! +! rt_vars_t rt_vars; +! +! //=========================== prototypes ====================================== +! +! owerror_t rt_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rt_timer(); +! void rt_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rt_init() { +! // startup the sensor +! sensitive_accel_temperature_init(); +! +! // prepare the resource descriptor for the /temp path +! rt_vars.desc.path0len = sizeof(rt_path0)-1; +! rt_vars.desc.path0val = (uint8_t*)(&rt_path0); +! rt_vars.desc.path1len = 0; +! rt_vars.desc.path1val = NULL; +! rt_vars.desc.componentID = COMPONENT_RT; +! rt_vars.desc.callbackRx = &rt_receive; +! rt_vars.desc.callbackSendDone = &rt_sendDone; +! +! +! rt_vars.timerId = opentimers_start(openrandom_get16b()%RTPERIOD, +! TIMER_PERIODIC,TIME_MS, +! rt_timer); +! opencoap_register(&rt_vars.desc); +! } +! +! //=========================== private ========================================= +! +! owerror_t rt_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! // start/stop the data generation to data server +! +! if (msg->payload[0]=='1') { +! opentimers_restart(rt_vars.timerId); +! } else { +! opentimers_stop(rt_vars.timerId); +! } +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP header +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! outcome = E_SUCCESS; +! +! } else if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current sensor value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP payload (2 bytes of temperature data) +! packetfunctions_reserveHeaderSize(msg,2); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! msg->payload[0] = rawdata[8]; +! msg->payload[1] = rawdata[9]; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rt_timer() { +! OpenQueueEntry_t* pkt; +! owerror_t outcome; +! uint8_t numOptions; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RT); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RT,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RT; +! pkt->owner = COMPONENT_RT; +! // CoAP payload (2 bytes of temperature data) +! packetfunctions_reserveHeaderSize(pkt,2); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! pkt->payload[0] = rawdata[8]; +! pkt->payload[1] = rawdata[9]; +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(rt_path0)-1); +! memcpy(&pkt->payload[0],&rt_path0,sizeof(rt_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(rt_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rt_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! return; +! } +! +! void rt_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/rt/rt.h ../../../sys/net/openwsn/07-App/rt/rt.h +*** openwsn/07-App/rt/rt.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rt/rt.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RT_H +! #define __RT_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rT +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rt_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RT_H +! #define __RT_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rT +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rt_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rwellknown/Makefile ../../../sys/net/openwsn/07-App/rwellknown/Makefile +*** openwsn/07-App/rwellknown/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/rwellknown/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/rwellknown/rwellknown.c ../../../sys/net/openwsn/07-App/rwellknown/rwellknown.c +*** openwsn/07-App/rwellknown/rwellknown.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rwellknown/rwellknown.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,77 **** +! #include "openwsn.h" +! #include "rwellknown.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! } rwellknown_vars_t; +! +! rwellknown_vars_t rwellknown_vars; +! +! const uint8_t rwellknown_path0[] = ".well-known"; +! const uint8_t rwellknown_path1[] = "core"; +! const uint8_t rwellknown_testlink[] = ";if=\"actuator\";rt=\"ipso:light\";ct=\"0\""; +! +! //=========================== prototypes ====================================== +! +! error_t rwellknown_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rwellknown_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rwellknown_init() { +! // prepare the resource descriptor for the /.well-known/core path +! rwellknown_vars.desc.path0len = sizeof(rwellknown_path0)-1; +! rwellknown_vars.desc.path0val = (uint8_t*)(&rwellknown_path0); +! rwellknown_vars.desc.path1len = sizeof(rwellknown_path1)-1; +! rwellknown_vars.desc.path1val = (uint8_t*)(&rwellknown_path1); +! rwellknown_vars.desc.componentID = COMPONENT_RWELLKNOWN; +! rwellknown_vars.desc.callbackRx = &rwellknown_receive; +! rwellknown_vars.desc.callbackSendDone = &rwellknown_sendDone; +! +! opencoap_register(&rwellknown_vars.desc); +! } +! +! //=========================== private ========================================= +! +! error_t rwellknown_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // add link descriptors to the packet +! opencoap_writeLinks(msg); +! +! // add return option +! packetfunctions_reserveHeaderSize(msg,2); +! msg->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! msg->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; +! +! // set the CoAP header +! coap_header->OC = 1; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! } else { +! outcome = E_FAIL; +! } +! return outcome; +! } +! +! void rwellknown_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,80 ---- +! #include "openwsn.h" +! #include "rwellknown.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! } rwellknown_vars_t; +! +! rwellknown_vars_t rwellknown_vars; +! +! const uint8_t rwellknown_path0[] = ".well-known"; +! const uint8_t rwellknown_path1[] = "core"; +! const uint8_t rwellknown_testlink[] = ";if=\"actuator\";rt=\"ipso:light\";ct=\"0\""; +! +! //=========================== prototypes ====================================== +! +! owerror_t rwellknown_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rwellknown_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rwellknown_init(void) { +! +! +! if(idmanager_getIsDAGroot()==TRUE) return; +! +! // prepare the resource descriptor for the /.well-known/core path +! rwellknown_vars.desc.path0len = sizeof(rwellknown_path0)-1; +! rwellknown_vars.desc.path0val = (uint8_t*)(&rwellknown_path0); +! rwellknown_vars.desc.path1len = sizeof(rwellknown_path1)-1; +! rwellknown_vars.desc.path1val = (uint8_t*)(&rwellknown_path1); +! rwellknown_vars.desc.componentID = COMPONENT_RWELLKNOWN; +! rwellknown_vars.desc.callbackRx = &rwellknown_receive; +! rwellknown_vars.desc.callbackSendDone = &rwellknown_sendDone; +! +! opencoap_register(&rwellknown_vars.desc); +! } +! +! //=========================== private ========================================= +! +! owerror_t rwellknown_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! +! if (coap_header->Code==COAP_CODE_REQ_GET) { +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // add link descriptors to the packet +! opencoap_writeLinks(msg); +! +! // add return option +! packetfunctions_reserveHeaderSize(msg,2); +! msg->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! msg->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! } else { +! outcome = E_FAIL; +! } +! return outcome; +! } +! +! void rwellknown_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/rwellknown/rwellknown.h ../../../sys/net/openwsn/07-App/rwellknown/rwellknown.h +*** openwsn/07-App/rwellknown/rwellknown.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rwellknown/rwellknown.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RWELLKNOWN_H +! #define __RWELLKNOWN_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rWellKnown +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rwellknown_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RWELLKNOWN_H +! #define __RWELLKNOWN_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rWellKnown +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rwellknown_init(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/rxl1/rxl1.c ../../../sys/net/openwsn/07-App/rxl1/rxl1.c +*** openwsn/07-App/rxl1/rxl1.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rxl1/rxl1.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,176 **** +! #include "openwsn.h" +! #include "rxl1.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "sensitive_accel_temperature.h" +! +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define RXL1PERIOD 6000 +! +! const uint8_t rxl1_path0[] = "x"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rxl1_vars_t; +! +! rxl1_vars_t rxl1_vars; +! +! //=========================== prototypes ====================================== +! +! error_t rxl1_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rxl1_timer(); +! void rxl1_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void rxl1_init() { +! // startup the sensor +! sensitive_accel_temperature_init(); +! +! // prepare the resource descriptor for the /temp path +! rxl1_vars.desc.path0len = sizeof(rxl1_path0)-1; +! rxl1_vars.desc.path0val = (uint8_t*)(&rxl1_path0); +! rxl1_vars.desc.path1len = 0; +! rxl1_vars.desc.path1val = NULL; +! rxl1_vars.desc.componentID = COMPONENT_RXL1; +! rxl1_vars.desc.callbackRx = &rxl1_receive; +! rxl1_vars.desc.callbackSendDone = &rxl1_sendDone; +! +! //we start a timer, but just to get a timer ID, we stop it immediately +! rxl1_vars.timerId = opentimers_start(openrandom_get16b()%RXL1PERIOD, +! TIMER_PERIODIC,TIME_MS, +! rxl1_timer); +! opentimers_stop(rxl1_vars.timerId); +! +! opencoap_register(&rxl1_vars.desc); +! } +! +! //=========================== private ========================================= +! +! error_t rxl1_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! error_t outcome; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! // start/stop the data generation to data server +! +! if (msg->payload[0]=='1') { +! //restart timer +! opentimers_restart(rxl1_vars.timerId); +! +! } else { +! //stop timer +! opentimers_stop(rxl1_vars.timerId); +! } +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! outcome = E_SUCCESS; +! +! } else if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current sensor value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP payload (8 bytes of XL data) +! packetfunctions_reserveHeaderSize(msg,8); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! memcpy(&msg->payload[0],&rawdata[8],8); +! +! // set the CoAP header +! coap_header->OC = 0; +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rxl1_timer() { +! OpenQueueEntry_t* pkt; +! error_t outcome; +! uint8_t numOptions; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RXL1); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RXL1,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RXL1; +! pkt->owner = COMPONENT_RXL1; +! // CoAP payload (2 bytes of temperature data) +! packetfunctions_reserveHeaderSize(pkt,2); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! pkt->payload[0] = rawdata[8]; +! pkt->payload[1] = rawdata[9]; +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(rxl1_path0)-1); +! memcpy(&pkt->payload[0],&rxl1_path0,sizeof(rxl1_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! sizeof(rxl1_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rxl1_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! +! return; +! } +! +! void rxl1_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); +! } +--- 1,174 ---- +! #include "openwsn.h" +! #include "rxl1.h" +! #include "opentimers.h" +! #include "opencoap.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "sensitive_accel_temperature.h" +! +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define RXL1PERIOD 6000 +! +! const uint8_t rxl1_path0[] = "x"; +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! } rxl1_vars_t; +! +! rxl1_vars_t rxl1_vars; +! +! //=========================== prototypes ====================================== +! +! owerror_t rxl1_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void rxl1_timer(); +! void rxl1_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void rxl1_init() { +! // startup the sensor +! sensitive_accel_temperature_init(); +! +! // prepare the resource descriptor for the /temp path +! rxl1_vars.desc.path0len = sizeof(rxl1_path0)-1; +! rxl1_vars.desc.path0val = (uint8_t*)(&rxl1_path0); +! rxl1_vars.desc.path1len = 0; +! rxl1_vars.desc.path1val = NULL; +! rxl1_vars.desc.componentID = COMPONENT_RXL1; +! rxl1_vars.desc.callbackRx = &rxl1_receive; +! rxl1_vars.desc.callbackSendDone = &rxl1_sendDone; +! +! //we start a timer, but just to get a timer ID, we stop it immediately +! rxl1_vars.timerId = opentimers_start(openrandom_get16b()%RXL1PERIOD, +! TIMER_PERIODIC,TIME_MS, +! rxl1_timer); +! opentimers_stop(rxl1_vars.timerId); +! +! opencoap_register(&rxl1_vars.desc); +! } +! +! //=========================== private ========================================= +! +! owerror_t rxl1_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! owerror_t outcome; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! if (coap_header->Code==COAP_CODE_REQ_POST) { +! // start/stop the data generation to data server +! +! if (msg->payload[0]=='1') { +! //restart timer +! opentimers_restart(rxl1_vars.timerId); +! +! } else { +! //stop timer +! opentimers_stop(rxl1_vars.timerId); +! } +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP header +! coap_header->Code = COAP_CODE_RESP_VALID; +! +! outcome = E_SUCCESS; +! +! } else if (coap_header->Code==COAP_CODE_REQ_GET) { +! // return current sensor value +! +! // reset packet payload +! msg->payload = &(msg->packet[127]); +! msg->length = 0; +! +! // CoAP payload (8 bytes of XL data) +! packetfunctions_reserveHeaderSize(msg,8); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! memcpy(&msg->payload[0],&rawdata[8],8); +! +! // set the CoAP header +! coap_header->Code = COAP_CODE_RESP_CONTENT; +! +! outcome = E_SUCCESS; +! +! } else { +! // return an error message +! outcome = E_FAIL; +! } +! +! return outcome; +! } +! +! void rxl1_timer() { +! OpenQueueEntry_t* pkt; +! owerror_t outcome; +! uint8_t numOptions; +! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; +! +! +! // create a CoAP RD packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_RXL1); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_RXL1,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_RXL1; +! pkt->owner = COMPONENT_RXL1; +! // CoAP payload (2 bytes of temperature data) +! packetfunctions_reserveHeaderSize(pkt,2); +! sensitive_accel_temperature_get_measurement(&rawdata[0]); +! pkt->payload[0] = rawdata[8]; +! pkt->payload[1] = rawdata[9]; +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(rxl1_path0)-1); +! memcpy(&pkt->payload[0],&rxl1_path0,sizeof(rxl1_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | +! sizeof(rxl1_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &rxl1_vars.desc); +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! +! return; +! } +! +! void rxl1_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); +! } +diff -crB openwsn/07-App/rxl1/rxl1.h ../../../sys/net/openwsn/07-App/rxl1/rxl1.h +*** openwsn/07-App/rxl1/rxl1.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/rxl1/rxl1.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __RXL1_H +! #define __RXL1_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup rXL1 +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rxl1_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __RXL1_H +! #define __RXL1_H +! +! /** +! \addtogroup AppCoAP +! \{ +! \addtogroup rXL1 +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void rxl1_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/tcpecho/Makefile ../../../sys/net/openwsn/07-App/tcpecho/Makefile +*** openwsn/07-App/tcpecho/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/tcpecho/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/tcpecho/tcpecho.c ../../../sys/net/openwsn/07-App/tcpecho/tcpecho.c +*** openwsn/07-App/tcpecho/tcpecho.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/tcpecho/tcpecho.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,53 **** +! #include "openwsn.h" +! #include "tcpecho.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "opentcp.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void tcpecho_init() { +! } +! +! bool tcpecho_shouldIlisten() { +! return TRUE; +! } +! +! void tcpecho_receive(OpenQueueEntry_t* msg) { +! uint16_t temp_l4_destination_port; +! msg->owner = COMPONENT_TCPECHO; +! //reply with the same OpenQueueEntry_t +! msg->creator = COMPONENT_TCPECHO; +! msg->l4_protocol = IANA_TCP; +! temp_l4_destination_port = msg->l4_destination_port; +! msg->l4_destination_port = msg->l4_sourcePortORicmpv6Type; +! msg->l4_sourcePortORicmpv6Type = temp_l4_destination_port; +! if (opentcp_send(msg)==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } +! +! void tcpecho_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_TCPECHO; +! if (msg->creator!=COMPONENT_TCPECHO) { +! openserial_printError(COMPONENT_TCPECHO,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! //close TCP session, but keep listening +! opentcp_close(); +! openqueue_freePacketBuffer(msg); +! } +! +! void tcpecho_connectDone() { +! } +! +! bool tcpecho_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,53 ---- +! #include "openwsn.h" +! #include "tcpecho.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "opentcp.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void tcpecho_init(void) { +! } +! +! bool tcpecho_shouldIlisten(void) { +! return TRUE; +! } +! +! void tcpecho_receive(OpenQueueEntry_t* msg) { +! uint16_t temp_l4_destination_port; +! msg->owner = COMPONENT_TCPECHO; +! //reply with the same OpenQueueEntry_t +! msg->creator = COMPONENT_TCPECHO; +! msg->l4_protocol = IANA_TCP; +! temp_l4_destination_port = msg->l4_destination_port; +! msg->l4_destination_port = msg->l4_sourcePortORicmpv6Type; +! msg->l4_sourcePortORicmpv6Type = temp_l4_destination_port; +! if (opentcp_send(msg)==E_FAIL) { +! openqueue_freePacketBuffer(msg); +! } +! } +! +! void tcpecho_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_TCPECHO; +! if (msg->creator!=COMPONENT_TCPECHO) { +! openserial_printError(COMPONENT_TCPECHO,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! //close TCP session, but keep listening +! opentcp_close(); +! openqueue_freePacketBuffer(msg); +! } +! +! void tcpecho_connectDone(owerror_t error) { +! } +! +! bool tcpecho_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/tcpecho/tcpecho.h ../../../sys/net/openwsn/07-App/tcpecho/tcpecho.h +*** openwsn/07-App/tcpecho/tcpecho.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/tcpecho/tcpecho.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,31 **** +! #ifndef __TCPECHO_H +! #define __TCPECHO_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup tcpEcho +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void tcpecho_init(); +! bool tcpecho_shouldIlisten(); +! void tcpecho_receive(OpenQueueEntry_t* msg); +! void tcpecho_sendDone(OpenQueueEntry_t* msg, error_t error); +! void tcpecho_connectDone(); +! bool tcpecho_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,31 ---- +! #ifndef __TCPECHO_H +! #define __TCPECHO_H +! +! /** +! \addtogroup AppTcp +! \{ +! \addtogroup tcpEcho +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void tcpecho_init(void); +! bool tcpecho_shouldIlisten(void); +! void tcpecho_receive(OpenQueueEntry_t* msg); +! void tcpecho_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void tcpecho_connectDone(owerror_t error); +! bool tcpecho_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/tcpinject/Makefile ../../../sys/net/openwsn/07-App/tcpinject/Makefile +*** openwsn/07-App/tcpinject/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/tcpinject/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/tcpinject/tcpinject.c ../../../sys/net/openwsn/07-App/tcpinject/tcpinject.c +*** openwsn/07-App/tcpinject/tcpinject.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/tcpinject/tcpinject.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,95 **** +! #include "openwsn.h" +! #include "tcpinject.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "opentcp.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! OpenQueueEntry_t* pkt; +! bool sending; +! open_addr_t hisAddress; +! uint16_t hisPort; +! } tcpinject_vars_t; +! +! tcpinject_vars_t tcpinject_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void tcpinject_init() { +! } +! +! bool tcpinject_shouldIlisten() { +! return FALSE; +! } +! +! void tcpinject_trigger() { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[18]; +! //get command from OpenSerial (16B IPv6 destination address, 2B destination port) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_TCPINJECT,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! tcpinject_vars.hisAddress.type = ADDR_128B; +! memcpy(&(tcpinject_vars.hisAddress.addr_128b[0]),&(input_buffer[0]),16); +! tcpinject_vars.hisPort = packetfunctions_ntohs(&(input_buffer[16])); +! //connect +! opentcp_connect(&tcpinject_vars.hisAddress,tcpinject_vars.hisPort,WKP_TCP_INJECT); +! } +! +! void tcpinject_connectDone(error_t error) { +! if (error==E_SUCCESS) { +! tcpinject_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_TCPINJECT); +! if (tcpinject_vars.pkt==NULL) { +! openserial_printError(COMPONENT_TCPINJECT,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! tcpinject_vars.pkt->creator = COMPONENT_TCPINJECT; +! tcpinject_vars.pkt->owner = COMPONENT_TCPINJECT; +! tcpinject_vars.pkt->l4_protocol = IANA_UDP; +! tcpinject_vars.pkt->l4_sourcePortORicmpv6Type = WKP_TCP_INJECT; +! tcpinject_vars.pkt->l4_destination_port = tcpinject_vars.hisPort; +! memcpy(&(tcpinject_vars.pkt->l3_destinationAdd),&tcpinject_vars.hisAddress,sizeof(open_addr_t)); +! packetfunctions_reserveHeaderSize(tcpinject_vars.pkt,6); +! ((uint8_t*)tcpinject_vars.pkt->payload)[0] = 'p'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[1] = 'o'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[2] = 'i'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[3] = 'p'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[4] = 'o'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[5] = 'i'; +! if (opentcp_send(tcpinject_vars.pkt)==E_FAIL) { +! openqueue_freePacketBuffer(tcpinject_vars.pkt); +! } +! return; +! } +! } +! +! void tcpinject_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_TCPINJECT; +! if (msg->creator!=COMPONENT_TCPINJECT) { +! openserial_printError(COMPONENT_TCPINJECT,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! opentcp_close(); +! openqueue_freePacketBuffer(msg); +! } +! +! void tcpinject_receive(OpenQueueEntry_t* msg) { +! } +! +! bool tcpinject_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,88 ---- +! #include "openwsn.h" +! #include "tcpinject.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "opentcp.h" +! #include "openqueue.h" +! +! //=========================== variables ======================================= +! +! tcpinject_vars_t tcpinject_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void tcpinject_init(void) { +! } +! +! bool tcpinject_shouldIlisten(void) { +! return FALSE; +! } +! +! void tcpinject_trigger(void) { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[18]; +! //get command from OpenSerial (16B IPv6 destination address, 2B destination port) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_TCPINJECT,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! tcpinject_vars.hisAddress.type = ADDR_128B; +! memcpy(&(tcpinject_vars.hisAddress.addr_128b[0]),&(input_buffer[0]),16); +! tcpinject_vars.hisPort = packetfunctions_ntohs(&(input_buffer[16])); +! //connect +! opentcp_connect(&tcpinject_vars.hisAddress,tcpinject_vars.hisPort,WKP_TCP_INJECT); +! } +! +! void tcpinject_connectDone(owerror_t error) { +! if (error==E_SUCCESS) { +! tcpinject_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_TCPINJECT); +! if (tcpinject_vars.pkt==NULL) { +! openserial_printError(COMPONENT_TCPINJECT,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! tcpinject_vars.pkt->creator = COMPONENT_TCPINJECT; +! tcpinject_vars.pkt->owner = COMPONENT_TCPINJECT; +! tcpinject_vars.pkt->l4_protocol = IANA_UDP; +! tcpinject_vars.pkt->l4_sourcePortORicmpv6Type = WKP_TCP_INJECT; +! tcpinject_vars.pkt->l4_destination_port = tcpinject_vars.hisPort; +! memcpy(&(tcpinject_vars.pkt->l3_destinationAdd),&tcpinject_vars.hisAddress,sizeof(open_addr_t)); +! packetfunctions_reserveHeaderSize(tcpinject_vars.pkt,6); +! ((uint8_t*)tcpinject_vars.pkt->payload)[0] = 'p'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[1] = 'o'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[2] = 'i'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[3] = 'p'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[4] = 'o'; +! ((uint8_t*)tcpinject_vars.pkt->payload)[5] = 'i'; +! if (opentcp_send(tcpinject_vars.pkt)==E_FAIL) { +! openqueue_freePacketBuffer(tcpinject_vars.pkt); +! } +! return; +! } +! } +! +! void tcpinject_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_TCPINJECT; +! if (msg->creator!=COMPONENT_TCPINJECT) { +! openserial_printError(COMPONENT_TCPINJECT,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! opentcp_close(); +! openqueue_freePacketBuffer(msg); +! } +! +! void tcpinject_receive(OpenQueueEntry_t* msg) { +! } +! +! bool tcpinject_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/tcpinject/tcpinject.h ../../../sys/net/openwsn/07-App/tcpinject/tcpinject.h +*** openwsn/07-App/tcpinject/tcpinject.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/tcpinject/tcpinject.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,32 **** +! #ifndef __TCPINJECT_H +! #define __TCPINJECT_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup tcpInject +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void tcpinject_init(); +! bool tcpinject_shouldIlisten(); +! void tcpinject_trigger(); +! void tcpinject_connectDone(error_t error); +! void tcpinject_sendDone(OpenQueueEntry_t* msg, error_t error); +! void tcpinject_receive(OpenQueueEntry_t* msg); +! bool tcpinject_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,39 ---- +! #ifndef __TCPINJECT_H +! #define __TCPINJECT_H +! +! /** +! \addtogroup AppTcp +! \{ +! \addtogroup tcpInject +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== module variables ================================ +! +! typedef struct { +! OpenQueueEntry_t* pkt; +! bool sending; +! open_addr_t hisAddress; +! uint16_t hisPort; +! } tcpinject_vars_t; +! +! //=========================== prototypes ====================================== +! +! void tcpinject_init(void); +! bool tcpinject_shouldIlisten(void); +! void tcpinject_trigger(void); +! void tcpinject_connectDone(owerror_t error); +! void tcpinject_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void tcpinject_receive(OpenQueueEntry_t* msg); +! bool tcpinject_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/tcpprint/Makefile ../../../sys/net/openwsn/07-App/tcpprint/Makefile +*** openwsn/07-App/tcpprint/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/tcpprint/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/tcpprint/tcpprint.c ../../../sys/net/openwsn/07-App/tcpprint/tcpprint.c +*** openwsn/07-App/tcpprint/tcpprint.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/tcpprint/tcpprint.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,37 **** +! #include "openwsn.h" +! #include "tcpprint.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "opentcp.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void tcpprint_init() { +! } +! +! bool tcpprint_shouldIlisten(){ +! return TRUE; +! } +! +! void tcpprint_receive(OpenQueueEntry_t* msg) { +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! //close TCP session, but keep listening +! opentcp_close(); +! openqueue_freePacketBuffer(msg); +! } +! +! void tcpprint_connectDone(error_t error) { +! } +! +! void tcpprint_sendDone(OpenQueueEntry_t* msg, error_t error) { +! } +! +! bool tcpprint_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,37 ---- +! #include "openwsn.h" +! #include "tcpprint.h" +! #include "openserial.h" +! #include "openqueue.h" +! #include "opentcp.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void tcpprint_init(void) { +! } +! +! bool tcpprint_shouldIlisten(void){ +! return TRUE; +! } +! +! void tcpprint_receive(OpenQueueEntry_t* msg) { +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! //close TCP session, but keep listening +! opentcp_close(); +! openqueue_freePacketBuffer(msg); +! } +! +! void tcpprint_connectDone(owerror_t error) { +! } +! +! void tcpprint_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! } +! +! bool tcpprint_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/tcpprint/tcpprint.h ../../../sys/net/openwsn/07-App/tcpprint/tcpprint.h +*** openwsn/07-App/tcpprint/tcpprint.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/tcpprint/tcpprint.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,31 **** +! #ifndef __TCPPRINT_H +! #define __TCPPRINT_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup tcpPrint +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void tcpprint_init(); +! bool tcpprint_shouldIlisten(); +! void tcpprint_receive(OpenQueueEntry_t* msg); +! void tcpprint_connectDone(error_t error); +! void tcpprint_sendDone(OpenQueueEntry_t* msg, error_t error); +! bool tcpprint_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,31 ---- +! #ifndef __TCPPRINT_H +! #define __TCPPRINT_H +! +! /** +! \addtogroup AppTcp +! \{ +! \addtogroup tcpPrint +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void tcpprint_init(void); +! bool tcpprint_shouldIlisten(void); +! void tcpprint_receive(OpenQueueEntry_t* msg); +! void tcpprint_connectDone(owerror_t error); +! void tcpprint_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! bool tcpprint_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/udpecho/Makefile ../../../sys/net/openwsn/07-App/udpecho/Makefile +*** openwsn/07-App/udpecho/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/udpecho/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/udpecho/udpecho.c ../../../sys/net/openwsn/07-App/udpecho/udpecho.c +*** openwsn/07-App/udpecho/udpecho.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpecho/udpecho.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,61 **** +! #include "openwsn.h" +! #include "udpecho.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void udpecho_init() { +! } +! +! void udpecho_receive(OpenQueueEntry_t* msg) { +! uint16_t temp_l4_destination_port; +! +! OpenQueueEntry_t * pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPECHO); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPLATENCY,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! +! pkt->owner = COMPONENT_UDPECHO; +! //reply with the same OpenQueueEntry_t +! pkt->creator = COMPONENT_UDPECHO; +! pkt->l4_protocol = IANA_UDP; +! temp_l4_destination_port = msg->l4_destination_port; +! pkt->l4_destination_port = msg->l4_sourcePortORicmpv6Type; +! pkt->l4_sourcePortORicmpv6Type = temp_l4_destination_port; +! pkt->l3_destinationAdd.type = ADDR_128B; +! //copy source to destination to echo. +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&msg->l3_sourceAdd.addr_128b[0],16); +! +! packetfunctions_reserveHeaderSize(pkt,msg->length); +! memcpy(&pkt->payload[0],&msg->payload[0],msg->length); +! openqueue_freePacketBuffer(msg); +! +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udpecho_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_UDPECHO; +! if (msg->creator!=COMPONENT_UDPECHO) { +! openserial_printError(COMPONENT_UDPECHO,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! bool udpecho_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,61 ---- +! #include "openwsn.h" +! #include "udpecho.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void udpecho_init(void) { +! } +! +! void udpecho_receive(OpenQueueEntry_t* msg) { +! uint16_t temp_l4_destination_port; +! +! OpenQueueEntry_t * pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPECHO); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPLATENCY,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! +! pkt->owner = COMPONENT_UDPECHO; +! //reply with the same OpenQueueEntry_t +! pkt->creator = COMPONENT_UDPECHO; +! pkt->l4_protocol = IANA_UDP; +! temp_l4_destination_port = msg->l4_destination_port; +! pkt->l4_destination_port = msg->l4_sourcePortORicmpv6Type; +! pkt->l4_sourcePortORicmpv6Type = temp_l4_destination_port; +! pkt->l3_destinationAdd.type = ADDR_128B; +! //copy source to destination to echo. +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&msg->l3_sourceAdd.addr_128b[0],16); +! +! packetfunctions_reserveHeaderSize(pkt,msg->length); +! memcpy(&pkt->payload[0],&msg->payload[0],msg->length); +! openqueue_freePacketBuffer(msg); +! +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udpecho_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_UDPECHO; +! if (msg->creator!=COMPONENT_UDPECHO) { +! openserial_printError(COMPONENT_UDPECHO,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! bool udpecho_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/udpecho/udpecho.h ../../../sys/net/openwsn/07-App/udpecho/udpecho.h +*** openwsn/07-App/udpecho/udpecho.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpecho/udpecho.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,29 **** +! #ifndef __UDPECHO_H +! #define __UDPECHO_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup udpEcho +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpecho_init(); +! void udpecho_receive(OpenQueueEntry_t* msg); +! void udpecho_sendDone(OpenQueueEntry_t* msg, error_t error); +! bool udpecho_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,29 ---- +! #ifndef __UDPECHO_H +! #define __UDPECHO_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup udpEcho +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpecho_init(void); +! void udpecho_receive(OpenQueueEntry_t* msg); +! void udpecho_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! bool udpecho_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/udpecho/udpecho.py ../../../sys/net/openwsn/07-App/udpecho/udpecho.py +*** openwsn/07-App/udpecho/udpecho.py Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpecho/udpecho.py Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! import socket +! +! request = "poipoipoipoi" +! myAddress = '' #means 'all' +! myPort = 21568 +! hisAddress = '2001:470:48b8:cfde:1415:9200:12:e63b' +! hisPort = 7 +! +! print "Testing udpEcho..." +! +! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) +! socket_handler.settimeout(5) +! socket_handler.bind((myAddress,myPort)) +! socket_handler.sendto(request,(hisAddress,hisPort)) +! print "\nrequest "+myAddress+"%"+str(myPort)+" -> "+hisAddress+"%"+str(hisPort) +! print request+" ("+str(len(request))+" bytes)" +! try: +! reply,dist_addr = socket_handler.recvfrom(1024) +! except socket.timeout: +! print "\nno reply" +! else: +! print "\nreply "+str(dist_addr[0])+"%"+str(dist_addr[1])+" -> "+myAddress+"%"+str(myPort) +! print reply+" ("+str(len(reply))+" bytes)" +! socket_handler.close() +! +! raw_input("\nPress return to close this window...") +--- 1,32 ---- +! import socket +! +! request = "poipoipoipoi" +! myAddress = '' #means 'all' +! myPort = 21568 +! hisAddress = 'bbbb::1415:920b:0301:00e9' +! hisPort = 7 +! succ = 0 +! fail = 0 +! print "Testing udpEcho..." +! +! for i in range(10): +! print "echo " + str(i) +! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) +! socket_handler.settimeout(5) +! socket_handler.bind((myAddress,myPort)) +! socket_handler.sendto(request,(hisAddress,hisPort)) +! print "\nrequest "+myAddress+"%"+str(myPort)+" -> "+hisAddress+"%"+str(hisPort) +! print request+" ("+str(len(request))+" bytes)" +! try: +! reply,dist_addr = socket_handler.recvfrom(1024) +! except socket.timeout: +! print "\nno reply" +! fail=fail+1 +! else: +! print "\nreply "+str(dist_addr[0])+"%"+str(dist_addr[1])+" -> "+myAddress+"%"+str(myPort) +! print reply+" ("+str(len(reply))+" bytes)" +! succ=succ+1 +! socket_handler.close() +! +! print "success " + str(succ) + " fail " + str(fail) +! raw_input("\nPress return to close this window...") +diff -crB openwsn/07-App/udpinject/Makefile ../../../sys/net/openwsn/07-App/udpinject/Makefile +*** openwsn/07-App/udpinject/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/udpinject/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/udpinject/udpinject.c ../../../sys/net/openwsn/07-App/udpinject/udpinject.c +*** openwsn/07-App/udpinject/udpinject.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpinject/udpinject.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,75 **** +! #include "openwsn.h" +! #include "udpinject.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void udpinject_init() { +! } +! +! void udpinject_trigger() { +! OpenQueueEntry_t* pkt; +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[18]; +! //get command from OpenSerial (16B IPv6 destination address, 2B destination port) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_UDPINJECT,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! //prepare packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPINJECT); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPINJECT,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! pkt->creator = COMPONENT_UDPINJECT; +! pkt->owner = COMPONENT_UDPINJECT; +! pkt->l4_protocol = IANA_UDP; +! pkt->l4_sourcePortORicmpv6Type = WKP_UDP_INJECT; +! pkt->l4_destination_port = packetfunctions_ntohs(&(input_buffer[16])); +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&(pkt->l3_destinationAdd.addr_128b[0]),&(input_buffer[0]),16); +! packetfunctions_reserveHeaderSize(pkt,6); +! ((uint8_t*)pkt->payload)[0] = 'p'; +! ((uint8_t*)pkt->payload)[1] = 'o'; +! ((uint8_t*)pkt->payload)[2] = 'i'; +! ((uint8_t*)pkt->payload)[3] = 'p'; +! ((uint8_t*)pkt->payload)[4] = 'o'; +! ((uint8_t*)pkt->payload)[5] = 'i'; +! //send packet +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udpinject_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_UDPINJECT; +! if (msg->creator!=COMPONENT_UDPINJECT) { +! openserial_printError(COMPONENT_UDPINJECT,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! void udpinject_receive(OpenQueueEntry_t* msg) { +! openqueue_freePacketBuffer(msg); +! } +! +! bool udpinject_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,75 ---- +! #include "openwsn.h" +! #include "udpinject.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void udpinject_init(void) { +! } +! +! void udpinject_trigger(void) { +! OpenQueueEntry_t* pkt; +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[18]; +! //get command from OpenSerial (16B IPv6 destination address, 2B destination port) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&(input_buffer[0]),sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_UDPINJECT,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! //prepare packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPINJECT); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPINJECT,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! pkt->creator = COMPONENT_UDPINJECT; +! pkt->owner = COMPONENT_UDPINJECT; +! pkt->l4_protocol = IANA_UDP; +! pkt->l4_sourcePortORicmpv6Type = WKP_UDP_INJECT; +! pkt->l4_destination_port = packetfunctions_ntohs(&(input_buffer[16])); +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&(pkt->l3_destinationAdd.addr_128b[0]),&(input_buffer[0]),16); +! packetfunctions_reserveHeaderSize(pkt,6); +! ((uint8_t*)pkt->payload)[0] = 'p'; +! ((uint8_t*)pkt->payload)[1] = 'o'; +! ((uint8_t*)pkt->payload)[2] = 'i'; +! ((uint8_t*)pkt->payload)[3] = 'p'; +! ((uint8_t*)pkt->payload)[4] = 'o'; +! ((uint8_t*)pkt->payload)[5] = 'i'; +! //send packet +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udpinject_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_UDPINJECT; +! if (msg->creator!=COMPONENT_UDPINJECT) { +! openserial_printError(COMPONENT_UDPINJECT,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! void udpinject_receive(OpenQueueEntry_t* msg) { +! openqueue_freePacketBuffer(msg); +! } +! +! bool udpinject_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/udpinject/udpinject.h ../../../sys/net/openwsn/07-App/udpinject/udpinject.h +*** openwsn/07-App/udpinject/udpinject.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpinject/udpinject.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,30 **** +! #ifndef __UDPINJECT_H +! #define __UDPINJECT_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup udpInject +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpinject_init(); +! void udpinject_trigger(); +! void udpinject_sendDone(OpenQueueEntry_t* msg, error_t error); +! void udpinject_receive(OpenQueueEntry_t* msg); +! bool udpinject_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,30 ---- +! #ifndef __UDPINJECT_H +! #define __UDPINJECT_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup udpInject +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpinject_init(void); +! void udpinject_trigger(void); +! void udpinject_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void udpinject_receive(OpenQueueEntry_t* msg); +! bool udpinject_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/udplatency/Makefile ../../../sys/net/openwsn/07-App/udplatency/Makefile +*** openwsn/07-App/udplatency/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/udplatency/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/udplatency/udplatency.c ../../../sys/net/openwsn/07-App/udplatency/udplatency.c +*** openwsn/07-App/udplatency/udplatency.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udplatency/udplatency.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,117 **** +! #include "openwsn.h" +! #include "udplatency.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "opentimers.h" +! #include "openrandom.h" +! #include "opencoap.h" +! #include "scheduler.h" +! #include "IEEE802154E.h" +! #include "idmanager.h" +! #include "neighbors.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define UDPLATENCYPERIOD 30000 +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimer_id_t timerId; +! } udplatency_vars_t; +! +! udplatency_vars_t udplatency_vars; +! +! //=========================== prototypes ====================================== +! +! void udplatency_timer(); +! +! //=========================== public ========================================== +! +! void udplatency_init() { +! //don't run on dagroot +! if (idmanager_getIsDAGroot()) return; +! +! udplatency_vars.timerId = opentimers_start(UDPLATENCYPERIOD, +! TIMER_PERIODIC,TIME_MS, +! udplatency_timer); +! } +! +! void udplatency_task(){ +! OpenQueueEntry_t* pkt; +! open_addr_t * p; +! open_addr_t q; +! +! //prepare packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPLATENCY); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPLATENCY,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! pkt->creator = COMPONENT_UDPLATENCY; +! pkt->owner = COMPONENT_UDPLATENCY; +! pkt->l4_protocol = IANA_UDP; +! pkt->l4_sourcePortORicmpv6Type = WKP_UDP_LATENCY; +! pkt->l4_destination_port = WKP_UDP_LATENCY; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16); +! +! //the payload contains the 64bit address of the sender + the ASN +! packetfunctions_reserveHeaderSize(pkt,sizeof(asn_t)); +! asnWriteToPkt(pkt);//gets asn from mac layer. +! +! packetfunctions_reserveHeaderSize(pkt,8); +! p=idmanager_getMyID(ADDR_64B); +! pkt->payload[0]=p->addr_64b[0]; +! pkt->payload[1]=p->addr_64b[1]; +! pkt->payload[2]=p->addr_64b[2]; +! pkt->payload[3]=p->addr_64b[3]; +! pkt->payload[4]=p->addr_64b[4]; +! pkt->payload[5]=p->addr_64b[5]; +! pkt->payload[6]=p->addr_64b[6]; +! pkt->payload[7]=p->addr_64b[7]; +! +! neighbors_getPreferredParentEui64(&q); +! if (q.type==ADDR_64B){ +! packetfunctions_reserveHeaderSize(pkt,8); +! +! //copy my preferred parent so we can build the topology +! pkt->payload[0]=q.addr_64b[0]; +! pkt->payload[1]=q.addr_64b[1]; +! pkt->payload[2]=q.addr_64b[2]; +! pkt->payload[3]=q.addr_64b[3]; +! pkt->payload[4]=q.addr_64b[4]; +! pkt->payload[5]=q.addr_64b[5]; +! pkt->payload[6]=q.addr_64b[6]; +! pkt->payload[7]=q.addr_64b[7]; +! } +! //send packet +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udplatency_timer() { +! scheduler_push_task(udplatency_task,TASKPRIO_COAP); +! } +! +! void udplatency_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_UDPLATENCY; +! if (msg->creator!=COMPONENT_UDPLATENCY) { +! openserial_printError(COMPONENT_UDPLATENCY,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! void udplatency_receive(OpenQueueEntry_t* msg) { +! openqueue_freePacketBuffer(msg); +! } +! +! //=========================== private ========================================= +\ No newline at end of file +--- 1,143 ---- +! #include "openwsn.h" +! #include "udplatency.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "opentimers.h" +! #include "openrandom.h" +! #include "opencoap.h" +! #include "scheduler.h" +! #include "IEEE802154E.h" +! #include "idmanager.h" +! #include "neighbors.h" +! +! #include "thread.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimer_id_t timerId; +! } udplatency_vars_t; +! +! udplatency_vars_t udplatency_vars; +! uint16_t seqNum; +! +! //static char openwsn_udplatency_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! +! //=========================== prototypes ====================================== +! +! void udplatency_timer(void); +! +! //=========================== public ========================================== +! +! void udplatency_init(void) { +! seqNum = 0; +! udplatency_vars.timerId = opentimers_start(UDPLATENCYPERIOD, +! TIMER_PERIODIC,TIME_MS, +! udplatency_timer); +! } +! +! void udplatency_task(void) { +! OpenQueueEntry_t* pkt; +! open_addr_t * p; +! open_addr_t q; +! +! // don't run if not synch +! if (ieee154e_isSynch() == FALSE) return; +! +! // don't run on dagroot +! if (idmanager_getIsDAGroot()) { +! opentimers_stop(udplatency_vars.timerId); +! return; +! } +! +! // prepare packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPLATENCY); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPLATENCY,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! pkt->creator = COMPONENT_UDPLATENCY; +! pkt->owner = COMPONENT_UDPLATENCY; +! pkt->l4_protocol = IANA_UDP; +! pkt->l4_sourcePortORicmpv6Type = WKP_UDP_LATENCY; +! pkt->l4_destination_port = WKP_UDP_LATENCY; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16); +! +! // the payload contains the 64bit address of the sender + the ASN +! packetfunctions_reserveHeaderSize(pkt, sizeof(asn_t)); +! ieee154e_getAsn(pkt->payload);//gets asn from mac layer. +! +! packetfunctions_reserveHeaderSize(pkt,8); +! p=idmanager_getMyID(ADDR_64B); +! pkt->payload[0] = p->addr_64b[0]; +! pkt->payload[1] = p->addr_64b[1]; +! pkt->payload[2] = p->addr_64b[2]; +! pkt->payload[3] = p->addr_64b[3]; +! pkt->payload[4] = p->addr_64b[4]; +! pkt->payload[5] = p->addr_64b[5]; +! pkt->payload[6] = p->addr_64b[6]; +! pkt->payload[7] = p->addr_64b[7]; +! +! neighbors_getPreferredParentEui64(&q); +! if (q.type==ADDR_64B) { +! packetfunctions_reserveHeaderSize(pkt,8); +! +! // copy my preferred parent so we can build the topology +! pkt->payload[0] = q.addr_64b[0]; +! pkt->payload[1] = q.addr_64b[1]; +! pkt->payload[2] = q.addr_64b[2]; +! pkt->payload[3] = q.addr_64b[3]; +! pkt->payload[4] = q.addr_64b[4]; +! pkt->payload[5] = q.addr_64b[5]; +! pkt->payload[6] = q.addr_64b[6]; +! pkt->payload[7] = q.addr_64b[7]; +! } +! +! // insert Sequence Number +! packetfunctions_reserveHeaderSize(pkt,sizeof(seqNum)); +! pkt->payload[0] = (seqNum >> 8) & 0xff; +! pkt->payload[1] = seqNum & 0xff; +! +! // send packet +! if ((openudp_send(pkt)) == E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! // increment seqNum +! seqNum++; +! +! // close timer when test finish +! if (seqNum > NUMPKTTEST) { +! opentimers_stop(udplatency_vars.timerId); +! } +! } +! +! void udplatency_timer(void) { +! scheduler_push_task(udplatency_task,TASKPRIO_COAP); +! /*thread_create(openwsn_udplatency_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_UDPLATENCY, CREATE_STACKTEST, +! udplatency_task, "udplatency task");*/ +! } +! +! void udplatency_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_UDPLATENCY; +! if (msg->creator!=COMPONENT_UDPLATENCY) { +! openserial_printError(COMPONENT_UDPLATENCY,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! void udplatency_receive(OpenQueueEntry_t* msg) { +! openqueue_freePacketBuffer(msg); +! } +! +! //=========================== private ========================================= +diff -crB openwsn/07-App/udplatency/udplatency.h ../../../sys/net/openwsn/07-App/udplatency/udplatency.h +*** openwsn/07-App/udplatency/udplatency.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udplatency/udplatency.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,31 **** +! #ifndef __UDPLATENCY_H +! #define __UDPLATENCY_H +! +! /** +! \addtogroup App +! +! \addtogroup udpLatency +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udplatency_init(); +! void udplatency_trigger(); +! void udplatency_sendDone(OpenQueueEntry_t* msg, error_t error); +! void udplatency_receive(OpenQueueEntry_t* msg); +! bool udplatency_debugPrint(); +! void udplatency_task(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,35 ---- +! #ifndef __UDPLATENCY_H +! #define __UDPLATENCY_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup UdpLatency +! \{ +! */ +! +! //=========================== define ========================================== +! +! /// inter-packet period (in mseconds) +! #define UDPLATENCYPERIOD 3000 +! #define NUMPKTTEST 300 +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udplatency_init(void); +! void udplatency_trigger(void); +! void udplatency_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void udplatency_receive(OpenQueueEntry_t* msg); +! bool udplatency_debugPrint(void); +! void udplatency_task(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/udpprint/Makefile ../../../sys/net/openwsn/07-App/udpprint/Makefile +*** openwsn/07-App/udpprint/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/udpprint/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/udpprint/udpprint.c ../../../sys/net/openwsn/07-App/udpprint/udpprint.c +*** openwsn/07-App/udpprint/udpprint.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpprint/udpprint.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,31 **** +! #include "openwsn.h" +! #include "udpprint.h" +! #include "openqueue.h" +! #include "openserial.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void udpprint_init() { +! } +! +! void udpprint_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openserial_printError(COMPONENT_UDPPRINT,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! +! void udpprint_receive(OpenQueueEntry_t* msg) { +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! openqueue_freePacketBuffer(msg); +! } +! +! bool udpprint_debugPrint() { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,31 ---- +! #include "openwsn.h" +! #include "udpprint.h" +! #include "openqueue.h" +! #include "openserial.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void udpprint_init(void) { +! } +! +! void udpprint_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openserial_printError(COMPONENT_UDPPRINT,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(msg); +! } +! +! void udpprint_receive(OpenQueueEntry_t* msg) { +! openserial_printData((uint8_t*)(msg->payload),msg->length); +! openqueue_freePacketBuffer(msg); +! } +! +! bool udpprint_debugPrint(void) { +! return FALSE; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/udpprint/udpprint.h ../../../sys/net/openwsn/07-App/udpprint/udpprint.h +*** openwsn/07-App/udpprint/udpprint.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpprint/udpprint.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,29 **** +! #ifndef __UDPPRINT_H +! #define __UDPPRINT_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup udpPrint +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpprint_init(); +! void udpprint_sendDone(OpenQueueEntry_t* msg, error_t error); +! void udpprint_receive(OpenQueueEntry_t* msg); +! bool udpprint_debugPrint(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,29 ---- +! #ifndef __UDPPRINT_H +! #define __UDPPRINT_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup udpPrint +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpprint_init(void); +! void udpprint_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void udpprint_receive(OpenQueueEntry_t* msg); +! bool udpprint_debugPrint(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/udprand/Makefile ../../../sys/net/openwsn/07-App/udprand/Makefile +*** openwsn/07-App/udprand/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/udprand/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/udprand/udprand.c ../../../sys/net/openwsn/07-App/udprand/udprand.c +*** openwsn/07-App/udprand/udprand.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udprand/udprand.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,81 **** +! #include "openwsn.h" +! #include "udprand.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "opentimers.h" +! #include "openrandom.h" +! #include "opencoap.h" +! #include "scheduler.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define UDPRANDPERIOD 30000 +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimer_id_t timerId; +! } udprand_vars_t; +! +! udprand_vars_t udprand_vars; +! +! //=========================== prototypes ====================================== +! +! void udprand_timer(); +! +! //=========================== public ========================================== +! +! void udprand_init() { +! udprand_vars.timerId = opentimers_start(openrandom_get16b()%UDPRANDPERIOD, +! TIMER_PERIODIC,TIME_MS, +! udprand_timer); +! } +! +! void udprand_task(){ +! OpenQueueEntry_t* pkt; +! //prepare packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPRAND); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPRAND,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! pkt->creator = COMPONENT_UDPRAND; +! pkt->owner = COMPONENT_UDPRAND; +! pkt->l4_protocol = IANA_UDP; +! pkt->l4_sourcePortORicmpv6Type = WKP_UDP_RAND; +! pkt->l4_destination_port = WKP_UDP_RAND; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16); +! packetfunctions_reserveHeaderSize(pkt,2); +! ((uint8_t*)pkt->payload)[0] = openrandom_get16b()%0xff; +! ((uint8_t*)pkt->payload)[1] = openrandom_get16b()%0xff; +! //send packet +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udprand_timer() { +! scheduler_push_task(udprand_task,TASKPRIO_COAP); +! } +! +! void udprand_sendDone(OpenQueueEntry_t* msg, error_t error) { +! msg->owner = COMPONENT_UDPRAND; +! if (msg->creator!=COMPONENT_UDPRAND) { +! openserial_printError(COMPONENT_UDPRAND,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! void udprand_receive(OpenQueueEntry_t* msg) { +! openqueue_freePacketBuffer(msg); +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,98 ---- +! #include "openwsn.h" +! #include "udprand.h" +! #include "openudp.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "opentimers.h" +! #include "openrandom.h" +! #include "opencoap.h" +! #include "scheduler.h" +! #include "idmanager.h" +! #include "IEEE802154E.h" +! +! #include "thread.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in mseconds) +! #define UDPRANDPERIOD 30000 +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimer_id_t timerId; +! } udprand_vars_t; +! +! udprand_vars_t udprand_vars; +! //static char openwsn_udprand_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! //=========================== prototypes ====================================== +! +! void udprand_timer(void); +! +! //=========================== public ========================================== +! +! void udprand_init(void) { +! udprand_vars.timerId = opentimers_start(openrandom_get16b()%UDPRANDPERIOD, +! TIMER_PERIODIC,TIME_MS, +! udprand_timer); +! } +! +! void udprand_task(void){ +! OpenQueueEntry_t* pkt; +! +! // don't run if not synch +! if (ieee154e_isSynch() == FALSE) return; +! +! // don't run on dagroot +! if (idmanager_getIsDAGroot()) { +! opentimers_stop(udprand_vars.timerId); +! return; +! } +! +! //prepare packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPRAND); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPRAND,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! return; +! } +! pkt->creator = COMPONENT_UDPRAND; +! pkt->owner = COMPONENT_UDPRAND; +! pkt->l4_protocol = IANA_UDP; +! pkt->l4_sourcePortORicmpv6Type = WKP_UDP_RAND; +! pkt->l4_destination_port = WKP_UDP_RAND; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motedata,16); +! packetfunctions_reserveHeaderSize(pkt,2); +! ((uint8_t*)pkt->payload)[0] = openrandom_get16b()%0xff; +! ((uint8_t*)pkt->payload)[1] = openrandom_get16b()%0xff; +! //send packet +! if ((openudp_send(pkt))==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! } +! +! void udprand_timer(void) { +! scheduler_push_task(udprand_task,TASKPRIO_COAP); +! /*thread_create(openwsn_udprand_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_UDPRAND, CREATE_STACKTEST, +! udprand_task, "udprand task");*/ +! } +! +! void udprand_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! msg->owner = COMPONENT_UDPRAND; +! if (msg->creator!=COMPONENT_UDPRAND) { +! openserial_printError(COMPONENT_UDPRAND,ERR_UNEXPECTED_SENDDONE, +! (errorparameter_t)0, +! (errorparameter_t)0); +! } +! openqueue_freePacketBuffer(msg); +! } +! +! void udprand_receive(OpenQueueEntry_t* msg) { +! openqueue_freePacketBuffer(msg); +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/07-App/udprand/udprand.h ../../../sys/net/openwsn/07-App/udprand/udprand.h +*** openwsn/07-App/udprand/udprand.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udprand/udprand.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,31 **** +! #ifndef __UDPRAND_H +! #define __UDPRAND_H +! +! /** +! \addtogroup App +! +! \addtogroup udpRand +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udprand_init(); +! void udprand_trigger(); +! void udprand_sendDone(OpenQueueEntry_t* msg, error_t error); +! void udprand_receive(OpenQueueEntry_t* msg); +! bool udprand_debugPrint(); +! void udprand_task(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,31 ---- +! #ifndef __UDPRAND_H +! #define __UDPRAND_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup UdpRand +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udprand_init(void); +! void udprand_trigger(void); +! void udprand_sendDone(OpenQueueEntry_t* msg, owerror_t error); +! void udprand_receive(OpenQueueEntry_t* msg); +! bool udprand_debugPrint(void); +! void udprand_task(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/07-App/udpstorm/Makefile ../../../sys/net/openwsn/07-App/udpstorm/Makefile +*** openwsn/07-App/udpstorm/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/07-App/udpstorm/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBSUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBSUBMOD) ++ ++ $(BINDIR)$(SUBSUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/07-App/udpstorm/udpstorm.c ../../../sys/net/openwsn/07-App/udpstorm/udpstorm.c +*** openwsn/07-App/udpstorm/udpstorm.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpstorm/udpstorm.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,152 **** +! #include "openwsn.h" +! #include "udpstorm.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "scheduler.h" +! //#include "ADC_Channel.h" +! #include "IEEE802154E.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in ms) +! #define UDPSTORMPERIOD 1000 +! #define NUMPACKETS 300 +! +! const uint8_t udpstorm_path0[] = "strm"; +! +! PRAGMA(pack(1)); +! typedef struct { +! uint16_t seqNum; +! } udpstorm_payload_t; +! PRAGMA(pack()); +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! uint16_t seqNum; +! } udpstorm_vars_t; +! +! udpstorm_vars_t udpstorm_vars; +! +! //=========================== prototypes ====================================== +! +! error_t udpstorm_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void udpstorm_timer_cb(); +! void udpstorm_task_cb(); +! void udpstorm_sendDone(OpenQueueEntry_t* msg, +! error_t error); +! +! //=========================== public ========================================== +! +! void udpstorm_init() { +! // prepare the resource descriptor for the path +! udpstorm_vars.desc.path0len = sizeof(udpstorm_path0)-1; +! udpstorm_vars.desc.path0val = (uint8_t*)(&udpstorm_path0); +! udpstorm_vars.desc.path1len = 0; +! udpstorm_vars.desc.path1val = NULL; +! udpstorm_vars.desc.componentID = COMPONENT_UDPSTORM; +! udpstorm_vars.desc.callbackRx = &udpstorm_receive; +! udpstorm_vars.desc.callbackSendDone = &udpstorm_sendDone; +! +! opencoap_register(&udpstorm_vars.desc); +! udpstorm_vars.timerId = opentimers_start(UDPSTORMPERIOD, +! TIMER_PERIODIC,TIME_MS, +! udpstorm_timer_cb); +! udpstorm_vars.seqNum = 0; +! } +! +! //=========================== private ========================================= +! +! error_t udpstorm_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! return E_FAIL; +! } +! +! //timer fired, but we don't want to execute task in ISR mode +! //instead, push task to scheduler with CoAP priority, and let scheduler take care of it +! void udpstorm_timer_cb(){ +! scheduler_push_task(udpstorm_task_cb,TASKPRIO_COAP); +! } +! +! void udpstorm_task_cb() { +! OpenQueueEntry_t* pkt; +! error_t outcome; +! uint8_t numOptions; +! +! if(udpstorm_vars.seqNum>=NUMPACKETS) { +! // we've sent enough packets +! +! // stop the periodic timer +! opentimers_stop(udpstorm_vars.timerId); +! +! // reset the sequence number +! udpstorm_vars.seqNum = 0; +! } +! +! // if you get here, send a packet +! +! // get a packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPSTORM); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPSTORM,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_UDPSTORM; +! pkt->owner = COMPONENT_UDPSTORM; +! +! // add payload +! packetfunctions_reserveHeaderSize(pkt,sizeof(udpstorm_payload_t)); +! ((udpstorm_payload_t*)(pkt->payload))->seqNum = udpstorm_vars.seqNum; +! +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(udpstorm_path0)-1); +! memcpy(&pkt->payload[0],&udpstorm_path0,sizeof(udpstorm_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | +! sizeof(udpstorm_path0)-1; +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); +! +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &udpstorm_vars.desc); +! +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! // increment counter +! udpstorm_vars.seqNum++; +! } +! +! void udpstorm_sendDone(OpenQueueEntry_t* msg, error_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +--- 1,168 ---- +! #include "openwsn.h" +! #include "udpstorm.h" +! #include "opencoap.h" +! #include "opentimers.h" +! #include "openqueue.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "openrandom.h" +! #include "scheduler.h" +! //#include "ADC_Channel.h" +! #include "IEEE802154E.h" +! #include "idmanager.h" +! +! #include "thread.h" +! +! //=========================== defines ========================================= +! +! /// inter-packet period (in ms) +! #define UDPSTORMPERIOD 1000 +! #define NUMPACKETS 300 +! +! const uint8_t udpstorm_path0[] = "strm"; +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint16_t seqNum; +! } udpstorm_payload_t; +! //PRAGMA(pack()); +! +! //=========================== variables ======================================= +! +! typedef struct { +! coap_resource_desc_t desc; +! opentimer_id_t timerId; +! uint16_t seqNum; +! } udpstorm_vars_t; +! +! udpstorm_vars_t udpstorm_vars; +! //static char openwsn_udpstorm_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! //=========================== prototypes ====================================== +! +! owerror_t udpstorm_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options); +! void udpstorm_timer_cb(void); +! void udpstorm_task_cb(void); +! void udpstorm_sendDone(OpenQueueEntry_t* msg, +! owerror_t error); +! +! //=========================== public ========================================== +! +! void udpstorm_init(void) { +! // prepare the resource descriptor for the path +! udpstorm_vars.desc.path0len = sizeof(udpstorm_path0)-1; +! udpstorm_vars.desc.path0val = (uint8_t*)(&udpstorm_path0); +! udpstorm_vars.desc.path1len = 0; +! udpstorm_vars.desc.path1val = NULL; +! udpstorm_vars.desc.componentID = COMPONENT_UDPSTORM; +! udpstorm_vars.desc.callbackRx = &udpstorm_receive; +! udpstorm_vars.desc.callbackSendDone = &udpstorm_sendDone; +! +! opencoap_register(&udpstorm_vars.desc); +! udpstorm_vars.timerId = opentimers_start(UDPSTORMPERIOD, +! TIMER_PERIODIC,TIME_MS, +! udpstorm_timer_cb); +! udpstorm_vars.seqNum = 0; +! } +! +! //=========================== private ========================================= +! +! owerror_t udpstorm_receive(OpenQueueEntry_t* msg, +! coap_header_iht* coap_header, +! coap_option_iht* coap_options) { +! return E_FAIL; +! } +! +! //timer fired, but we don't want to execute task in ISR mode +! //instead, push task to scheduler with CoAP priority, and let scheduler take care of it +! void udpstorm_timer_cb(void){ +! scheduler_push_task(udpstorm_task_cb,TASKPRIO_COAP); +! /*thread_create(openwsn_udpstorm_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN_UDPSTORM, CREATE_STACKTEST, +! udpstorm_task_cb, "udpstorm task cb");*/ +! } +! +! void udpstorm_task_cb(void) { +! OpenQueueEntry_t* pkt; +! owerror_t outcome; +! uint8_t numOptions; +! +! // don't run if not synch +! if (ieee154e_isSynch() == FALSE) return; +! +! // don't run on dagroot +! if (idmanager_getIsDAGroot()) { +! opentimers_stop(udpstorm_vars.timerId); +! return; +! } +! +! +! if(udpstorm_vars.seqNum>=NUMPACKETS) { +! // we've sent enough packets +! +! // stop the periodic timer +! opentimers_stop(udpstorm_vars.timerId); +! +! // reset the sequence number +! udpstorm_vars.seqNum = 0; +! } +! +! // if you get here, send a packet +! +! // get a packet +! pkt = openqueue_getFreePacketBuffer(COMPONENT_UDPSTORM); +! if (pkt==NULL) { +! openserial_printError(COMPONENT_UDPSTORM,ERR_NO_FREE_PACKET_BUFFER, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openqueue_freePacketBuffer(pkt); +! return; +! } +! // take ownership over that packet +! pkt->creator = COMPONENT_UDPSTORM; +! pkt->owner = COMPONENT_UDPSTORM; +! +! // add payload +! packetfunctions_reserveHeaderSize(pkt,sizeof(udpstorm_payload_t)); +! ((udpstorm_payload_t*)(pkt->payload))->seqNum = udpstorm_vars.seqNum; +! +! numOptions = 0; +! // location-path option +! packetfunctions_reserveHeaderSize(pkt,sizeof(udpstorm_path0)-1); +! memcpy(&pkt->payload[0],&udpstorm_path0,sizeof(udpstorm_path0)-1); +! packetfunctions_reserveHeaderSize(pkt,1); +! pkt->payload[0] = ((COAP_OPTION_NUM_URIPATH) << 4) | +! (sizeof(udpstorm_path0)-1); +! numOptions++; +! // content-type option +! packetfunctions_reserveHeaderSize(pkt,2); +! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | +! 1; +! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; +! numOptions++; +! +! // metadata +! pkt->l4_destination_port = WKP_UDP_COAP; +! pkt->l3_destinationAdd.type = ADDR_128B; +! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); +! +! // send +! outcome = opencoap_send(pkt, +! COAP_TYPE_NON, +! COAP_CODE_REQ_PUT, +! numOptions, +! &udpstorm_vars.desc); +! +! // avoid overflowing the queue if fails +! if (outcome==E_FAIL) { +! openqueue_freePacketBuffer(pkt); +! } +! +! // increment counter +! udpstorm_vars.seqNum++; +! } +! +! void udpstorm_sendDone(OpenQueueEntry_t* msg, owerror_t error) { +! openqueue_freePacketBuffer(msg); + } +\ No newline at end of file +diff -crB openwsn/07-App/udpstorm/udpstorm.h ../../../sys/net/openwsn/07-App/udpstorm/udpstorm.h +*** openwsn/07-App/udpstorm/udpstorm.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/07-App/udpstorm/udpstorm.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,26 **** +! #ifndef __UDPSTORM_H +! #define __UDPSTORM_H +! +! /** +! \addtogroup App +! \{ +! \addtogroup udpStorm +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpstorm_init(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,26 ---- +! #ifndef __UDPSTORM_H +! #define __UDPSTORM_H +! +! /** +! \addtogroup AppUdp +! \{ +! \addtogroup udpStorm +! \{ +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void udpstorm_init(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/Makefile ../../../sys/net/openwsn/Makefile +*** openwsn/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,57 ---- ++ export MODULE:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/cpu/msp430-common/include -I$(RIOTBASE)/sys/net/include/ ++ ++ INCLUDES += -I$(CURDIR) ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ INCLUDES += -I$(CURDIR)/07-APP/rinfo ++ INCLUDES += -I$(CURDIR)/07-APP/rwellknown ++ INCLUDES += -I$(CURDIR)/07-APP/ohlone ++ INCLUDES += -I$(CURDIR)/07-APP/tcpecho ++ INCLUDES += -I$(CURDIR)/07-APP/tcpinject ++ INCLUDES += -I$(CURDIR)/07-APP/tcpprint ++ INCLUDES += -I$(CURDIR)/07-APP/udpecho ++ INCLUDES += -I$(CURDIR)/07-APP/udpinject ++ INCLUDES += -I$(CURDIR)/07-APP/udplatency ++ INCLUDES += -I$(CURDIR)/07-APP/udpprint ++ INCLUDES += -I$(CURDIR)/07-APP/udprand ++ INCLUDES += -I$(CURDIR)/07-APP/udpstorm ++ ++ ++ DIRS = ++ DIRS += cross-layers ++ DIRS += 02a-MAClow ++ DIRS += 02b-MAChigh ++ DIRS += 03a-IPHC ++ DIRS += 03b-IPv6 ++ DIRS += 04-TRAN ++ DIRS += 07-App ++ ++ all: $(BINDIR)$(MODULE) ++ @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; ++ ++ $(BINDIR)$(MODULE): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ mkdir -p $(BINDIR) ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ ++ # remove compilation products ++ clean:: ++ @for i in $(DIRS) ; do "$(MAKE)" -C $$i clean ; done ; +diff -crB openwsn/board_info.h ../../../sys/net/openwsn/board_info.h +*** openwsn/board_info.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/board_info.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,80 **** +! /** +! \brief TelosB-specific board information bsp module. +! +! This module file defines board-related element, but which are applicable only +! to this board. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __BOARD_INFO_H +! #define __BOARD_INFO_H +! +! #include "stdint.h" +! #include "msp430f1611.h" +! #include "string.h" +! +! //=========================== define ========================================== +! +! // (pre-)processor scpecific commands +! +! #define port_INLINE inline +! +! #define PRAGMA(x) _Pragma(#x) +! #define PACK(x) pack(x) +! +! #define INTERRUPT_DECLARATION() __istate_t s; +! #define DISABLE_INTERRUPTS() s = __get_interrupt_state(); \ +! __disable_interrupt(); +! #define ENABLE_INTERRUPTS() __set_interrupt_state(s); +! +! //===== timer +! +! #define PORT_TIMER_WIDTH uint16_t +! #define PORT_SIGNED_INT_WIDTH int16_t +! #define PORT_TICS_PER_MS 33 +! +! // on TelosB, we use the comparatorA interrupt for the OS +! #define SCHEDULER_WAKEUP() CACTL1 |= CAIFG +! #define SCHEDULER_ENABLE_INTERRUPT() CACTL1 = CAIE +! +! //===== pins +! +! // [P4.5] radio VREG +! #define PORT_PIN_RADIO_VREG_HIGH() P4OUT |= 0x20; +! #define PORT_PIN_RADIO_VREG_LOW() P4OUT &= ~0x20; +! // [P4.6] radio RESET +! #define PORT_PIN_RADIO_RESET_HIGH() P4OUT |= 0x40; +! #define PORT_PIN_RADIO_RESET_LOW() P4OUT &= ~0x40; +! +! //===== IEEE802154E timing +! +! // time-slot related +! #define PORT_TsSlotDuration 491 // counter counts one extra count, see datasheet +! +! // execution speed related +! #define PORT_maxTxDataPrepare 100 // 2899us (measured 2420us) +! #define PORT_maxRxAckPrepare 20 // 610us (measured 474us) +! #define PORT_maxRxDataPrepare 33 // 1000us (measured 477us) +! #define PORT_maxTxAckPrepare 40 // 792us (measured 746us)- cannot be bigger than 28.. is the limit for telosb as actvitiy_rt5 is executed almost there. +! +! // radio speed related +! #define PORT_delayTx 12 // 366us (measured 352us) +! #define PORT_delayRx 0 // 0us (can not measure) +! +! //=========================== variables ======================================= +! +! // The variables below are used by CoAP's registration engine. +! +! static const uint8_t rreg_uriquery[] = "h=ucb"; +! static const uint8_t infoBoardname[] = "TelosB"; +! static const uint8_t infouCName[] = "MSP430f1611"; +! static const uint8_t infoRadioName[] = "CC2420"; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! //=========================== private ========================================= +! +! #endif +--- 1,93 ---- +! /** +! \brief TelosB-specific board information bsp module. +! +! This module file defines board-related element, but which are applicable only +! to this board. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __BOARD_INFO_H +! #define __BOARD_INFO_H +! +! #include "stdint.h" +! #include "msp430f1611.h" +! #include "string.h" +! +! //=========================== define ========================================== +! +! // (pre-)processor scpecific commands +! +! #define port_INLINE inline +! +! #define PRAGMA(x) _Pragma(#x) +! #define PACK(x) pack(x) +! +! //===== interrupt state +! +! #if defined(__GNUC__) && (__GNUC__==4) && (__GNUC_MINOR__<=5) && defined(__MSP430__) +! // mspgcc <4.5.x +! #define INTERRUPT_DECLARATION() unsigned short s; +! #define DISABLE_INTERRUPTS() s = READ_SR&0x0008; \ +! __disable_interrupt(); +! #define ENABLE_INTERRUPTS() __asm__("bis %0,r2" : : "ir" ((uint16_t) s)); +! #else +! // other +! #define INTERRUPT_DECLARATION() __istate_t s; +! #define DISABLE_INTERRUPTS() s = __get_interrupt_state(); \ +! __disable_interrupt(); +! #define ENABLE_INTERRUPTS() __set_interrupt_state(s); +! #endif +! +! //===== timer +! +! #define PORT_TIMER_WIDTH uint16_t +! #define PORT_RADIOTIMER_WIDTH uint16_t +! +! #define PORT_SIGNED_INT_WIDTH int16_t +! #define PORT_TICS_PER_MS 33 +! +! // on TelosB, we use the comparatorA interrupt for the OS +! #define SCHEDULER_WAKEUP() CACTL1 |= CAIFG +! #define SCHEDULER_ENABLE_INTERRUPT() CACTL1 = CAIE +! +! //===== pins +! +! // [P4.5] radio VREG +! #define PORT_PIN_RADIO_VREG_HIGH() P4OUT |= 0x20; +! #define PORT_PIN_RADIO_VREG_LOW() P4OUT &= ~0x20; +! // [P4.6] radio RESET +! #define PORT_PIN_RADIO_RESET_HIGH() P4OUT |= 0x40; +! #define PORT_PIN_RADIO_RESET_LOW() P4OUT &= ~0x40; +! +! //===== IEEE802154E timing +! +! // time-slot related +! #define PORT_TsSlotDuration 491 // counter counts one extra count, see datasheet +! +! // execution speed related +! #define PORT_maxTxDataPrepare 100 // 2899us (measured 2420us) +! #define PORT_maxRxAckPrepare 20 // 610us (measured 474us) +! #define PORT_maxRxDataPrepare 33 // 1000us (measured 477us) +! #define PORT_maxTxAckPrepare 40 // 792us (measured 746us)- cannot be bigger than 28.. is the limit for telosb as actvitiy_rt5 is executed almost there. +! +! // radio speed related +! #define PORT_delayTx 12 // 366us (measured 352us) +! #define PORT_delayRx 0 // 0us (can not measure) +! +! //=========================== variables ======================================= +! +! // The variables below are used by CoAP's registration engine. +! +! static const uint8_t rreg_uriquery[] = "h=ucb"; +! static const uint8_t infoBoardname[] = "TelosB"; +! static const uint8_t infouCName[] = "MSP430f1611"; +! static const uint8_t infoRadioName[] = "CC2420"; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! //=========================== private ========================================= +! +! #endif +diff -crB openwsn/board_ow.c ../../../sys/net/openwsn/board_ow.c +*** openwsn/board_ow.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/board_ow.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,138 **** +! /** +! \brief TelosB-specific definition of the "board" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "board.h" +! // bsp modules +! #include "debugpins.h" +! #include "leds.h" +! #include "uart.h" +! #include "spi.h" +! #include "bsp_timer.h" +! #include "radio.h" +! #include "radiotimer.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== main ============================================ +! +! extern int mote_main(void); +! int main(void) { +! return mote_main(); +! } +! +! //=========================== public ========================================== +! +! void board_init() { +! // disable watchdog timer +! WDTCTL = WDTPW + WDTHOLD; +! +! // setup clock speed +! DCOCTL |= DCO0 | DCO1 | DCO2; // MCLK at ~8MHz +! BCSCTL1 |= RSEL0 | RSEL1 | RSEL2; // MCLK at ~8MHz +! // by default, ACLK from 32kHz XTAL which is running +! +! // initialize pins +! P4DIR |= 0x20; // [P4.5] radio VREG: output +! P4DIR |= 0x40; // [P4.6] radio reset: output +! +! // initialize bsp modules +! debugpins_init(); +! leds_init(); +! uart_init(); +! spi_init(); +! bsp_timer_init(); +! radio_init(); +! radiotimer_init(); +! +! // enable interrupts +! __bis_SR_register(GIE); +! } +! +! void board_sleep() { +! __bis_SR_register(GIE+LPM0_bits); // sleep, but leave ACLK on +! } +! +! void board_reset() { +! WDTCTL = (WDTPW+0x1200) + WDTHOLD; // writing a wrong watchdog password to causes handler to reset +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! // DACDMA_VECTOR +! +! // PORT2_VECTOR +! +! #pragma vector = USART1TX_VECTOR +! __interrupt void USART1TX_ISR (void) { +! debugpins_isr_set(); +! if (uart_tx_isr()==KICK_SCHEDULER) { // UART; TX +! __bic_SR_register_on_exit(CPUOFF); +! } +! debugpins_isr_clr(); +! } +! +! #pragma vector = USART1RX_VECTOR +! __interrupt void USART1RX_ISR (void) { +! debugpins_isr_set(); +! if (uart_rx_isr()==KICK_SCHEDULER) { // UART: RX +! __bic_SR_register_on_exit(CPUOFF); +! } +! debugpins_isr_clr(); +! } +! +! // PORT1_VECTOR +! +! // TIMERA1_VECTOR +! +! #pragma vector = TIMERA0_VECTOR +! __interrupt void TIMERA0_ISR (void) { +! debugpins_isr_set(); +! if (bsp_timer_isr()==KICK_SCHEDULER) { // timer: 0 +! __bic_SR_register_on_exit(CPUOFF); +! } +! debugpins_isr_clr(); +! } +! +! // ADC12_VECTOR +! +! // USART0TX_VECTOR +! +! #pragma vector = USART0RX_VECTOR +! __interrupt void USART0RX_ISR (void) { +! debugpins_isr_set(); +! if (spi_isr()==KICK_SCHEDULER) { // SPI +! __bic_SR_register_on_exit(CPUOFF); +! } +! debugpins_isr_clr(); +! } +! +! // WDT_VECTOR +! +! #pragma vector = COMPARATORA_VECTOR +! __interrupt void COMPARATORA_ISR (void) { +! debugpins_isr_set(); +! __bic_SR_register_on_exit(CPUOFF); // restart CPU +! debugpins_isr_clr(); +! } +! +! #pragma vector = TIMERB1_VECTOR +! __interrupt void TIMERB1_ISR (void) { +! debugpins_isr_set(); +! if (radiotimer_isr()==KICK_SCHEDULER) { // radiotimer +! __bic_SR_register_on_exit(CPUOFF); +! } +! debugpins_isr_clr(); +! } +! +! // TIMERB0_VECTOR +! +! // NMI_VECTOR +! +--- 1,65 ---- +! #include "msp430f1611.h" +! #include "board_ow.h" +! +! #include "leds.h" +! #include "uart.h" +! #include "spi.h" +! //#include "bsp_timer.h" +! #include "radio.h" +! #include "radiotimer.h" +! +! void board_init_ow() { +! puts(__PRETTY_FUNCTION__); +! //disable watchdog timer +! WDTCTL = WDTPW + WDTHOLD; +! +! //setup clock speed +! DCOCTL |= DCO0 | DCO1 | DCO2; // MCLK at ~8MHz +! BCSCTL1 |= RSEL0 | RSEL1 | RSEL2; // MCLK at ~8MHz +! // by default, ACLK from 32kHz XTAL which is running +! +! // initialize pins +! P4DIR |= 0x20; // [P4.5] radio VREG: output +! P4DIR |= 0x40; // [P4.6] radio reset: output +! +! // initialize bsp modules +! // debugpins_init(); +! // leds_init(); +! // uart_init_ow(); +! // spi_init(); +! // bsp_timer_init(); +! // radio_init(); +! // radiotimer_init(); +! +! // enable interrupts +! // __bis_SR_register(GIE); +! } +! +! void board_reset() { +! WDTCTL = (WDTPW+0x1200) + WDTHOLD; // writing a wrong watchdog password to causes handler to reset +! } +! +! void board_sleep() { +! __bis_SR_register(GIE+LPM0_bits); // sleep, but leave ACLK on +! } +! // ISR(COMPARATORA) { +! // //debugpins_isr_set(); +! // __bic_SR_register_on_exit(CPUOFF); // restart CPU +! // //debugpins_isr_clr(); +! // } +! +! ISR(TIMERB1) { +! //debugpins_isr_set(); +! if (radiotimer_isr()==KICK_SCHEDULER) { // radiotimer +! __bic_SR_register_on_exit(CPUOFF); +! } +! //debugpins_isr_clr(); +! } +! +! // ISR(TIMERA0) { +! // //debugpins_isr_set(); +! // if (bsp_timer_isr()==KICK_SCHEDULER) { // timer: 0 +! // __bic_SR_register_on_exit(CPUOFF); +! // } +! // //debugpins_isr_clr(); +! // } +diff -crB openwsn/board_ow.h ../../../sys/net/openwsn/board_ow.h +*** openwsn/board_ow.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/board_ow.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,29 **** +! /** +! \brief Cross-platform declaration "board" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __BOARD_H +! #define __BOARD_H +! +! #include "board_info.h" +! +! //=========================== define ========================================== +! +! typedef enum { +! DO_NOT_KICK_SCHEDULER, +! KICK_SCHEDULER, +! } kick_scheduler_t; +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void board_init(); +! void board_sleep(); +! void board_reset(); +! +! #endif +--- 1,49 ---- +! #ifndef __BOARD_H +! #define __BOARD_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup board +! \{ +! +! \brief Cross-platform declaration "board" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "board_info.h" +! +! //=========================== define ========================================== +! +! typedef enum { +! DO_NOT_KICK_SCHEDULER, +! KICK_SCHEDULER, +! } kick_scheduler_t; +! +! #if defined(__GNUC__) && (__GNUC__==4) && (__GNUC_MINOR__<=5) && defined(__MSP430__) +! // mspgcc <4.5.x +! #include +! #define ISR(v) interrupt (v ## _VECTOR) v ## _ISR(void) +! #else +! // other +! #define __PRAGMA__(x) _Pragma(#x) +! #define ISR(v) __PRAGMA__(vector=v ##_VECTOR) __interrupt void v ##_ISR(void) +! #endif +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void board_init_ow(void); +! void board_sleep(void); +! void board_reset(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/cc2420.h ../../../sys/net/openwsn/cc2420.h +*** openwsn/cc2420.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cc2420.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,407 **** +! /** +! \brief Register definitions for the Texas Instruments CC2420 radio chip. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __CC2420_H +! #define __CC2420_H +! +! //=========================== spi flags ======================================= +! +! #define CC2420_FLAG_READ 0x40 +! #define CC2420_FLAG_WRITE 0x00 +! +! #define CC2420_FLAG_RAM 0x80 +! #define CC2420_FLAG_REG 0x00 +! +! //=========================== status byte ===================================== +! +! typedef struct { +! uint8_t reserved_1:1; +! uint8_t rssi_valid:1; +! uint8_t lock:1; +! uint8_t tx_active:1; +! uint8_t enc_busy:1; +! uint8_t tx_underflow:1; +! uint8_t xosc16m_stable:1; +! uint8_t reserved_2:1; +! } cc2420_status_t; +! +! //=========================== strobes ========================================= +! +! #define CC2420_SNOP 0x00 // [S ] No Operation +! #define CC2420_SXOSCON 0x01 // [S ] Turn on the crystal oscillator +! #define CC2420_STXCAL 0x02 // [S ] Enable and calibrate frequency synthesizer for TX +! #define CC2420_SRXON 0x03 // [S ] Enable RX +! #define CC2420_STXON 0x04 // [S ] Enable TX after calibration (if not already performed) +! #define CC2420_STXONCCA 0x05 // [S ] If CCA indicates a clear channel, Enable calibration, then TX +! #define CC2420_SRFOFF 0x06 // [S ] Disable RX/TX and frequency synthesizer +! #define CC2420_SXOSCOFF 0x07 // [S ] Turn off the crystal oscillator and RF +! #define CC2420_SFLUSHRX 0x08 // [S ] Flush the RX FIFO buffer and reset the demodulator +! #define CC2420_SFLUSHTX 0x09 // [S ] Flush the TX FIFO buffer +! #define CC2420_SACK 0x0a // [S ] Send acknowledge frame, with pending field cleared +! #define CC2420_SACKPEND 0x0b // [S ] Send acknowledge frame, with pending field set +! #define CC2420_SRXDEC 0x0c // [S ] Start RXFIFO in-line decryption / authentication +! #define CC2420_STXENC 0x0d // [S ] Start TXFIFO in-line encryption / authentication +! #define CC2420_SAES 0x0e // [S ] AES Stand alone encryption strobe +! +! //=========================== registers ======================================= +! +! /// [R/W] Main Control Register +! #define CC2420_MAIN_ADDR 0x10 +! typedef struct { +! uint16_t XOSC16M_BYPASS:1; +! uint16_t reserved_w0:10; +! uint16_t FS_RESETn:1; +! uint16_t MOD_RESETn:1; +! uint16_t DEMOD_RESETn:1; +! uint16_t ENC_RESETn:1; +! uint16_t RESETn:1; +! } cc2420_MAIN_reg_t; +! +! /// [R/W] Modem Control Register 0 +! #define CC2420_MDMCTRL0_ADDR 0x11 +! typedef struct { +! uint16_t PREAMBLE_LENGTH:4; +! uint16_t AUTOACK:1; +! uint16_t AUTOCRC:1; +! uint16_t CCA_MODE:2; +! uint16_t CCA_HYST:3; +! uint16_t ADR_DECODE:1; +! uint16_t PAN_COORDINATOR:1; +! uint16_t RESERVED_FRAME_MODE:1; +! uint16_t reserved_w0:2; +! } cc2420_MDMCTRL0_reg_t; +! +! /// [R/W] Modem Control Register 1 +! #define CC2420_MDMCTRL1_ADDR 0x12 +! typedef struct { +! uint16_t RX_MODE:2; +! uint16_t TX_MODE:2; +! uint16_t MODULATION_MODE:1; +! uint16_t DEMOD_AVG_MODE:1; +! uint16_t CORR_THR:5; +! uint16_t reserved_w0:5; +! } cc2420_MDMCTRL1_reg_t; +! +! // [R/W] RSSI and CCA Status and Control register +! #define CC2420_RSSI_ADDR 0x13 +! typedef struct { +! uint16_t RSSI_VAL:8; +! uint16_t CCR_THR:8; +! } cc2420_RSSI_reg_t; +! +! /// [R/W] Synchronisation word control register +! #define CC2420_SYNCWORD_ADDR 0x14 +! typedef struct { +! uint16_t SYNCWORD:16; +! } cc2420_SYNCWORD_reg_t; +! +! /// [R/W] Transmit Control Register +! #define CC2420_TXCTRL_ADDR 0x15 +! typedef struct { +! uint16_t PA_LEVEL:5; +! uint16_t reserved_w1:1; +! uint16_t PA_CURRENT:3; +! uint16_t TXMIX_CURRENT:2; +! uint16_t TXMIX_CAP_ARRAY:2; +! uint16_t TX_TURNAROUND:1; +! uint16_t TXMIXBUF_CUR:2; +! } cc2420_TXCTRL_reg_t; +! +! /// [R/W] Receive Control Register 0 +! #define CC2420_RXCTRL0_ADDR 0x16 +! typedef struct { +! uint16_t LOW_LNA_CURRENT:2; +! uint16_t MED_LNA_CURRENT:2; +! uint16_t HIGH_LNA_CURRENT:2; +! uint16_t LOW_LNA_GAIN:2; +! uint16_t MED_LNA_GAIN:2; +! uint16_t HIGH_LNA_GAIN:2; +! uint16_t RXMIXBUF_CUR:2; +! uint16_t reserved_w0:2; +! } cc2420_RXCTRL0_reg_t; +! +! /// [R/W] Receive Control Register 1 +! #define CC2420_RXCTRL1_ADDR 0x17 +! typedef struct { +! uint16_t RXMIX_CURRENT:2; +! uint16_t RXMIX_VCM:2; +! uint16_t RXMIX_TAIL:2; +! uint16_t LNA_CAP_ARRAY:2; +! uint16_t MED_HGM:1; +! uint16_t HIGH_HGM:1; +! uint16_t MED_LOWGAIN:1; +! uint16_t LOW_LOWGAIN:1; +! uint16_t RXBPF_MIDCUR:1; +! uint16_t RXBPF_LOCUR:1; +! uint16_t reserved_w0:2; +! } cc2420_RXCTRL1_reg_t; +! +! /// [R/W] Frequency Synthesizer Control and Status Register +! #define CC2420_FSCTRL_ADDR 0x18 +! typedef struct { +! uint16_t FREQ:10; +! uint16_t LOCK_STATUS:1; +! uint16_t LOCK_LENGTH:1; +! uint16_t CAL_RUNNING:1; +! uint16_t CAL_DONE:1; +! uint16_t LOCK_THR:2; +! } cc2420_FSCTRL_reg_t; +! +! /// [R/W] Security Control Register 0 +! #define CC2420_SECCTRL0_ADDR 0x19 +! typedef struct { +! uint16_t SEC_MODE:2; +! uint16_t SEC_M:3; +! uint16_t SEC_RXKEYSEL:1; +! uint16_t SEC_TXKEYSEL:1; +! uint16_t SEC_SAKEYSEL:1; +! uint16_t SEC_CBC_HEAD:1; +! uint16_t RXFIFO_PROTECTION:1; +! uint16_t reserved_w0:6; +! } cc2420_SECCTRL0_reg_t; +! +! /// [R/W] Security Control Register 1 +! #define CC2420_SECCTRL1_ADDR 0x1a +! typedef struct { +! uint16_t SEC_RXL:7; +! uint16_t reserved_1_w0:1; +! uint16_t SEC_TXL:7; +! uint16_t reserved_2_w0:1; +! } cc2420_SECCTRL1_reg_t; +! +! /// [R/W] Battery Monitor Control and Status Register +! #define CC2420_BATTMON_ADDR 0x1b +! typedef struct { +! uint16_t BATTMON_VOLTAGE:5; +! uint16_t BATTMON_EN:1; +! uint16_t BATTMON_OK:1; +! uint16_t reserved_w0:9; +! } cc2420_BATTMON_reg_t; +! +! /// [R/W] Input / Output Control Register 0 +! #define CC2420_IOCFG0_ADDR 0x1c +! typedef struct { +! uint16_t FIFOP_THR:7; +! uint16_t CCA_POLARITY:1; +! uint16_t SFD_POLARITY:1; +! uint16_t FIFOP_POLARITY:1; +! uint16_t FIFO_POLARITY:1; +! uint16_t BCN_ACCEPT:1; +! uint16_t reserved_w0:4; +! } cc2420_IOCFG0_reg_t; +! +! /// [R/W] Input / Output Control Register 1 +! #define CC2420_IOCFG1_ADDR 0x1d +! typedef struct { +! uint16_t CCAMUX:5; +! uint16_t SFDMUX:5; +! uint16_t HSSD_SRC:3; +! uint16_t reserved_w0:3; +! } cc2420_IOCFG1_reg_t; +! +! /// [R/W] Manufacturer ID, Low 16 bits +! #define CC2420_MANFIDL_ADDR 0x1e +! typedef struct { +! uint16_t MANFID:12; +! uint16_t PARTNUM:4; +! } cc2420_MANFIDL_reg_t; +! +! /// [R/W] Manufacturer ID, High 16 bits +! #define CC2420_MANFIDH_ADDR 0x1f +! typedef struct { +! uint16_t PARTNUM:12; +! uint16_t VERSION:4; +! } cc2420_MANFIDH_reg_t; +! +! /// [R/W] Finite State Machine Time Constants +! #define CC2420_FSMTC_ADDR 0x20 +! typedef struct { +! uint16_t TC_TXEND2PAOFF:3; +! uint16_t TC_TXEND2SWITCH:3; +! uint16_t TC_PAON2TX:4; +! uint16_t TC_SWITCH2TX:3; +! uint16_t TC_RXCHAIN2RX:3; +! } cc2420_FSMTC_reg_t; +! +! /// [R/W] Manual signal AND override register +! #define CC2420_MANAND_ADDR 0x21 +! typedef struct { +! uint16_t LNAMIX_PD:1; +! uint16_t RXBPF_PD:1; +! uint16_t VGA_PD:1; +! uint16_t ADC_PD:1; +! uint16_t FS_PD:1; +! uint16_t CHP_PD:1; +! uint16_t RXBPF_CAL_PD:1; +! uint16_t XOSC16M_PD:1; +! uint16_t DAC_LPF_PD:1; +! uint16_t PA_P_PD:1; +! uint16_t PA_N_PD:1; +! uint16_t PRE_PD:1; +! uint16_t RXTX:1; +! uint16_t BALUN_CTRL:1; +! uint16_t BIAS_PD:1; +! uint16_t VGA_RESET_N:1; +! } cc2420_MANAND_reg_t; +! +! /// [R/W] Manual signal OR override register +! #define CC2420_MANOR_ADDR 0x22 +! typedef struct { +! uint16_t LNAMIX_PD:1; +! uint16_t RXBPF_PD:1; +! uint16_t VGA_PD:1; +! uint16_t ADC_PD:1; +! uint16_t FS_PD:1; +! uint16_t CHP_PD:1; +! uint16_t RXBPF_CAL_PD:1; +! uint16_t XOSC16M_PD:1; +! uint16_t DAC_LPF_PD:1; +! uint16_t PA_P_PD:1; +! uint16_t PA_N_PD:1; +! uint16_t PRE_PD:1; +! uint16_t RXTX:1; +! uint16_t BALUN_CTRL:1; +! uint16_t BIAS_PD:1; +! uint16_t VGA_RESET_N:1; +! } cc2420_MANOR_reg_t; +! +! /// [R/W] AGC Control Register +! #define CC2420_AGCCTRL_ADDR 0x23 +! typedef struct { +! uint16_t LNAMIX_GAINMODE:2; +! uint16_t LNAMIX_GAINMODE_O:2; +! uint16_t VGA_GAIN:7; +! uint16_t VGA_GAIN_OE:1; +! uint16_t reserved_w0:4; +! } cc2420_AGCCTRL_reg_t; +! +! /// [R/W] AGC Test Register 0 +! #define CC2420_AGCTST0_ADDR 0x24 +! typedef struct { +! uint16_t LNAMIX_THR_L:6; +! uint16_t LNAMIX_THR_H:6; +! uint16_t LNAMIX_HYST:4; +! } cc2420_AGCTST0_reg_t; +! +! /// [R/W] AGC Test Register 1 +! #define CC2420_AGCTST1_ADDR 0x25 +! typedef struct { +! uint16_t AGC_REF:6; +! uint16_t AGC_WIN_SIZE:2; +! uint16_t AGC_PEAK_DET_MODE:3; +! uint16_t AGC_SETTLE_WAIT:2; +! uint16_t PEAKDET_CUR_BOOST:1; +! uint16_t AGC_BLANK_MODE:1; +! uint16_t reserved_w0:1; +! } cc2420_AGCTST1_reg_t; +! +! /// [R/W] AGC Test Register 2 +! #define CC2420_AGCTST2_ADDR 0x26 +! typedef struct { +! uint16_t LOW2MEDGAIN:5; +! uint16_t MED2HIGHGAIN:5; +! uint16_t reserved_w0:6; +! } cc2420_AGCTST2_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 0 +! #define CC2420_FSTST0_ADDR 0x27 +! typedef struct { +! uint16_t VCO_ARRAY_RES:5; +! uint16_t VCO_ARRAY_O:5; +! uint16_t VCO_ARRAY_OE:1; +! uint16_t VCO_ARRAY_SETTLE_LONG:1; +! uint16_t reserved_w0:4; +! } cc2420_FSTST0_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 1 +! #define CC2420_FSTST1_ADDR 0x28 +! typedef struct { +! uint16_t VC_DAC_VAL:3; +! uint16_t VC_DAC_EN:1; +! uint16_t VCO_CURRENT_K:6; +! uint16_t VCO_CURRENT_REF:4; +! uint16_t VCO_ARRAY_CAL_LONG:1; +! uint16_t VCO_TX_NOCAL:1; +! } cc2420_FSTST1_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 2 +! #define CC2420_FSTST2_ADDR 0x29 +! typedef struct { +! uint16_t VCO_CURRENT_RES:6; +! uint16_t VCO_CURRENT_O:6; +! uint16_t VCO_CURRENT_OE:1; +! uint16_t VCO_CURCAL_SPEED:2; +! uint16_t reserved_w0:1; +! } cc2420_FSTST2_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 3 +! #define CC2420_FSTST3_ADDR 0x2a +! typedef struct { +! uint16_t START_CHP_CURRENT:4; +! uint16_t STOP_CHP_CURRENT:4; +! uint16_t CHP_STEP_PERIOD:2; +! uint16_t PD_DELAY:1; +! uint16_t CHP_DISABLE:1; +! uint16_t CHP_TEST_DN:1; +! uint16_t CHP_TEST_UP:1; +! uint16_t CHP_CURRENT_OE:1; +! uint16_t CHP_CAL_DISABLE:1; +! } cc2420_FSTST3_reg_t; +! +! /// [R/W] Receiver Bandpass Filter Test Register +! #define CC2420_RXBPFTST_ADDR 0x2b +! typedef struct { +! uint16_t RXBPF_CAP_RES:7; +! uint16_t RXBPF_CAP_O:7; +! uint16_t RXBPF_CAP_OE:1; +! uint16_t reserved_w0:1; +! } cc2420_RXBPFTST_reg_t; +! +! /// [R ] Finite State Machine State Status Register +! #define CC2420_FSMSTATE_ADDR 0x2c +! typedef struct { +! uint16_t FSM_CUR_STATE:6; +! uint16_t reserved_w0:10; +! } cc2420_FSMSTATE_reg_t; +! +! /// [R/W] ADC Test Register +! #define CC2420_ADCTST_ADDR 0x2d +! typedef struct { +! uint16_t ADC_Q:7; +! uint16_t reserved_w0:1; +! uint16_t ADC_I:7; +! uint16_t ADC_CLOCK_DISABLE:1; +! } cc2420_ADCTST_reg_t; +! +! /// [R/W] DAC Test Register +! #define CC2420_DACTST_ADDR 0x2e +! typedef struct { +! uint16_t DAC_Q_O:6; +! uint16_t DAC_I_O:6; +! uint16_t DAC_SRC:3; +! uint16_t reserved_w0:1; +! } cc2420_DACTST_reg_t; +! +! /// [R/W] Top Level Test Register +! #define CC2420_TOPTST_ADDR 0x2f +! typedef struct { +! uint16_t ATESTMOD_MODE:4; +! uint16_t ATESTMOD_PD:1; +! uint16_t VC_IN_TEST_EN:1; +! uint16_t TEST_BATTMON_EN:1; +! uint16_t RAM_BIST_RUN:1; +! uint16_t reserved_w0:8; +! } cc2420_TOPTST_reg_t; +! +! //=========================== buffer ========================================== +! +! /// [ W] Transmit FIFO Byte Register +! #define CC2420_TXFIFO_ADDR 0x3e +! +! /// [R/W] Receiver FIFO Byte Register +! #define CC2420_RXFIFO_ADDR 0x3f +! + #endif +\ No newline at end of file +--- 1,407 ---- +! /** +! \brief Register definitions for the Texas Instruments CC2420 radio chip. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __CC2420_H +! #define __CC2420_H +! +! //=========================== spi flags ======================================= +! +! #define CC2420_FLAG_READ 0x40 +! #define CC2420_FLAG_WRITE 0x00 +! +! #define CC2420_FLAG_RAM 0x80 +! #define CC2420_FLAG_REG 0x00 +! +! //=========================== status byte ===================================== +! +! typedef struct { +! uint8_t reserved_1:1; +! uint8_t rssi_valid:1; +! uint8_t lock:1; +! uint8_t tx_active:1; +! uint8_t enc_busy:1; +! uint8_t tx_underflow:1; +! uint8_t xosc16m_stable:1; +! uint8_t reserved_2:1; +! } cc2420_status_t; +! +! //=========================== strobes ========================================= +! +! #define CC2420_SNOP 0x00 // [S ] No Operation +! #define CC2420_SXOSCON 0x01 // [S ] Turn on the crystal oscillator +! #define CC2420_STXCAL 0x02 // [S ] Enable and calibrate frequency synthesizer for TX +! #define CC2420_SRXON 0x03 // [S ] Enable RX +! #define CC2420_STXON 0x04 // [S ] Enable TX after calibration (if not already performed) +! #define CC2420_STXONCCA 0x05 // [S ] If CCA indicates a clear channel, Enable calibration, then TX +! #define CC2420_SRFOFF 0x06 // [S ] Disable RX/TX and frequency synthesizer +! #define CC2420_SXOSCOFF 0x07 // [S ] Turn off the crystal oscillator and RF +! #define CC2420_SFLUSHRX 0x08 // [S ] Flush the RX FIFO buffer and reset the demodulator +! #define CC2420_SFLUSHTX 0x09 // [S ] Flush the TX FIFO buffer +! #define CC2420_SACK 0x0a // [S ] Send acknowledge frame, with pending field cleared +! #define CC2420_SACKPEND 0x0b // [S ] Send acknowledge frame, with pending field set +! #define CC2420_SRXDEC 0x0c // [S ] Start RXFIFO in-line decryption / authentication +! #define CC2420_STXENC 0x0d // [S ] Start TXFIFO in-line encryption / authentication +! #define CC2420_SAES 0x0e // [S ] AES Stand alone encryption strobe +! +! //=========================== registers ======================================= +! +! /// [R/W] Main Control Register +! #define CC2420_MAIN_ADDR 0x10 +! typedef struct { +! uint16_t XOSC16M_BYPASS:1; +! uint16_t reserved_w0:10; +! uint16_t FS_RESETn:1; +! uint16_t MOD_RESETn:1; +! uint16_t DEMOD_RESETn:1; +! uint16_t ENC_RESETn:1; +! uint16_t RESETn:1; +! } cc2420_MAIN_reg_t; +! +! /// [R/W] Modem Control Register 0 +! #define CC2420_MDMCTRL0_ADDR 0x11 +! typedef struct { +! uint16_t PREAMBLE_LENGTH:4; +! uint16_t AUTOACK:1; +! uint16_t AUTOCRC:1; +! uint16_t CCA_MODE:2; +! uint16_t CCA_HYST:3; +! uint16_t ADR_DECODE:1; +! uint16_t PAN_COORDINATOR:1; +! uint16_t RESERVED_FRAME_MODE:1; +! uint16_t reserved_w0:2; +! } cc2420_MDMCTRL0_reg_t; +! +! /// [R/W] Modem Control Register 1 +! #define CC2420_MDMCTRL1_ADDR 0x12 +! typedef struct { +! uint16_t RX_MODE:2; +! uint16_t TX_MODE:2; +! uint16_t MODULATION_MODE:1; +! uint16_t DEMOD_AVG_MODE:1; +! uint16_t CORR_THR:5; +! uint16_t reserved_w0:5; +! } cc2420_MDMCTRL1_reg_t; +! +! // [R/W] RSSI and CCA Status and Control register +! #define CC2420_RSSI_ADDR 0x13 +! typedef struct { +! uint16_t RSSI_VAL:8; +! uint16_t CCR_THR:8; +! } cc2420_RSSI_reg_t; +! +! /// [R/W] Synchronisation word control register +! #define CC2420_SYNCWORD_ADDR 0x14 +! typedef struct { +! uint16_t SYNCWORD:16; +! } cc2420_SYNCWORD_reg_t; +! +! /// [R/W] Transmit Control Register +! #define CC2420_TXCTRL_ADDR 0x15 +! typedef struct { +! uint16_t PA_LEVEL:5; +! uint16_t reserved_w1:1; +! uint16_t PA_CURRENT:3; +! uint16_t TXMIX_CURRENT:2; +! uint16_t TXMIX_CAP_ARRAY:2; +! uint16_t TX_TURNAROUND:1; +! uint16_t TXMIXBUF_CUR:2; +! } cc2420_TXCTRL_reg_t; +! +! /// [R/W] Receive Control Register 0 +! #define CC2420_RXCTRL0_ADDR 0x16 +! typedef struct { +! uint16_t LOW_LNA_CURRENT:2; +! uint16_t MED_LNA_CURRENT:2; +! uint16_t HIGH_LNA_CURRENT:2; +! uint16_t LOW_LNA_GAIN:2; +! uint16_t MED_LNA_GAIN:2; +! uint16_t HIGH_LNA_GAIN:2; +! uint16_t RXMIXBUF_CUR:2; +! uint16_t reserved_w0:2; +! } cc2420_RXCTRL0_reg_t; +! +! /// [R/W] Receive Control Register 1 +! #define CC2420_RXCTRL1_ADDR 0x17 +! typedef struct { +! uint16_t RXMIX_CURRENT:2; +! uint16_t RXMIX_VCM:2; +! uint16_t RXMIX_TAIL:2; +! uint16_t LNA_CAP_ARRAY:2; +! uint16_t MED_HGM:1; +! uint16_t HIGH_HGM:1; +! uint16_t MED_LOWGAIN:1; +! uint16_t LOW_LOWGAIN:1; +! uint16_t RXBPF_MIDCUR:1; +! uint16_t RXBPF_LOCUR:1; +! uint16_t reserved_w0:2; +! } cc2420_RXCTRL1_reg_t; +! +! /// [R/W] Frequency Synthesizer Control and Status Register +! #define CC2420_FSCTRL_ADDR 0x18 +! typedef struct { +! uint16_t FREQ:10; +! uint16_t LOCK_STATUS:1; +! uint16_t LOCK_LENGTH:1; +! uint16_t CAL_RUNNING:1; +! uint16_t CAL_DONE:1; +! uint16_t LOCK_THR:2; +! } cc2420_FSCTRL_reg_t; +! +! /// [R/W] Security Control Register 0 +! #define CC2420_SECCTRL0_ADDR 0x19 +! typedef struct { +! uint16_t SEC_MODE:2; +! uint16_t SEC_M:3; +! uint16_t SEC_RXKEYSEL:1; +! uint16_t SEC_TXKEYSEL:1; +! uint16_t SEC_SAKEYSEL:1; +! uint16_t SEC_CBC_HEAD:1; +! uint16_t RXFIFO_PROTECTION:1; +! uint16_t reserved_w0:6; +! } cc2420_SECCTRL0_reg_t; +! +! /// [R/W] Security Control Register 1 +! #define CC2420_SECCTRL1_ADDR 0x1a +! typedef struct { +! uint16_t SEC_RXL:7; +! uint16_t reserved_1_w0:1; +! uint16_t SEC_TXL:7; +! uint16_t reserved_2_w0:1; +! } cc2420_SECCTRL1_reg_t; +! +! /// [R/W] Battery Monitor Control and Status Register +! #define CC2420_BATTMON_ADDR 0x1b +! typedef struct { +! uint16_t BATTMON_VOLTAGE:5; +! uint16_t BATTMON_EN:1; +! uint16_t BATTMON_OK:1; +! uint16_t reserved_w0:9; +! } cc2420_BATTMON_reg_t; +! +! /// [R/W] Input / Output Control Register 0 +! #define CC2420_IOCFG0_ADDR 0x1c +! typedef struct { +! uint16_t FIFOP_THR:7; +! uint16_t CCA_POLARITY:1; +! uint16_t SFD_POLARITY:1; +! uint16_t FIFOP_POLARITY:1; +! uint16_t FIFO_POLARITY:1; +! uint16_t BCN_ACCEPT:1; +! uint16_t reserved_w0:4; +! } cc2420_IOCFG0_reg_t; +! +! /// [R/W] Input / Output Control Register 1 +! #define CC2420_IOCFG1_ADDR 0x1d +! typedef struct { +! uint16_t CCAMUX:5; +! uint16_t SFDMUX:5; +! uint16_t HSSD_SRC:3; +! uint16_t reserved_w0:3; +! } cc2420_IOCFG1_reg_t; +! +! /// [R/W] Manufacturer ID, Low 16 bits +! #define CC2420_MANFIDL_ADDR 0x1e +! typedef struct { +! uint16_t MANFID:12; +! uint16_t PARTNUM:4; +! } cc2420_MANFIDL_reg_t; +! +! /// [R/W] Manufacturer ID, High 16 bits +! #define CC2420_MANFIDH_ADDR 0x1f +! typedef struct { +! uint16_t PARTNUM:12; +! uint16_t AVERSION:4; // collision with -DVERSION=$(GIT_VERSION) +! } cc2420_MANFIDH_reg_t; +! +! /// [R/W] Finite State Machine Time Constants +! #define CC2420_FSMTC_ADDR 0x20 +! typedef struct { +! uint16_t TC_TXEND2PAOFF:3; +! uint16_t TC_TXEND2SWITCH:3; +! uint16_t TC_PAON2TX:4; +! uint16_t TC_SWITCH2TX:3; +! uint16_t TC_RXCHAIN2RX:3; +! } cc2420_FSMTC_reg_t; +! +! /// [R/W] Manual signal AND override register +! #define CC2420_MANAND_ADDR 0x21 +! typedef struct { +! uint16_t LNAMIX_PD:1; +! uint16_t RXBPF_PD:1; +! uint16_t VGA_PD:1; +! uint16_t ADC_PD:1; +! uint16_t FS_PD:1; +! uint16_t CHP_PD:1; +! uint16_t RXBPF_CAL_PD:1; +! uint16_t XOSC16M_PD:1; +! uint16_t DAC_LPF_PD:1; +! uint16_t PA_P_PD:1; +! uint16_t PA_N_PD:1; +! uint16_t PRE_PD:1; +! uint16_t RXTX:1; +! uint16_t BALUN_CTRL:1; +! uint16_t BIAS_PD:1; +! uint16_t VGA_RESET_N:1; +! } cc2420_MANAND_reg_t; +! +! /// [R/W] Manual signal OR override register +! #define CC2420_MANOR_ADDR 0x22 +! typedef struct { +! uint16_t LNAMIX_PD:1; +! uint16_t RXBPF_PD:1; +! uint16_t VGA_PD:1; +! uint16_t ADC_PD:1; +! uint16_t FS_PD:1; +! uint16_t CHP_PD:1; +! uint16_t RXBPF_CAL_PD:1; +! uint16_t XOSC16M_PD:1; +! uint16_t DAC_LPF_PD:1; +! uint16_t PA_P_PD:1; +! uint16_t PA_N_PD:1; +! uint16_t PRE_PD:1; +! uint16_t RXTX:1; +! uint16_t BALUN_CTRL:1; +! uint16_t BIAS_PD:1; +! uint16_t VGA_RESET_N:1; +! } cc2420_MANOR_reg_t; +! +! /// [R/W] AGC Control Register +! #define CC2420_AGCCTRL_ADDR 0x23 +! typedef struct { +! uint16_t LNAMIX_GAINMODE:2; +! uint16_t LNAMIX_GAINMODE_O:2; +! uint16_t VGA_GAIN:7; +! uint16_t VGA_GAIN_OE:1; +! uint16_t reserved_w0:4; +! } cc2420_AGCCTRL_reg_t; +! +! /// [R/W] AGC Test Register 0 +! #define CC2420_AGCTST0_ADDR 0x24 +! typedef struct { +! uint16_t LNAMIX_THR_L:6; +! uint16_t LNAMIX_THR_H:6; +! uint16_t LNAMIX_HYST:4; +! } cc2420_AGCTST0_reg_t; +! +! /// [R/W] AGC Test Register 1 +! #define CC2420_AGCTST1_ADDR 0x25 +! typedef struct { +! uint16_t AGC_REF:6; +! uint16_t AGC_WIN_SIZE:2; +! uint16_t AGC_PEAK_DET_MODE:3; +! uint16_t AGC_SETTLE_WAIT:2; +! uint16_t PEAKDET_CUR_BOOST:1; +! uint16_t AGC_BLANK_MODE:1; +! uint16_t reserved_w0:1; +! } cc2420_AGCTST1_reg_t; +! +! /// [R/W] AGC Test Register 2 +! #define CC2420_AGCTST2_ADDR 0x26 +! typedef struct { +! uint16_t LOW2MEDGAIN:5; +! uint16_t MED2HIGHGAIN:5; +! uint16_t reserved_w0:6; +! } cc2420_AGCTST2_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 0 +! #define CC2420_FSTST0_ADDR 0x27 +! typedef struct { +! uint16_t VCO_ARRAY_RES:5; +! uint16_t VCO_ARRAY_O:5; +! uint16_t VCO_ARRAY_OE:1; +! uint16_t VCO_ARRAY_SETTLE_LONG:1; +! uint16_t reserved_w0:4; +! } cc2420_FSTST0_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 1 +! #define CC2420_FSTST1_ADDR 0x28 +! typedef struct { +! uint16_t VC_DAC_VAL:3; +! uint16_t VC_DAC_EN:1; +! uint16_t VCO_CURRENT_K:6; +! uint16_t VCO_CURRENT_REF:4; +! uint16_t VCO_ARRAY_CAL_LONG:1; +! uint16_t VCO_TX_NOCAL:1; +! } cc2420_FSTST1_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 2 +! #define CC2420_FSTST2_ADDR 0x29 +! typedef struct { +! uint16_t VCO_CURRENT_RES:6; +! uint16_t VCO_CURRENT_O:6; +! uint16_t VCO_CURRENT_OE:1; +! uint16_t VCO_CURCAL_SPEED:2; +! uint16_t reserved_w0:1; +! } cc2420_FSTST2_reg_t; +! +! /// [R/W] Frequency Synthesizer Test Register 3 +! #define CC2420_FSTST3_ADDR 0x2a +! typedef struct { +! uint16_t START_CHP_CURRENT:4; +! uint16_t STOP_CHP_CURRENT:4; +! uint16_t CHP_STEP_PERIOD:2; +! uint16_t PD_DELAY:1; +! uint16_t CHP_DISABLE:1; +! uint16_t CHP_TEST_DN:1; +! uint16_t CHP_TEST_UP:1; +! uint16_t CHP_CURRENT_OE:1; +! uint16_t CHP_CAL_DISABLE:1; +! } cc2420_FSTST3_reg_t; +! +! /// [R/W] Receiver Bandpass Filter Test Register +! #define CC2420_RXBPFTST_ADDR 0x2b +! typedef struct { +! uint16_t RXBPF_CAP_RES:7; +! uint16_t RXBPF_CAP_O:7; +! uint16_t RXBPF_CAP_OE:1; +! uint16_t reserved_w0:1; +! } cc2420_RXBPFTST_reg_t; +! +! /// [R ] Finite State Machine State Status Register +! #define CC2420_FSMSTATE_ADDR 0x2c +! typedef struct { +! uint16_t FSM_CUR_STATE:6; +! uint16_t reserved_w0:10; +! } cc2420_FSMSTATE_reg_t; +! +! /// [R/W] ADC Test Register +! #define CC2420_ADCTST_ADDR 0x2d +! typedef struct { +! uint16_t ADC_Q:7; +! uint16_t reserved_w0:1; +! uint16_t ADC_I:7; +! uint16_t ADC_CLOCK_DISABLE:1; +! } cc2420_ADCTST_reg_t; +! +! /// [R/W] DAC Test Register +! #define CC2420_DACTST_ADDR 0x2e +! typedef struct { +! uint16_t DAC_Q_O:6; +! uint16_t DAC_I_O:6; +! uint16_t DAC_SRC:3; +! uint16_t reserved_w0:1; +! } cc2420_DACTST_reg_t; +! +! /// [R/W] Top Level Test Register +! #define CC2420_TOPTST_ADDR 0x2f +! typedef struct { +! uint16_t ATESTMOD_MODE:4; +! uint16_t ATESTMOD_PD:1; +! uint16_t VC_IN_TEST_EN:1; +! uint16_t TEST_BATTMON_EN:1; +! uint16_t RAM_BIST_RUN:1; +! uint16_t reserved_w0:8; +! } cc2420_TOPTST_reg_t; +! +! //=========================== buffer ========================================== +! +! /// [ W] Transmit FIFO Byte Register +! #define CC2420_TXFIFO_ADDR 0x3e +! +! /// [R/W] Receiver FIFO Byte Register +! #define CC2420_RXFIFO_ADDR 0x3f +! + #endif +\ No newline at end of file +diff -crB openwsn/cross-layers/Makefile ../../../sys/net/openwsn/cross-layers/Makefile +*** openwsn/cross-layers/Makefile Wed Jan 15 13:55:34 2014 +--- ../../../sys/net/openwsn/cross-layers/Makefile Wed Jan 15 13:48:27 2014 +*************** +*** 0 **** +--- 1,32 ---- ++ SUBMOD:=$(shell basename $(CURDIR)).a ++ BINDIR = $(RIOTBASE)/bin/ ++ SRC = $(wildcard *.c) ++ OBJ = $(SRC:%.c=$(BINDIR)%.o) ++ DEP = $(SRC:%.c=$(BINDIR)%.d) ++ ++ INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ ++ INCLUDES += -I$(CURDIR)/02a-MAClow ++ INCLUDES += -I$(CURDIR)/02b-MAChigh ++ INCLUDES += -I$(CURDIR)/03a-IPHC ++ INCLUDES += -I$(CURDIR)/03b-IPv6 ++ INCLUDES += -I$(CURDIR)/04-TRAN ++ INCLUDES += -I$(CURDIR)/cross-layers ++ ++ .PHONY: $(BINDIR)$(SUBMOD) ++ ++ $(BINDIR)$(SUBMOD): $(OBJ) ++ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ ++ # pull in dependency info for *existing* .o files ++ -include $(OBJ:.o=.d) ++ ++ # compile and generate dependency info ++ $(BINDIR)%.o: %.c ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d ++ ++ # remove compilation products ++ ++ clean: ++ rm -f $(OBJ) $(DEP) +diff -crB openwsn/cross-layers/idmanager.c ../../../sys/net/openwsn/cross-layers/idmanager.c +*** openwsn/cross-layers/idmanager.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/idmanager.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,269 **** +! #include "openwsn.h" +! #include "idmanager.h" +! #include "eui64.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "neighbors.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! bool isDAGroot; +! bool isBridge; +! open_addr_t my16bID; +! open_addr_t my64bID; +! open_addr_t myPANID; +! open_addr_t myPrefix; +! } idmanager_vars_t; +! +! idmanager_vars_t idmanager_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void idmanager_init() { +! idmanager_vars.isDAGroot = FALSE; +! idmanager_vars.isBridge = FALSE; +! idmanager_vars.myPANID.type = ADDR_PANID; +! idmanager_vars.myPANID.panid[0] = 0xca; +! idmanager_vars.myPANID.panid[1] = 0xfe; +! idmanager_vars.myPrefix.type = ADDR_PREFIX; +! idmanager_vars.myPrefix.prefix[0] = 0x00; +! idmanager_vars.myPrefix.prefix[1] = 0x00; +! idmanager_vars.myPrefix.prefix[2] = 0x00; +! idmanager_vars.myPrefix.prefix[3] = 0x00; +! idmanager_vars.myPrefix.prefix[4] = 0x00; +! idmanager_vars.myPrefix.prefix[5] = 0x00; +! idmanager_vars.myPrefix.prefix[6] = 0x00; +! idmanager_vars.myPrefix.prefix[7] = 0x00; +! idmanager_vars.my64bID.type = ADDR_64B; +! eui64_get(idmanager_vars.my64bID.addr_64b); +! packetfunctions_mac64bToMac16b(&idmanager_vars.my64bID,&idmanager_vars.my16bID); +! +! // DEBUG_MOTEID_MASTER is DAGroot and bridge +! if (idmanager_vars.my16bID.addr_16b[1]==DEBUG_MOTEID_MASTER) { +! idmanager_vars.isDAGroot = TRUE; +! idmanager_vars.isBridge = TRUE; +! } +! } +! +! bool idmanager_getIsDAGroot() { +! bool res; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! res=idmanager_vars.isDAGroot; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! void idmanager_setIsDAGroot(bool newRole) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! idmanager_vars.isDAGroot = newRole; +! neighbors_updateMyDAGrankAndNeighborPreference(); +! ENABLE_INTERRUPTS(); +! } +! +! bool idmanager_getIsBridge() { +! bool res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! res=idmanager_vars.isBridge; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! void idmanager_setIsBridge(bool newRole) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! idmanager_vars.isBridge = newRole; +! ENABLE_INTERRUPTS(); +! +! } +! +! open_addr_t* idmanager_getMyID(uint8_t type) { +! open_addr_t* res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! switch (type) { +! case ADDR_16B: +! res= &idmanager_vars.my16bID; +! break; +! case ADDR_64B: +! res= &idmanager_vars.my64bID; +! break; +! case ADDR_PANID: +! res= &idmanager_vars.myPANID; +! break; +! case ADDR_PREFIX: +! res= &idmanager_vars.myPrefix; +! break; +! case ADDR_128B: +! // you don't ask for my full address, rather for prefix, then 64b +! default: +! openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)type, +! (errorparameter_t)0); +! res= NULL; +! break; +! } +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! error_t idmanager_setMyID(open_addr_t* newID) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! switch (newID->type) { +! case ADDR_16B: +! memcpy(&idmanager_vars.my16bID,newID,sizeof(open_addr_t)); +! break; +! case ADDR_64B: +! memcpy(&idmanager_vars.my64bID,newID,sizeof(open_addr_t)); +! break; +! case ADDR_PANID: +! memcpy(&idmanager_vars.myPANID,newID,sizeof(open_addr_t)); +! break; +! case ADDR_PREFIX: +! memcpy(&idmanager_vars.myPrefix,newID,sizeof(open_addr_t)); +! break; +! case ADDR_128B: +! //don't set 128b, but rather prefix and 64b +! default: +! openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)newID->type, +! (errorparameter_t)1); +! ENABLE_INTERRUPTS(); +! return E_FAIL; +! } +! ENABLE_INTERRUPTS(); +! return E_SUCCESS; +! } +! +! bool idmanager_isMyAddress(open_addr_t* addr) { +! open_addr_t temp_my128bID; +! bool res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! switch (addr->type) { +! case ADDR_16B: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.my16bID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_64B: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.my64bID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_128B: +! //build temporary my128bID +! temp_my128bID.type = ADDR_128B; +! memcpy(&temp_my128bID.addr_128b[0],&idmanager_vars.myPrefix.prefix,8); +! memcpy(&temp_my128bID.addr_128b[8],&idmanager_vars.my64bID.addr_64b,8); +! +! res= packetfunctions_sameAddress(addr,&temp_my128bID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_PANID: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.myPANID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_PREFIX: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.myPrefix); +! ENABLE_INTERRUPTS(); +! return res; +! default: +! openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)addr->type, +! (errorparameter_t)2); +! ENABLE_INTERRUPTS(); +! return FALSE; +! } +! } +! +! void idmanager_triggerAboutRoot() { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer; +! //get command from OpenSerial +! number_bytes_from_input_buffer = openserial_getInputBuffer(&input_buffer,sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_IDMANAGER,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! //handle command +! switch (input_buffer) { +! case 'Y': +! idmanager_setIsDAGroot(TRUE); +! break; +! case 'N': +! idmanager_setIsDAGroot(FALSE); +! break; +! case 'T': +! if (idmanager_getIsDAGroot()) { +! idmanager_setIsDAGroot(FALSE); +! } else { +! idmanager_setIsDAGroot(TRUE); +! } +! break; +! } +! return; +! } +! +! void idmanager_triggerAboutBridge() { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer[9]; +! //get command from OpenSerial (1B command, 8B prefix) +! number_bytes_from_input_buffer = openserial_getInputBuffer(&input_buffer[0],sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_IDMANAGER,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! //handle command +! switch (input_buffer[0]) { +! case 'Y': +! idmanager_setIsBridge(TRUE); +! memcpy(&(idmanager_vars.myPrefix.prefix),&(input_buffer[1]),8); +! break; +! case 'N': +! idmanager_setIsBridge(FALSE); +! break; +! case 'T': +! if (idmanager_getIsBridge()) { +! idmanager_setIsBridge(FALSE); +! } else { +! idmanager_setIsBridge(TRUE); +! memcpy(&(idmanager_vars.myPrefix.prefix),&(input_buffer[1]),8); +! } +! break; +! } +! return; +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_id() { +! debugIDManagerEntry_t output; +! output.isDAGroot = idmanager_vars.isDAGroot; +! output.isBridge = idmanager_vars.isBridge; +! output.my16bID = idmanager_vars.my16bID; +! output.my64bID = idmanager_vars.my64bID; +! output.myPANID = idmanager_vars.myPANID; +! output.myPrefix = idmanager_vars.myPrefix; +! openserial_printStatus(STATUS_ID,(uint8_t*)&output,sizeof(debugIDManagerEntry_t)); +! return TRUE; +! } +! +! +! //=========================== private ========================================= +--- 1,250 ---- +! #include "openwsn.h" +! #include "idmanager.h" +! #include "eui64.h" +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "neighbors.h" +! +! //=========================== variables ======================================= +! +! idmanager_vars_t idmanager_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void idmanager_init(void) { +! idmanager_vars.isDAGroot = FALSE; +! idmanager_vars.isBridge = FALSE; +! idmanager_vars.myPANID.type = ADDR_PANID; +! idmanager_vars.myPANID.panid[0] = 0xca; +! idmanager_vars.myPANID.panid[1] = 0xfe; +! +! idmanager_vars.myPrefix.type = ADDR_PREFIX; +! memset(&idmanager_vars.myPrefix.prefix[0], 0x00, sizeof(idmanager_vars.myPrefix.prefix)); +! idmanager_vars.my64bID.type = ADDR_64B; +! +! eui64_get(idmanager_vars.my64bID.addr_64b); +! packetfunctions_mac64bToMac16b(&idmanager_vars.my64bID,&idmanager_vars.my16bID); +! +! // if(idmanager_vars.my16bID.addr_16b[1] == 0x0B) +! // idmanager_setIsDAGroot(TRUE); +! } +! +! bool idmanager_getIsDAGroot(void) { +! bool res; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! res=idmanager_vars.isDAGroot; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! void idmanager_setIsDAGroot(bool newRole) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! idmanager_vars.isDAGroot = newRole; +! neighbors_updateMyDAGrankAndNeighborPreference(); +! ENABLE_INTERRUPTS(); +! } +! +! bool idmanager_getIsBridge(void) { +! bool res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! res=idmanager_vars.isBridge; +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! void idmanager_setIsBridge(bool newRole) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! idmanager_vars.isBridge = newRole; +! ENABLE_INTERRUPTS(); +! +! } +! +! open_addr_t* idmanager_getMyID(uint8_t type) { +! open_addr_t* res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! switch (type) { +! case ADDR_16B: +! res= &idmanager_vars.my16bID; +! break; +! case ADDR_64B: +! res= &idmanager_vars.my64bID; +! break; +! case ADDR_PANID: +! res= &idmanager_vars.myPANID; +! break; +! case ADDR_PREFIX: +! res= &idmanager_vars.myPrefix; +! break; +! case ADDR_128B: +! // you don't ask for my full address, rather for prefix, then 64b +! default: +! openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)type, +! (errorparameter_t)0); +! res= NULL; +! break; +! } +! ENABLE_INTERRUPTS(); +! return res; +! } +! +! owerror_t idmanager_setMyID(open_addr_t* newID) { +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! switch (newID->type) { +! case ADDR_16B: +! memcpy(&idmanager_vars.my16bID,newID,sizeof(open_addr_t)); +! break; +! case ADDR_64B: +! memcpy(&idmanager_vars.my64bID,newID,sizeof(open_addr_t)); +! break; +! case ADDR_PANID: +! memcpy(&idmanager_vars.myPANID,newID,sizeof(open_addr_t)); +! break; +! case ADDR_PREFIX: +! memcpy(&idmanager_vars.myPrefix,newID,sizeof(open_addr_t)); +! break; +! case ADDR_128B: +! //don't set 128b, but rather prefix and 64b +! default: +! openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)newID->type, +! (errorparameter_t)1); +! ENABLE_INTERRUPTS(); +! return E_FAIL; +! } +! ENABLE_INTERRUPTS(); +! return E_SUCCESS; +! } +! +! bool idmanager_isMyAddress(open_addr_t* addr) { +! open_addr_t temp_my128bID; +! bool res; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! +! switch (addr->type) { +! case ADDR_16B: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.my16bID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_64B: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.my64bID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_128B: +! //build temporary my128bID +! temp_my128bID.type = ADDR_128B; +! memcpy(&temp_my128bID.addr_128b[0],&idmanager_vars.myPrefix.prefix,8); +! memcpy(&temp_my128bID.addr_128b[8],&idmanager_vars.my64bID.addr_64b,8); +! +! res= packetfunctions_sameAddress(addr,&temp_my128bID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_PANID: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.myPANID); +! ENABLE_INTERRUPTS(); +! return res; +! case ADDR_PREFIX: +! res= packetfunctions_sameAddress(addr,&idmanager_vars.myPrefix); +! ENABLE_INTERRUPTS(); +! return res; +! default: +! openserial_printCritical(COMPONENT_IDMANAGER,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)addr->type, +! (errorparameter_t)2); +! ENABLE_INTERRUPTS(); +! return FALSE; +! } +! } +! +! void idmanager_triggerAboutRoot(void) { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer; +! // get command from OpenSerial +! number_bytes_from_input_buffer = openserial_getInputBuffer(&input_buffer,sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_IDMANAGER,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)0); +! return; +! }; +! // handle command +! switch (input_buffer) { +! case ACTION_YES: +! idmanager_setIsDAGroot(TRUE); +! break; +! case ACTION_NO: +! idmanager_setIsDAGroot(FALSE); +! break; +! case ACTION_TOGGLE: +! if (idmanager_getIsDAGroot()) { +! idmanager_setIsDAGroot(FALSE); +! } else { +! idmanager_setIsDAGroot(TRUE); +! } +! break; +! } +! return; +! } +! +! void idmanager_triggerAboutBridge(void) { +! uint8_t number_bytes_from_input_buffer; +! uint8_t input_buffer; +! //get command from OpenSerial +! number_bytes_from_input_buffer = openserial_getInputBuffer(&input_buffer,sizeof(input_buffer)); +! if (number_bytes_from_input_buffer!=sizeof(input_buffer)) { +! openserial_printError(COMPONENT_IDMANAGER,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)number_bytes_from_input_buffer, +! (errorparameter_t)1); +! return; +! }; +! //handle command +! switch (input_buffer) { +! case ACTION_YES: +! idmanager_setIsBridge(TRUE); +! break; +! case ACTION_NO: +! idmanager_setIsBridge(FALSE); +! break; +! case ACTION_TOGGLE: +! if (idmanager_getIsBridge()) { +! idmanager_setIsBridge(FALSE); +! } else { +! idmanager_setIsBridge(TRUE); +! } +! break; +! } +! return; +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_id(void) { +! debugIDManagerEntry_t output; +! output.isDAGroot = idmanager_vars.isDAGroot; +! output.isBridge = idmanager_vars.isBridge; +! output.my16bID = idmanager_vars.my16bID; +! output.my64bID = idmanager_vars.my64bID; +! output.myPANID = idmanager_vars.myPANID; +! output.myPrefix = idmanager_vars.myPrefix; +! openserial_printStatus(STATUS_ID,(uint8_t*)&output,sizeof(debugIDManagerEntry_t)); +! return TRUE; +! } +! +! +! //=========================== private ========================================= +diff -crB openwsn/cross-layers/idmanager.h ../../../sys/net/openwsn/cross-layers/idmanager.h +*** openwsn/cross-layers/idmanager.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/idmanager.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,49 **** +! #ifndef __IDMANAGER_H +! #define __IDMANAGER_H +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup IDManager +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef struct { +! bool isDAGroot; +! bool isBridge; +! open_addr_t my16bID; +! open_addr_t my64bID; +! open_addr_t myPANID; +! open_addr_t myPrefix; +! } debugIDManagerEntry_t; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void idmanager_init(); +! bool idmanager_getIsDAGroot(); +! void idmanager_setIsDAGroot(bool newRole); +! bool idmanager_getIsBridge(); +! void idmanager_setIsBridge(bool newRole); +! open_addr_t* idmanager_getMyID(uint8_t type); +! error_t idmanager_setMyID(open_addr_t* newID); +! bool idmanager_isMyAddress(open_addr_t* addr); +! void idmanager_triggerAboutRoot(); +! void idmanager_triggerAboutBridge(); +! +! bool debugPrint_id(); +! +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,62 ---- +! #ifndef __IDMANAGER_H +! #define __IDMANAGER_H +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup IDManager +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! #define ACTION_YES 'Y' +! #define ACTION_NO 'N' +! #define ACTION_TOGGLE 'T' +! +! //=========================== typedef ========================================= +! +! typedef struct { +! bool isDAGroot; +! bool isBridge; +! open_addr_t my16bID; +! open_addr_t my64bID; +! open_addr_t myPANID; +! open_addr_t myPrefix; +! } debugIDManagerEntry_t; +! +! //=========================== module variables ================================ +! +! typedef struct { +! bool isDAGroot; +! bool isBridge; +! open_addr_t my16bID; +! open_addr_t my64bID; +! open_addr_t myPANID; +! open_addr_t myPrefix; +! } idmanager_vars_t; +! +! //=========================== prototypes ====================================== +! +! void idmanager_init(void); +! bool idmanager_getIsDAGroot(void); +! void idmanager_setIsDAGroot(bool newRole); +! bool idmanager_getIsBridge(void); +! void idmanager_setIsBridge(bool newRole); +! open_addr_t* idmanager_getMyID(uint8_t type); +! owerror_t idmanager_setMyID(open_addr_t* newID); +! bool idmanager_isMyAddress(open_addr_t* addr); +! void idmanager_triggerAboutRoot(void); +! void idmanager_triggerAboutBridge(void); +! +! bool debugPrint_id(void); +! +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/cross-layers/openqueue.c ../../../sys/net/openwsn/cross-layers/openqueue.c +*** openwsn/cross-layers/openqueue.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/openqueue.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,261 **** +! #include "openwsn.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "IEEE802154E.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! OpenQueueEntry_t queue[QUEUELENGTH]; +! } openqueue_vars_t; +! +! openqueue_vars_t openqueue_vars; +! +! //=========================== prototypes ====================================== +! +! void openqueue_reset_entry(OpenQueueEntry_t* entry); +! +! //=========================== public ========================================== +! +! //======= admin +! +! /** +! \brief Initialize this module. +! */ +! void openqueue_init() { +! uint8_t i; +! for (i=0;i COMPONENT_IEEE802154E){ +! ENABLE_INTERRUPTS(); +! return NULL; +! } +! +! // if you get here, I will try to allocate a buffer for you +! +! // walk through queue and find free entry +! for (i=0;itype==ADDR_64B) { +! // a neighbor is specified, look for a packet unicast to that neigbhbor +! for (i=0;itype==ADDR_ANYCAST) { +! // anycast case: look for a packet which is either not created by RES +! // or an KA (created by RES, but not broadcast) +! for (i=0;icreator = COMPONENT_NULL; +! entry->owner = COMPONENT_NULL; +! entry->payload = &(entry->packet[127]); +! entry->length = 0; +! //l4 +! entry->l4_protocol = IANA_UNDEFINED; +! //l3 +! entry->l3_destinationAdd.type = ADDR_NONE; +! entry->l3_sourceAdd.type = ADDR_NONE; +! //l2 +! entry->l2_nextORpreviousHop.type = ADDR_NONE; +! entry->l2_frameType = IEEE154_TYPE_UNDEFINED; +! entry->l2_retriesLeft = 0; +! } +--- 1,257 ---- +! #include "openwsn.h" +! #include "openqueue.h" +! #include "openserial.h" +! #include "packetfunctions.h" +! #include "IEEE802154E.h" +! +! //=========================== variables ======================================= +! +! openqueue_vars_t openqueue_vars; +! +! //=========================== prototypes ====================================== +! +! void openqueue_reset_entry(OpenQueueEntry_t* entry); +! +! //=========================== public ========================================== +! +! //======= admin +! +! /** +! \brief Initialize this module. +! */ +! void openqueue_init(void) { +! uint8_t i; +! for (i=0;i COMPONENT_IEEE802154E){ +! ENABLE_INTERRUPTS(); +! return NULL; +! } +! +! // if you get here, I will try to allocate a buffer for you +! +! // walk through queue and find free entry +! for (i=0;itype==ADDR_64B) { +! // a neighbor is specified, look for a packet unicast to that neigbhbor +! for (i=0;itype==ADDR_ANYCAST) { +! // anycast case: look for a packet which is either not created by RES +! // or an KA (created by RES, but not broadcast) +! for (i=0;icreator = COMPONENT_NULL; +! entry->owner = COMPONENT_NULL; +! entry->payload = &(entry->packet[127]); +! entry->length = 0; +! //l4 +! entry->l4_protocol = IANA_UNDEFINED; +! //l3 +! entry->l3_destinationAdd.type = ADDR_NONE; +! entry->l3_sourceAdd.type = ADDR_NONE; +! //l2 +! entry->l2_nextORpreviousHop.type = ADDR_NONE; +! entry->l2_frameType = IEEE154_TYPE_UNDEFINED; +! entry->l2_retriesLeft = 0; +! } +diff -crB openwsn/cross-layers/openqueue.h ../../../sys/net/openwsn/cross-layers/openqueue.h +*** openwsn/cross-layers/openqueue.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/openqueue.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,49 **** +! #ifndef __OPENQUEUE_H +! #define __OPENQUEUE_H +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup OpenQueue +! \{ +! */ +! +! #include "openwsn.h" +! #include "IEEE802154.h" +! +! //=========================== define ========================================== +! +! #define QUEUELENGTH 10 +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t creator; +! uint8_t owner; +! } debugOpenQueueEntry_t; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void openqueue_init(); +! bool debugPrint_queue(); +! // called by any component +! OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator); +! error_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt); +! void openqueue_removeAllCreatedBy(uint8_t creator); +! void openqueue_removeAllOwnedBy(uint8_t owner); +! // called by res +! OpenQueueEntry_t* openqueue_resGetSentPacket(); +! OpenQueueEntry_t* openqueue_resGetReceivedPacket(); +! // called by IEEE80215E +! OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor); +! OpenQueueEntry_t* openqueue_macGetAdvPacket(); +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,53 ---- +! #ifndef __OPENQUEUE_H +! #define __OPENQUEUE_H +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup OpenQueue +! \{ +! */ +! +! #include "openwsn.h" +! #include "IEEE802154.h" +! +! //=========================== define ========================================== +! +! #define QUEUELENGTH 10 +! +! //=========================== typedef ========================================= +! +! typedef struct { +! uint8_t creator; +! uint8_t owner; +! } debugOpenQueueEntry_t; +! +! //=========================== module variables ================================ +! +! typedef struct { +! OpenQueueEntry_t queue[QUEUELENGTH]; +! } openqueue_vars_t; +! +! //=========================== prototypes ====================================== +! +! // admin +! void openqueue_init(void); +! bool debugPrint_queue(void); +! // called by any component +! OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator); +! owerror_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt); +! void openqueue_removeAllCreatedBy(uint8_t creator); +! void openqueue_removeAllOwnedBy(uint8_t owner); +! // called by res +! OpenQueueEntry_t* openqueue_resGetSentPacket(void); +! OpenQueueEntry_t* openqueue_resGetReceivedPacket(void); +! // called by IEEE80215E +! OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor); +! OpenQueueEntry_t* openqueue_macGetAdvPacket(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/cross-layers/openrandom.c ../../../sys/net/openwsn/cross-layers/openrandom.c +*** openwsn/cross-layers/openrandom.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/openrandom.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,38 **** +! #include "openwsn.h" +! #include "openrandom.h" +! #include "idmanager.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! uint16_t shift_reg; // Galois shift register used to obtain a pseudo-random number +! } random_vars_t; +! +! random_vars_t random_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void openrandom_init() { +! // seed the random number generator with the last 2 bytes of the MAC address +! random_vars.shift_reg = 0; +! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[0]*256; +! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[1]; +! } +! +! uint16_t openrandom_get16b() { +! uint8_t i; +! uint16_t random_value; +! random_value = 0; +! for(i=0;i<16;i++) { +! // Galois shift register +! // taps: 16 14 13 11 +! // characteristic polynomial: x^16 + x^14 + x^13 + x^11 + 1 +! random_value |= (random_vars.shift_reg & 0x01)<>1)^(-(int16_t)(random_vars.shift_reg & 1)&0xb400); +! } +! return random_value; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,34 ---- +! #include "openwsn.h" +! #include "openrandom.h" +! #include "idmanager.h" +! +! //=========================== variables ======================================= +! +! random_vars_t random_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void openrandom_init(void) { +! // seed the random number generator with the last 2 bytes of the MAC address +! random_vars.shift_reg = 0; +! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[0]*256; +! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[1]; +! } +! +! uint16_t openrandom_get16b(void) { +! uint8_t i; +! uint16_t random_value; +! random_value = 0; +! for(i=0;i<16;i++) { +! // Galois shift register +! // taps: 16 14 13 11 +! // characteristic polynomial: x^16 + x^14 + x^13 + x^11 + 1 +! random_value |= (random_vars.shift_reg & 0x01)<>1)^(-(int16_t)(random_vars.shift_reg & 1)&0xb400); +! } +! return random_value; +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/cross-layers/openrandom.h ../../../sys/net/openwsn/cross-layers/openrandom.h +*** openwsn/cross-layers/openrandom.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/openrandom.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,29 **** +! #ifndef __OPENRANDOM_H +! #define __OPENRANDOM_H +! +! /** +! \addtogroup helpers +! \{ +! \addtogroup Random +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openrandom_init(); +! uint16_t openrandom_get16b(); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,33 ---- +! #ifndef __OPENRANDOM_H +! #define __OPENRANDOM_H +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup OpenRandom +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== module variables ================================ +! +! typedef struct { +! uint16_t shift_reg; // Galois shift register used to obtain a pseudo-random number +! } random_vars_t; +! +! //=========================== prototypes ====================================== +! +! void openrandom_init(void); +! uint16_t openrandom_get16b(void); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/cross-layers/packetfunctions.c ../../../sys/net/openwsn/cross-layers/packetfunctions.c +*** openwsn/cross-layers/packetfunctions.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/packetfunctions.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,447 **** +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length); +! +! //=========================== public ========================================== +! +! //======= address translation +! +! //assuming an ip128b is a concatenation of prefix64b followed by a mac64b +! void packetfunctions_ip128bToMac64b( +! open_addr_t* ip128b, +! open_addr_t* prefix64btoWrite, +! open_addr_t* mac64btoWrite) { +! if (ip128b->type!=ADDR_128B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)ip128b->type, +! (errorparameter_t)0); +! mac64btoWrite->type=ADDR_NONE; +! return; +! } +! prefix64btoWrite->type=ADDR_PREFIX; +! memcpy(prefix64btoWrite->prefix, &(ip128b->addr_128b[0]), 8); +! mac64btoWrite->type=ADDR_64B; +! memcpy(mac64btoWrite->addr_64b , &(ip128b->addr_128b[8]), 8); +! } +! void packetfunctions_mac64bToIp128b( +! open_addr_t* prefix64b, +! open_addr_t* mac64b, +! open_addr_t* ip128bToWrite) { +! if (prefix64b->type!=ADDR_PREFIX || mac64b->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)prefix64b->type, +! (errorparameter_t)1); +! ip128bToWrite->type=ADDR_NONE; +! return; +! } +! ip128bToWrite->type=ADDR_128B; +! memcpy(&(ip128bToWrite->addr_128b[0]), &(prefix64b->prefix[0]), 8); +! memcpy(&(ip128bToWrite->addr_128b[8]), &(mac64b->addr_64b[0]), 8); +! } +! +! //assuming an mac16b is lower 2B of mac64b +! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite) { +! if (mac64b->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)mac64b->type, +! (errorparameter_t)2); +! mac16btoWrite->type=ADDR_NONE; +! return; +! } +! mac16btoWrite->type = ADDR_16B; +! mac16btoWrite->addr_16b[0] = mac64b->addr_64b[6]; +! mac16btoWrite->addr_16b[1] = mac64b->addr_64b[7]; +! } +! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite) { +! if (mac16b->type!=ADDR_16B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)mac16b->type, +! (errorparameter_t)3); +! mac64btoWrite->type=ADDR_NONE; +! return; +! } +! mac64btoWrite->type = ADDR_64B; +! mac64btoWrite->addr_64b[0] = 0; +! mac64btoWrite->addr_64b[1] = 0; +! mac64btoWrite->addr_64b[2] = 0; +! mac64btoWrite->addr_64b[3] = 0; +! mac64btoWrite->addr_64b[4] = 0; +! mac64btoWrite->addr_64b[5] = 0; +! mac64btoWrite->addr_64b[6] = mac16b->addr_16b[0]; +! mac64btoWrite->addr_64b[7] = mac16b->addr_16b[1]; +! } +! +! //======= address recognition +! +! bool packetfunctions_isBroadcastMulticast(open_addr_t* address) { +! uint8_t i; +! uint8_t address_length; +! //IPv6 multicast +! if (address->type==ADDR_128B) { +! if (address->addr_128b[0]==0xff) { +! return TRUE; +! } else { +! return FALSE; +! } +! } +! //15.4 broadcast +! switch (address->type) { +! case ADDR_16B: +! address_length = 2; +! break; +! case ADDR_64B: +! address_length = 8; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)4); +! return FALSE; +! } +! for (i=0;iaddr_128b[i]!=0xFF) { +! return FALSE; +! } +! } +! return TRUE; +! } +! +! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address) { +! if ( +! address->type == ADDR_128B && +! address->addr_128b[0] == 0xff && +! address->addr_128b[1] == 0x02 && +! address->addr_128b[2] == 0x00 && +! address->addr_128b[3] == 0x00 && +! address->addr_128b[4] == 0x00 && +! address->addr_128b[5] == 0x00 && +! address->addr_128b[6] == 0x00 && +! address->addr_128b[7] == 0x00 && +! address->addr_128b[8] == 0x00 && +! address->addr_128b[9] == 0x00 && +! address->addr_128b[10] == 0x00 && +! address->addr_128b[11] == 0x00 && +! address->addr_128b[12] == 0x00 && +! address->addr_128b[13] == 0x00 && +! address->addr_128b[14] == 0x00 && +! address->addr_128b[15] == 0x02 +! ) { +! return TRUE; +! } +! return FALSE; +! } +! +! bool packetfunctions_isAllHostsMulticast(open_addr_t* address) { +! if ( +! address->type == ADDR_128B && +! address->addr_128b[0] == 0xff && +! address->addr_128b[1] == 0x02 && +! address->addr_128b[2] == 0x00 && +! address->addr_128b[3] == 0x00 && +! address->addr_128b[4] == 0x00 && +! address->addr_128b[5] == 0x00 && +! address->addr_128b[6] == 0x00 && +! address->addr_128b[7] == 0x00 && +! address->addr_128b[8] == 0x00 && +! address->addr_128b[9] == 0x00 && +! address->addr_128b[10] == 0x00 && +! address->addr_128b[11] == 0x00 && +! address->addr_128b[12] == 0x00 && +! address->addr_128b[13] == 0x00 && +! address->addr_128b[14] == 0x00 && +! address->addr_128b[15] == 0x01 +! ) { +! return TRUE; +! } +! return FALSE; +! } +! +! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2) { +! uint8_t address_length; +! +! if (address_1->type!=address_2->type) { +! return FALSE; +! } +! switch (address_1->type) { +! case ADDR_16B: +! case ADDR_PANID: +! address_length = 2; +! break; +! case ADDR_64B: +! case ADDR_PREFIX: +! address_length = 8; +! break; +! case ADDR_128B: +! address_length = 16; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address_1->type, +! (errorparameter_t)5); +! return FALSE; +! } +! if (memcmp((void*)address_1->addr_128b,(void*)address_2->addr_128b,address_length)==0) { +! return TRUE; +! } +! return FALSE; +! } +! +! //======= address read/write +! +! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian) { +! uint8_t i; +! uint8_t address_length; +! +! writeToAddress->type = type; +! switch (type) { +! case ADDR_16B: +! case ADDR_PANID: +! address_length = 2; +! break; +! case ADDR_64B: +! case ADDR_PREFIX: +! address_length = 8; +! break; +! case ADDR_128B: +! address_length = 16; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)type, +! (errorparameter_t)6); +! return; +! } +! +! for (i=0;iaddr_128b[address_length-1-i] = *(payload+i); +! } else { +! writeToAddress->addr_128b[i] = *(payload+i); +! } +! } +! } +! +! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian) { +! uint8_t i; +! uint8_t address_length; +! +! switch (address->type) { +! case ADDR_16B: +! case ADDR_PANID: +! address_length = 2; +! break; +! case ADDR_64B: +! case ADDR_PREFIX: +! address_length = 8; +! break; +! case ADDR_128B: +! address_length = 16; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)7); +! return; +! } +! +! for (i=0;ipayload -= sizeof(uint8_t); +! msg->length += sizeof(uint8_t); +! if (littleEndian) { +! *((uint8_t*)(msg->payload)) = address->addr_128b[i]; +! } else { +! *((uint8_t*)(msg->payload)) = address->addr_128b[address_length-1-i]; +! } +! } +! } +! +! //======= reserving/tossing headers +! +! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->payload -= header_length; +! pkt->length += header_length; +! if ( (uint8_t*)(pkt->payload) < (uint8_t*)(pkt->packet) ) { +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)0, +! (errorparameter_t)pkt->length); +! } +! } +! +! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->payload += header_length; +! pkt->length -= header_length; +! if ( (uint8_t*)(pkt->payload) > (uint8_t*)(pkt->packet+126) ) { +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)1, +! (errorparameter_t)pkt->length); +! } +! } +! +! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->length += header_length; +! if (pkt->length>127) { +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)2, +! (errorparameter_t)pkt->length); +! } +! } +! +! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->length -= header_length; +! if (pkt->length>128) {//wraps around, so a negative value will be >128 +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)3, +! (errorparameter_t)pkt->length); +! } +! } +! +! //======= CRC calculation +! +! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg) { +! uint16_t crc; +! uint8_t i; +! uint8_t count; +! crc = 0; +! for (count=1;countlength-2;count++) { +! crc = crc ^ (uint8_t)*(msg->payload+count); +! //crc = crc ^ (uint16_t)*ptr++ << 8; +! for (i=0;i<8;i++) { +! if (crc & 0x1) { +! crc = crc >> 1 ^ 0x8408; +! } else { +! crc = crc >> 1; +! } +! } +! } +! *(msg->payload+(msg->length-2)) = crc%256; +! *(msg->payload+(msg->length-1)) = crc/256; +! } +! +! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg) { +! uint16_t crc; +! uint8_t i; +! uint8_t count; +! crc = 0; +! for (count=0;countlength-2;count++) { +! crc = crc ^ (uint8_t)*(msg->payload+count); +! //crc = crc ^ (uint16_t)*ptr++ << 8; +! for (i=0;i<8;i++) { +! if (crc & 0x1) { +! crc = crc >> 1 ^ 0x8408; +! } else { +! crc = crc >> 1; +! } +! } +! } +! if (*(msg->payload+(msg->length-2))==crc%256 && +! *(msg->payload+(msg->length-1))==crc/256) { +! return TRUE; +! } else { +! return FALSE; +! } +! } +! +! //======= checksum calculation +! +! //see http://www-net.cs.umass.edu/kurose/transport/UDP.html, or http://tools.ietf.org/html/rfc1071 +! //see http://en.wikipedia.org/wiki/User_Datagram_Protocol#IPv6_PSEUDO-HEADER +! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr) { +! open_addr_t temp_dest_prefix; +! open_addr_t temp_dest_mac64b; +! uint8_t temp_checksum[2]; +! uint8_t little_helper[2]; +! //initialization +! temp_checksum[0] = 0; +! temp_checksum[1] = 0; +! *checksum_ptr = 0; +! *(checksum_ptr+1) = 0; +! //source/destination address +! packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); +! if (packetfunctions_sameAddress(&temp_dest_prefix,idmanager_getMyID(ADDR_PREFIX))) { +! little_helper[0] = 0xfe; +! little_helper[1] = 0x80; +! //source address prefix +! onesComplementSum(temp_checksum,little_helper,2); +! //source address EUI +! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_64B))->addr_64b,8); +! //destination address prefix (fe:80) +! onesComplementSum(temp_checksum,little_helper,2); +! //destination address EUI +! onesComplementSum(temp_checksum,temp_dest_mac64b.addr_64b,8); +! } else { +! //source address prefix +! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_PREFIX))->prefix,8); +! //source address EUI +! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_64B))->addr_64b,8); +! //destination address +! onesComplementSum(temp_checksum,msg->l3_destinationAdd.addr_128b,16); +! } +! //length +! little_helper[0] = 0; +! little_helper[1] = msg->length; +! onesComplementSum(temp_checksum,little_helper,2); +! //next header +! little_helper[0] = 0; +! little_helper[1] = msg->l4_protocol; +! onesComplementSum(temp_checksum,little_helper,2); +! //ICMPv6 packet +! onesComplementSum(temp_checksum,msg->payload,msg->length); +! temp_checksum[0] ^= 0xFF; +! temp_checksum[1] ^= 0xFF; +! //write in packet +! *checksum_ptr = temp_checksum[0]; +! *(checksum_ptr+1) = temp_checksum[1]; +! } +! +! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length) { +! uint32_t sum = 0xFFFF & (global_sum[0]<<8 | global_sum[1]); +! while (length>1) { +! sum += 0xFFFF & (*ptr<<8 | *(ptr+1)); +! ptr += 2; +! length -= 2; +! } +! if (length) { +! sum += (0xFF & *ptr)<<8; +! } +! while (sum>>16) { +! sum = (sum & 0xFFFF)+(sum >> 16); +! } +! global_sum[0] = (sum>>8) & 0xFF; +! global_sum[1] = sum & 0xFF; +! } +! +! //======= endianness +! +! void packetfunctions_htons( uint16_t val, uint8_t* dest ) { +! dest[0] = (val & 0xff00) >> 8; +! dest[1] = (val & 0x00ff); +! } +! +! uint16_t packetfunctions_ntohs( uint8_t* src ) { +! return (((uint16_t) src[0]) << 8) | +! (((uint16_t) src[1]) +! ); +! } +! +! void packetfunctions_htonl( uint32_t val, uint8_t* dest ) { +! dest[0] = (val & 0xff000000) >> 24; +! dest[1] = (val & 0x00ff0000) >> 16; +! dest[2] = (val & 0x0000ff00) >> 8; +! dest[3] = (val & 0x000000ff); +! } +! +! uint32_t packetfunctions_ntohl( uint8_t* src ) { +! return (((uint32_t) src[0]) << 24) | +! (((uint32_t) src[1]) << 16) | +! (((uint32_t) src[2]) << 8) | +! (((uint32_t) src[3]) +! ); +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,444 ---- +! #include "packetfunctions.h" +! #include "openserial.h" +! #include "idmanager.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length); +! +! //=========================== public ========================================== +! +! //======= address translation +! +! //assuming an ip128b is a concatenation of prefix64b followed by a mac64b +! void packetfunctions_ip128bToMac64b( +! open_addr_t* ip128b, +! open_addr_t* prefix64btoWrite, +! open_addr_t* mac64btoWrite) { +! if (ip128b->type!=ADDR_128B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)ip128b->type, +! (errorparameter_t)0); +! mac64btoWrite->type=ADDR_NONE; +! return; +! } +! prefix64btoWrite->type=ADDR_PREFIX; +! memcpy(prefix64btoWrite->prefix, &(ip128b->addr_128b[0]), 8); +! mac64btoWrite->type=ADDR_64B; +! memcpy(mac64btoWrite->addr_64b , &(ip128b->addr_128b[8]), 8); +! } +! void packetfunctions_mac64bToIp128b( +! open_addr_t* prefix64b, +! open_addr_t* mac64b, +! open_addr_t* ip128bToWrite) { +! if (prefix64b->type!=ADDR_PREFIX || mac64b->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)prefix64b->type, +! (errorparameter_t)1); +! ip128bToWrite->type=ADDR_NONE; +! return; +! } +! ip128bToWrite->type=ADDR_128B; +! memcpy(&(ip128bToWrite->addr_128b[0]), &(prefix64b->prefix[0]), 8); +! memcpy(&(ip128bToWrite->addr_128b[8]), &(mac64b->addr_64b[0]), 8); +! } +! +! //assuming an mac16b is lower 2B of mac64b +! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite) { +! if (mac64b->type!=ADDR_64B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)mac64b->type, +! (errorparameter_t)2); +! mac16btoWrite->type=ADDR_NONE; +! return; +! } +! mac16btoWrite->type = ADDR_16B; +! mac16btoWrite->addr_16b[0] = mac64b->addr_64b[6]; +! mac16btoWrite->addr_16b[1] = mac64b->addr_64b[7]; +! } +! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite) { +! if (mac16b->type!=ADDR_16B) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)mac16b->type, +! (errorparameter_t)3); +! mac64btoWrite->type=ADDR_NONE; +! return; +! } +! mac64btoWrite->type = ADDR_64B; +! mac64btoWrite->addr_64b[0] = 0; +! mac64btoWrite->addr_64b[1] = 0; +! mac64btoWrite->addr_64b[2] = 0; +! mac64btoWrite->addr_64b[3] = 0; +! mac64btoWrite->addr_64b[4] = 0; +! mac64btoWrite->addr_64b[5] = 0; +! mac64btoWrite->addr_64b[6] = mac16b->addr_16b[0]; +! mac64btoWrite->addr_64b[7] = mac16b->addr_16b[1]; +! } +! +! //======= address recognition +! +! bool packetfunctions_isBroadcastMulticast(open_addr_t* address) { +! uint8_t i; +! uint8_t address_length; +! //IPv6 multicast +! if (address->type==ADDR_128B) { +! if (address->addr_128b[0]==0xff) { +! return TRUE; +! } else { +! return FALSE; +! } +! } +! //15.4 broadcast +! switch (address->type) { +! case ADDR_16B: +! address_length = 2; +! break; +! case ADDR_64B: +! address_length = 8; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)4); +! return FALSE; +! } +! for (i=0;iaddr_128b[i]!=0xFF) { +! return FALSE; +! } +! } +! return TRUE; +! } +! +! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address) { +! if ( +! address->type == ADDR_128B && +! address->addr_128b[0] == 0xff && +! address->addr_128b[1] == 0x02 && +! address->addr_128b[2] == 0x00 && +! address->addr_128b[3] == 0x00 && +! address->addr_128b[4] == 0x00 && +! address->addr_128b[5] == 0x00 && +! address->addr_128b[6] == 0x00 && +! address->addr_128b[7] == 0x00 && +! address->addr_128b[8] == 0x00 && +! address->addr_128b[9] == 0x00 && +! address->addr_128b[10] == 0x00 && +! address->addr_128b[11] == 0x00 && +! address->addr_128b[12] == 0x00 && +! address->addr_128b[13] == 0x00 && +! address->addr_128b[14] == 0x00 && +! address->addr_128b[15] == 0x02 +! ) { +! return TRUE; +! } +! return FALSE; +! } +! +! bool packetfunctions_isAllHostsMulticast(open_addr_t* address) { +! if ( +! address->type == ADDR_128B && +! address->addr_128b[0] == 0xff && +! address->addr_128b[1] == 0x02 && +! address->addr_128b[2] == 0x00 && +! address->addr_128b[3] == 0x00 && +! address->addr_128b[4] == 0x00 && +! address->addr_128b[5] == 0x00 && +! address->addr_128b[6] == 0x00 && +! address->addr_128b[7] == 0x00 && +! address->addr_128b[8] == 0x00 && +! address->addr_128b[9] == 0x00 && +! address->addr_128b[10] == 0x00 && +! address->addr_128b[11] == 0x00 && +! address->addr_128b[12] == 0x00 && +! address->addr_128b[13] == 0x00 && +! address->addr_128b[14] == 0x00 && +! address->addr_128b[15] == 0x01 +! ) { +! return TRUE; +! } +! return FALSE; +! } +! +! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2) { +! uint8_t address_length; +! +! if (address_1->type!=address_2->type) { +! return FALSE; +! } +! switch (address_1->type) { +! case ADDR_16B: +! case ADDR_PANID: +! address_length = 2; +! break; +! case ADDR_64B: +! case ADDR_PREFIX: +! address_length = 8; +! break; +! case ADDR_128B: +! case ADDR_ANYCAST: +! address_length = 16; +! break; +! +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address_1->type, +! (errorparameter_t)5); +! return FALSE; +! } +! if (memcmp((void*)address_1->addr_128b,(void*)address_2->addr_128b,address_length)==0) { +! return TRUE; +! } +! return FALSE; +! } +! +! //======= address read/write +! +! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian) { +! uint8_t i; +! uint8_t address_length; +! +! writeToAddress->type = type; +! switch (type) { +! case ADDR_16B: +! case ADDR_PANID: +! address_length = 2; +! break; +! case ADDR_64B: +! case ADDR_PREFIX: +! address_length = 8; +! break; +! case ADDR_128B: +! address_length = 16; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)type, +! (errorparameter_t)6); +! return; +! } +! +! for (i=0;iaddr_128b[address_length-1-i] = *(payload+i); +! } else { +! writeToAddress->addr_128b[i] = *(payload+i); +! } +! } +! } +! +! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian) { +! uint8_t i; +! uint8_t address_length; +! +! switch (address->type) { +! case ADDR_16B: +! case ADDR_PANID: +! address_length = 2; +! break; +! case ADDR_64B: +! case ADDR_PREFIX: +! address_length = 8; +! break; +! case ADDR_128B: +! address_length = 16; +! break; +! default: +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, +! (errorparameter_t)address->type, +! (errorparameter_t)7); +! return; +! } +! +! for (i=0;ipayload -= sizeof(uint8_t); +! msg->length += sizeof(uint8_t); +! if (littleEndian) { +! *((uint8_t*)(msg->payload)) = address->addr_128b[i]; +! } else { +! *((uint8_t*)(msg->payload)) = address->addr_128b[address_length-1-i]; +! } +! } +! } +! +! //======= reserving/tossing headers +! +! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->payload -= header_length; +! pkt->length += header_length; +! if ( (uint8_t*)(pkt->payload) < (uint8_t*)(pkt->packet) ) { +! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)0, +! (errorparameter_t)pkt->length); +! } +! } +! +! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->payload += header_length; +! pkt->length -= header_length; +! if ( (uint8_t*)(pkt->payload) > (uint8_t*)(pkt->packet+126) ) { +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)1, +! (errorparameter_t)pkt->length); +! } +! } +! +! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->length += header_length; +! if (pkt->length>127) { +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)2, +! (errorparameter_t)pkt->length); +! } +! } +! +! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length) { +! pkt->length -= header_length; +! if (pkt->length>128) {//wraps around, so a negative value will be >128 +! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, +! (errorparameter_t)3, +! (errorparameter_t)pkt->length); +! } +! } +! +! //======= CRC calculation +! +! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg) { +! uint16_t crc; +! uint8_t i; +! uint8_t count; +! crc = 0; +! for (count=1;countlength-2;count++) { +! crc = crc ^ (uint8_t)*(msg->payload+count); +! //crc = crc ^ (uint16_t)*ptr++ << 8; +! for (i=0;i<8;i++) { +! if (crc & 0x1) { +! crc = crc >> 1 ^ 0x8408; +! } else { +! crc = crc >> 1; +! } +! } +! } +! *(msg->payload+(msg->length-2)) = crc%256; +! *(msg->payload+(msg->length-1)) = crc/256; +! } +! +! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg) { +! uint16_t crc; +! uint8_t i; +! uint8_t count; +! crc = 0; +! for (count=0;countlength-2;count++) { +! crc = crc ^ (uint8_t)*(msg->payload+count); +! //crc = crc ^ (uint16_t)*ptr++ << 8; +! for (i=0;i<8;i++) { +! if (crc & 0x1) { +! crc = crc >> 1 ^ 0x8408; +! } else { +! crc = crc >> 1; +! } +! } +! } +! if (*(msg->payload+(msg->length-2))==crc%256 && +! *(msg->payload+(msg->length-1))==crc/256) { +! return TRUE; +! } else { +! return FALSE; +! } +! } +! +! //======= checksum calculation +! +! //see http://www-net.cs.umass.edu/kurose/transport/UDP.html, or http://tools.ietf.org/html/rfc1071 +! //see http://en.wikipedia.org/wiki/User_Datagram_Protocol#IPv6_PSEUDO-HEADER +! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr) { +! uint8_t temp_checksum[2]; +! uint8_t little_helper[2]; +! +! // initialize running checksum +! temp_checksum[0] = 0; +! temp_checksum[1] = 0; +! +! //===== IPv6 pseudo header +! +! // source address (prefix and EUI64) +! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_PREFIX))->prefix,8); +! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_64B))->addr_64b,8); +! +! // destination address +! onesComplementSum(temp_checksum,msg->l3_destinationAdd.addr_128b,16); +! +! // length +! little_helper[0] = 0; +! little_helper[1] = msg->length; +! onesComplementSum(temp_checksum,little_helper,2); +! +! // next header +! little_helper[0] = 0; +! little_helper[1] = msg->l4_protocol; +! onesComplementSum(temp_checksum,little_helper,2); +! +! //===== payload +! +! // reset the checksum currently in the payload +! *checksum_ptr = 0; +! *(checksum_ptr+1) = 0; +! +! onesComplementSum(temp_checksum,msg->payload,msg->length); +! temp_checksum[0] ^= 0xFF; +! temp_checksum[1] ^= 0xFF; +! +! //write in packet +! *checksum_ptr = temp_checksum[0]; +! *(checksum_ptr+1) = temp_checksum[1]; +! } +! +! +! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length) { +! uint32_t sum = 0xFFFF & (global_sum[0]<<8 | global_sum[1]); +! while (length>1) { +! sum += 0xFFFF & (*ptr<<8 | *(ptr+1)); +! ptr += 2; +! length -= 2; +! } +! if (length) { +! sum += (0xFF & *ptr)<<8; +! } +! while (sum>>16) { +! sum = (sum & 0xFFFF)+(sum >> 16); +! } +! global_sum[0] = (sum>>8) & 0xFF; +! global_sum[1] = sum & 0xFF; +! } +! +! //======= endianness +! +! void packetfunctions_htons( uint16_t val, uint8_t* dest ) { +! dest[0] = (val & 0xff00) >> 8; +! dest[1] = (val & 0x00ff); +! } +! +! uint16_t packetfunctions_ntohs( uint8_t* src ) { +! return (((uint16_t) src[0]) << 8) | +! (((uint16_t) src[1]) +! ); +! } +! +! void packetfunctions_htonl( uint32_t val, uint8_t* dest ) { +! dest[0] = (val & 0xff000000) >> 24; +! dest[1] = (val & 0x00ff0000) >> 16; +! dest[2] = (val & 0x0000ff00) >> 8; +! dest[3] = (val & 0x000000ff); +! } +! +! uint32_t packetfunctions_ntohl( uint8_t* src ) { +! return (((uint32_t) src[0]) << 24) | +! (((uint32_t) src[1]) << 16) | +! (((uint32_t) src[2]) << 8) | +! (((uint32_t) src[3]) +! ); +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/cross-layers/packetfunctions.h ../../../sys/net/openwsn/cross-layers/packetfunctions.h +*** openwsn/cross-layers/packetfunctions.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/cross-layers/packetfunctions.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,61 **** +! #ifndef __PACKETFUNCTIONS_H +! #define __PACKETFUNCTIONS_H +! +! /** +! \addtogroup helpers +! \{ +! \addtogroup PacketFunctions +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // address translation +! void packetfunctions_ip128bToMac64b(open_addr_t* ip128b,open_addr_t* prefix64btoWrite,open_addr_t* mac64btoWrite); +! void packetfunctions_mac64bToIp128b(open_addr_t* prefix64b,open_addr_t* mac64b,open_addr_t* ip128bToWrite); +! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite); +! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite); +! +! // address recognition +! bool packetfunctions_isBroadcastMulticast(open_addr_t* address); +! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address); +! bool packetfunctions_isAllHostsMulticast(open_addr_t* address); +! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2); +! +! // read/write addresses to/from packets +! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian); +! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian); +! +! // reserving/tossing headers and footers +! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length); +! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length); +! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length); +! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length); +! +! // calculate CRC +! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg); +! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg); +! +! // calculate checksum +! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr); +! +! // endianness +! void packetfunctions_htons( uint16_t val, uint8_t* dest ); +! uint16_t packetfunctions_ntohs( uint8_t* src ); +! void packetfunctions_htonl( uint32_t val, uint8_t* dest ); +! uint32_t packetfunctions_ntohl( uint8_t* src ); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,61 ---- +! #ifndef __PACKETFUNCTIONS_H +! #define __PACKETFUNCTIONS_H +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup PacketFunctions +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // address translation +! void packetfunctions_ip128bToMac64b(open_addr_t* ip128b,open_addr_t* prefix64btoWrite,open_addr_t* mac64btoWrite); +! void packetfunctions_mac64bToIp128b(open_addr_t* prefix64b,open_addr_t* mac64b,open_addr_t* ip128bToWrite); +! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite); +! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite); +! +! // address recognition +! bool packetfunctions_isBroadcastMulticast(open_addr_t* address); +! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address); +! bool packetfunctions_isAllHostsMulticast(open_addr_t* address); +! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2); +! +! // read/write addresses to/from packets +! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian); +! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian); +! +! // reserving/tossing headers and footers +! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length); +! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length); +! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length); +! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length); +! +! // calculate CRC +! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg); +! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg); +! +! // calculate checksum +! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr); +! +! // endianness +! void packetfunctions_htons( uint16_t val, uint8_t* dest ); +! uint16_t packetfunctions_ntohs( uint8_t* src ); +! void packetfunctions_htonl( uint32_t val, uint8_t* dest ); +! uint32_t packetfunctions_ntohl( uint8_t* src ); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/debugpins.c ../../../sys/net/openwsn/debugpins.c +*** openwsn/debugpins.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/debugpins.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,93 **** +! /** +! \brief TelosB-specific definition of the "debugpins" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "debugpins.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void debugpins_init() { +! P6DIR |= 0x40; // frame [P6.6] +! P6DIR |= 0x80; // slot [P6.7] +! P2DIR |= 0x08; // fsm [P2.3] +! P2DIR |= 0x40; // task [P2.6] +! P6DIR |= 0x01; // isr [P6.0] +! P6DIR |= 0x02; // radio [P6.1] +! } +! +! // P6.6 +! void debugpins_frame_toggle() { +! P6OUT ^= 0x40; +! } +! void debugpins_frame_clr() { +! P6OUT &= ~0x40; +! } +! void debugpins_frame_set() { +! P6OUT |= 0x40; +! } +! +! // P6.7 +! void debugpins_slot_toggle() { +! P6OUT ^= 0x80; +! } +! void debugpins_slot_clr() { +! P6OUT &= ~0x80; +! } +! void debugpins_slot_set() { +! P6OUT |= 0x80; +! } +! +! // P2.3 +! void debugpins_fsm_toggle() { +! P2OUT ^= 0x08; +! } +! void debugpins_fsm_clr() { +! P2OUT &= ~0x08; +! } +! void debugpins_fsm_set() { +! P2OUT |= 0x08; +! } +! +! // P2.6 +! void debugpins_task_toggle() { +! P2OUT ^= 0x40; +! } +! void debugpins_task_clr() { +! P2OUT &= ~0x40; +! } +! void debugpins_task_set() { +! P2OUT |= 0x40; +! } +! +! // P6.0 +! void debugpins_isr_toggle() { +! P6OUT ^= 0x01; +! } +! void debugpins_isr_clr() { +! P6OUT &= ~0x01; +! } +! void debugpins_isr_set() { +! P6OUT |= 0x01; +! } +! +! // P6.1 +! void debugpins_radio_toggle() { +! P6OUT ^= 0x02; +! } +! void debugpins_radio_clr() { +! P6OUT &= ~0x02; +! } +! void debugpins_radio_set() { +! P6OUT |= 0x02; +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,110 ---- +! /** +! \brief TelosB-specific definition of the "debugpins" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! #include // needed for uin8_t, uint16_t +! #include "msp430f1611.h" +! #include "debugpins.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void debugpins_init(void) { +! P6DIR |= 0x40; // frame [P6.6] +! P6DIR |= 0x80; // slot [P6.7] +! P2DIR |= 0x08; // fsm [P2.3] +! P2DIR |= 0x40; // task [P2.6] +! P6DIR |= 0x01; // isr [P6.0] +! P6DIR |= 0x02; // radio [P6.1] +! } +! +! // P6.6 +! void debugpins_frame_toggle(void) { +! P6OUT ^= 0x40; +! } +! void debugpins_frame_clr(void) { +! P6OUT &= ~0x40; +! } +! void debugpins_frame_set(void) { +! P6OUT |= 0x40; +! } +! +! // P6.7 +! void debugpins_slot_toggle(void) { +! P6OUT ^= 0x80; +! } +! void debugpins_slot_clr(void) { +! P6OUT &= ~0x80; +! } +! void debugpins_slot_set(void) { +! P6OUT |= 0x80; +! } +! +! // P2.3 +! void debugpins_fsm_toggle(void) { +! P2OUT ^= 0x08; +! } +! void debugpins_fsm_clr(void) { +! P2OUT &= ~0x08; +! } +! void debugpins_fsm_set(void) { +! P2OUT |= 0x08; +! } +! +! // P2.6 +! void debugpins_task_toggle(void) { +! P2OUT ^= 0x40; +! } +! void debugpins_task_clr(void) { +! P2OUT &= ~0x40; +! } +! void debugpins_task_set(void) { +! P2OUT |= 0x40; +! } +! +! // P6.0 +! void debugpins_isr_toggle(void) { +! P6OUT ^= 0x01; +! } +! void debugpins_isr_clr(void) { +! P6OUT &= ~0x01; +! } +! void debugpins_isr_set(void) { +! P6OUT |= 0x01; +! } +! +! // P6.1 +! void debugpins_radio_toggle(void) { +! P6OUT ^= 0x02; +! } +! void debugpins_radio_clr(void) { +! P6OUT &= ~0x02; +! } +! void debugpins_radio_set(void) { +! P6OUT |= 0x02; +! } +! +! +! void leds_toggle_2x(void){ +! +! uint16_t i; +! debugpins_task_toggle(); +! for (i=0;i<0xFFFF;i++); +! for (i=0;i<0xFFFF;i++); +! debugpins_task_toggle(); +! } +! void leds_toggle_4x(void){ +! uint16_t i; +! leds_toggle_2x(); +! for (i=0;i<0xFFFF;i++); +! for (i=0;i<0xFFFF;i++); +! leds_toggle_2x(); +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/debugpins.h ../../../sys/net/openwsn/debugpins.h +*** openwsn/debugpins.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/debugpins.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,44 **** +! /** +! \brief Cross-platform declaration "leds" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __DEBUGPINS_H +! #define __DEBUGPINS_H +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void debugpins_init(); +! +! void debugpins_frame_toggle(); +! void debugpins_frame_clr(); +! void debugpins_frame_set(); +! +! void debugpins_slot_toggle(); +! void debugpins_slot_clr(); +! void debugpins_slot_set(); +! +! void debugpins_fsm_toggle(); +! void debugpins_fsm_clr(); +! void debugpins_fsm_set(); +! +! void debugpins_task_toggle(); +! void debugpins_task_clr(); +! void debugpins_task_set(); +! +! void debugpins_isr_toggle(); +! void debugpins_isr_clr(); +! void debugpins_isr_set(); +! +! void debugpins_radio_toggle(); +! void debugpins_radio_clr(); +! void debugpins_radio_set(); +! +! #endif +--- 1,54 ---- +! #ifndef __DEBUGPINS_H +! #define __DEBUGPINS_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup debugpins +! \{ +! +! \brief Cross-platform declaration "leds" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void debugpins_init(void); +! +! void debugpins_frame_toggle(void); +! void debugpins_frame_clr(void); +! void debugpins_frame_set(void); +! +! void debugpins_slot_toggle(void); +! void debugpins_slot_clr(void); +! void debugpins_slot_set(void); +! +! void debugpins_fsm_toggle(void); +! void debugpins_fsm_clr(void); +! void debugpins_fsm_set(void); +! +! void debugpins_task_toggle(void); +! void debugpins_task_clr(void); +! void debugpins_task_set(void); +! +! void debugpins_isr_toggle(void); +! void debugpins_isr_clr(void); +! void debugpins_isr_set(void); +! +! void debugpins_radio_toggle(void); +! void debugpins_radio_clr(void); +! void debugpins_radio_set(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/eui64.c ../../../sys/net/openwsn/eui64.c +*** openwsn/eui64.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/eui64.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,218 **** +! /** +! \brief TelosB-specific definition of the "eui64" bsp module. +! +! \author Thomas Watteyne , March 2012. +! */ +! +! #include "msp430f1611.h" +! #include "string.h" +! #include "eui64.h" +! +! //=========================== defines ========================================= +! +! #define PIN_1WIRE 0x10 +! +! //=========================== enums =========================================== +! +! enum { +! OW_DLY_A = 6, +! OW_DLY_B = 64, +! OW_DLY_C = 60, +! OW_DLY_D = 10, +! OW_DLY_E = 9, +! OW_DLY_F = 55, +! OW_DLY_G = 0, +! OW_DLY_H = 480, +! OW_DLY_I = 90, +! OW_DLY_J = 220, +! }; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // 1Wire +! uint8_t ow_reset(); +! void ow_write_byte(uint8_t byte); +! uint8_t ow_read_byte(); +! void ow_write_bit(int is_one); +! uint8_t ow_read_bit(); +! void ow_write_bit_one(); +! void ow_write_bit_zero(); +! // CRC +! uint8_t crc8_byte(uint8_t crc, uint8_t byte); +! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len); +! // timer +! void delay_us(uint16_t delay); +! // pin +! void owpin_init(); +! void owpin_output_low(); +! void owpin_output_high(); +! void owpin_prepare_read(); +! uint8_t owpin_read(); +! +! //=========================== public ========================================== +! +! void eui64_get(uint8_t* addressToWrite) { // >= 6000us +! uint8_t id[8]; +! int retry; +! int crc; +! uint8_t* byte; +! uint16_t oldTactl; +! +! retry = 5; +! memset(addressToWrite,0,8); +! +! // store current value of TACTL +! oldTactl = TACTL; +! +! // start timer in continuous mode at 1MHz +! TACTL = TASSEL_2 | ID_2 | MC_2; +! +! owpin_init(); +! while (retry-- > 0) { +! crc = 0; +! +! if(ow_reset()) { +! ow_write_byte(0x33); //read rom +! for(byte=id+7; byte>=id; byte--) { +! crc = crc8_byte( crc, *byte=ow_read_byte() ); +! } +! if(crc==0) { +! // CRC valid +! *(addressToWrite+0) = 0x14; +! *(addressToWrite+1) = 0x15; +! *(addressToWrite+2) = 0x92; +! memcpy(addressToWrite+3,id+1,5); +! } +! } +! } +! +! // restore value of TACTL +! TACTL = oldTactl; +! } +! +! //=========================== private ========================================= +! +! //===== 1Wire +! +! // admin +! +! uint8_t ow_reset() { // >= 960us +! int present; +! owpin_output_low(); +! delay_us(OW_DLY_H); // t_RSTL +! owpin_prepare_read(); +! delay_us(OW_DLY_I); // t_MSP +! present = owpin_read(); +! delay_us(OW_DLY_J); // t_REC +! return (present==0); +! } +! +! // byte-level access +! +! void ow_write_byte(uint8_t byte) {// >= 560us +! uint8_t bit; +! for(bit=0x01;bit!=0;bit<<=1) { +! ow_write_bit(byte & bit); +! } +! } +! +! uint8_t ow_read_byte() { // >= 560us +! uint8_t byte = 0; +! uint8_t bit; +! for( bit=0x01; bit!=0; bit<<=1 ) { +! if(ow_read_bit()) { +! byte |= bit; +! } +! } +! return byte; +! } +! +! // bit-level access +! +! void ow_write_bit(int is_one) { // >= 70us +! if(is_one) { +! ow_write_bit_one(); +! } else { +! ow_write_bit_zero(); +! } +! } +! +! uint8_t ow_read_bit() { // >= 70us +! int bit; +! owpin_output_low(); +! delay_us(OW_DLY_A); // t_RL +! owpin_prepare_read(); +! delay_us(OW_DLY_E); // near-max t_MSR +! bit = owpin_read(); +! delay_us(OW_DLY_F); // t_REC +! return bit; +! } +! +! void ow_write_bit_one() { // >= 70us +! owpin_output_low(); +! delay_us(OW_DLY_A); // t_W1L +! owpin_output_high(); +! delay_us(OW_DLY_B); // t_SLOT - t_W1L +! } +! +! void ow_write_bit_zero() { // >= 70us +! owpin_output_low(); +! delay_us(OW_DLY_C); // t_W0L +! owpin_output_high(); +! delay_us(OW_DLY_D); // t_SLOT - t_W0L +! } +! +! //===== CRC +! +! uint8_t crc8_byte(uint8_t crc, uint8_t byte) { +! int i; +! crc ^= byte; +! for( i=0; i<8; i++ ) +! { +! if( crc & 1 ) +! crc = (crc >> 1) ^ 0x8c; +! else +! crc >>= 1; +! } +! return crc; +! } +! +! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len) { +! uint8_t* end = bytes+len; +! while( bytes != end ) +! crc = crc8_byte( crc, *bytes++ ); +! return crc; +! } +! +! //===== timer +! +! void delay_us(uint16_t delay) { +! uint16_t startTime; +! startTime = TAR; +! while (TAR, March 2012. +! */ +! +! #include "msp430f1611.h" +! #include "string.h" +! #include "eui64.h" +! +! //=========================== defines ========================================= +! +! #define PIN_1WIRE 0x10 +! +! //=========================== enums =========================================== +! +! enum { +! OW_DLY_A = 6, +! OW_DLY_B = 64, +! OW_DLY_C = 60, +! OW_DLY_D = 10, +! OW_DLY_E = 9, +! OW_DLY_F = 55, +! OW_DLY_G = 0, +! OW_DLY_H = 480, +! OW_DLY_I = 90, +! OW_DLY_J = 220, +! }; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // 1Wire +! uint8_t ow_reset(void); +! void ow_write_byte(uint8_t byte); +! uint8_t ow_read_byte(void); +! void ow_write_bit(int is_one); +! uint8_t ow_read_bit(void); +! void ow_write_bit_one(void); +! void ow_write_bit_zero(void); +! // CRC +! uint8_t crc8_byte(uint8_t crc, uint8_t byte); +! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len); +! // timer +! void delay_us(uint16_t delay); +! // pin +! void owpin_init(void); +! void owpin_output_low(void); +! void owpin_output_high(void); +! void owpin_prepare_read(void); +! uint8_t owpin_read(void); +! +! //=========================== public ========================================== +! +! void eui64_get(uint8_t* addressToWrite) { // >= 6000us +! uint8_t id[8]; +! int retry; +! int crc; +! uint8_t* byte; +! uint16_t oldTactl; +! +! retry = 5; +! memset(addressToWrite,0,8); +! +! // store current value of TACTL +! oldTactl = TACTL; +! +! // start timer in continuous mode at 1MHz +! TACTL = TASSEL_2 | ID_2 | MC_2; +! +! owpin_init(); +! while (retry-- > 0) { +! crc = 0; +! +! if(ow_reset()) { +! ow_write_byte(0x33); //read rom +! for(byte=id+7; byte>=id; byte--) { +! crc = crc8_byte( crc, *byte=ow_read_byte() ); +! } +! if(crc==0) { +! // CRC valid +! *(addressToWrite+0) = 0x14; +! *(addressToWrite+1) = 0x15; +! *(addressToWrite+2) = 0x92; +! memcpy(addressToWrite+3,id+1,5); +! } +! } +! } +! +! // restore value of TACTL +! TACTL = oldTactl; +! } +! +! //=========================== private ========================================= +! +! //===== 1Wire +! +! // admin +! +! uint8_t ow_reset(void) { // >= 960us +! int present; +! owpin_output_low(); +! delay_us(OW_DLY_H); // t_RSTL +! owpin_prepare_read(); +! delay_us(OW_DLY_I); // t_MSP +! present = owpin_read(); +! delay_us(OW_DLY_J); // t_REC +! return (present==0); +! } +! +! // byte-level access +! +! void ow_write_byte(uint8_t byte) {// >= 560us +! uint8_t bit; +! for(bit=0x01;bit!=0;bit<<=1) { +! ow_write_bit(byte & bit); +! } +! } +! +! uint8_t ow_read_byte(void) { // >= 560us +! uint8_t byte = 0; +! uint8_t bit; +! for( bit=0x01; bit!=0; bit<<=1 ) { +! if(ow_read_bit()) { +! byte |= bit; +! } +! } +! return byte; +! } +! +! // bit-level access +! +! void ow_write_bit(int is_one) { // >= 70us +! if(is_one) { +! ow_write_bit_one(); +! } else { +! ow_write_bit_zero(); +! } +! } +! +! uint8_t ow_read_bit(void) { // >= 70us +! int bit; +! owpin_output_low(); +! delay_us(OW_DLY_A); // t_RL +! owpin_prepare_read(); +! delay_us(OW_DLY_E); // near-max t_MSR +! bit = owpin_read(); +! delay_us(OW_DLY_F); // t_REC +! return bit; +! } +! +! void ow_write_bit_one(void) { // >= 70us +! owpin_output_low(); +! delay_us(OW_DLY_A); // t_W1L +! owpin_output_high(); +! delay_us(OW_DLY_B); // t_SLOT - t_W1L +! } +! +! void ow_write_bit_zero(void) { // >= 70us +! owpin_output_low(); +! delay_us(OW_DLY_C); // t_W0L +! owpin_output_high(); +! delay_us(OW_DLY_D); // t_SLOT - t_W0L +! } +! +! //===== CRC +! +! uint8_t crc8_byte(uint8_t crc, uint8_t byte) { +! int i; +! crc ^= byte; +! for( i=0; i<8; i++ ) +! { +! if( crc & 1 ) +! crc = (crc >> 1) ^ 0x8c; +! else +! crc >>= 1; +! } +! return crc; +! } +! +! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len) { +! uint8_t* end = bytes+len; +! while( bytes != end ) +! crc = crc8_byte( crc, *bytes++ ); +! return crc; +! } +! +! //===== timer +! +! void delay_us(uint16_t delay) { +! uint16_t startTime; +! startTime = TAR; +! while (TAR, March 2012. +! */ +! +! #ifndef __EUI64_H +! #define __EUI64_H +! +! #include +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void eui64_get(uint8_t* addressToWrite); +! + #endif +\ No newline at end of file +--- 1,32 ---- +! #ifndef __EUI64_H +! #define __EUI64_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup eui64 +! \{ +! +! \brief Cross-platform declaration "eui64" bsp module. +! +! \author Thomas Watteyne , March 2012. +! */ +! +! #include +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void eui64_get(uint8_t* addressToWrite); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/leds.c ../../../sys/net/openwsn/leds.c +*** openwsn/leds.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/leds.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,137 **** +! /** +! \brief TelosB-specific definition of the "leds" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void leds_init() { +! P5DIR |= 0x70; // P5DIR = 0bx111xxxx for LEDs +! P5OUT |= 0x70; // P2OUT = 0bx111xxxx, all LEDs off +! } +! +! // red = LED1 = P5.4 +! void leds_error_on() { +! P5OUT &= ~0x10; +! } +! void leds_error_off() { +! P5OUT |= 0x10; +! } +! void leds_error_toggle() { +! P5OUT ^= 0x10; +! } +! uint8_t leds_error_isOn() { +! return (uint8_t)(P5OUT & 0x10)>>4; +! } +! void leds_error_blink() { +! uint8_t i; +! volatile uint16_t delay; +! // turn all LEDs off +! P5OUT |= 0x70; +! +! // blink error LED for ~10s +! for (i=0;i<80;i++) { +! P5OUT ^= 0x10; +! for (delay=0xffff;delay>0;delay--); +! } +! } +! +! // green = LED2 = P5.5 +! void leds_radio_on() { +! P5OUT &= ~0x20; +! } +! void leds_radio_off() { +! P5OUT |= 0x20; +! } +! void leds_radio_toggle() { +! P5OUT ^= 0x20; +! } +! uint8_t leds_radio_isOn() { +! return (uint8_t)(P5OUT & 0x20)>>5; +! } +! +! // blue = LED3 = P5.6 +! void leds_sync_on() { +! P5OUT &= ~0x40; +! } +! void leds_sync_off() { +! P5OUT |= 0x40; +! } +! void leds_sync_toggle() { +! P5OUT ^= 0x40; +! } +! uint8_t leds_sync_isOn() { +! return (uint8_t)(P5OUT & 0x40)>>6; +! } +! +! void leds_debug_on() { +! // TelosB doesn't have a debug LED :( +! } +! void leds_debug_off() { +! // TelosB doesn't have a debug LED :( +! } +! void leds_debug_toggle() { +! // TelosB doesn't have a debug LED :( +! } +! uint8_t leds_debug_isOn() { +! // TelosB doesn't have a debug LED :( +! return 0; +! } +! +! void leds_all_on() { +! P5OUT &= ~0x70; +! } +! void leds_all_off() { +! P5OUT |= 0x70; +! } +! void leds_all_toggle() { +! P5OUT ^= 0x70; +! } +! +! void leds_circular_shift() { +! uint8_t leds_on; +! // get LED state +! leds_on = (~P5OUT & 0x70) >> 4; +! // modify LED state +! if (leds_on==0) { // if no LEDs on, switch on one +! leds_on = 0x01; +! } else { +! leds_on <<= 1; // shift by one position +! if ((leds_on & 0x08)!=0) { +! leds_on &= ~0x08; +! leds_on |= 0x01; // handle overflow +! } +! } +! // apply updated LED state +! leds_on <<= 4; // send back to position 4 +! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on +! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on +! } +! +! void leds_increment() { +! uint8_t leds_on; +! // get LED state +! leds_on = (~P5OUT & 0x70) >> 4; +! // modify LED state +! if (leds_on==0) { // if no LEDs on, switch on one +! leds_on = 0x01; +! } else { +! leds_on += 1; +! } +! // apply updated LED state +! leds_on <<= 4; // send back to position 4 +! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on +! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on +! } +! + //=========================== private ========================================= +\ No newline at end of file +--- 1,137 ---- +! /** +! \brief TelosB-specific definition of the "leds" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void leds_init(void) { +! P5DIR |= 0x70; // P5DIR = 0bx111xxxx for LEDs +! P5OUT |= 0x70; // P2OUT = 0bx111xxxx, all LEDs off +! } +! +! // red = LED1 = P5.4 +! void leds_error_on(void) { +! P5OUT &= ~0x10; +! } +! void leds_error_off(void) { +! P5OUT |= 0x10; +! } +! void leds_error_toggle(void) { +! P5OUT ^= 0x10; +! } +! uint8_t leds_error_isOn(void) { +! return (uint8_t)(P5OUT & 0x10)>>4; +! } +! void leds_error_blink(void) { +! uint8_t i; +! volatile uint16_t delay; +! // turn all LEDs off +! P5OUT |= 0x70; +! +! // blink error LED for ~10s +! for (i=0;i<80;i++) { +! P5OUT ^= 0x10; +! for (delay=0xffff;delay>0;delay--); +! } +! } +! +! // green = LED2 = P5.5 +! void leds_radio_on(void) { +! P5OUT &= ~0x20; +! } +! void leds_radio_off(void) { +! P5OUT |= 0x20; +! } +! void leds_radio_toggle(void) { +! P5OUT ^= 0x20; +! } +! uint8_t leds_radio_isOn(void) { +! return (uint8_t)(P5OUT & 0x20)>>5; +! } +! +! // blue = LED3 = P5.6 +! void leds_sync_on(void) { +! P5OUT &= ~0x40; +! } +! void leds_sync_off(void) { +! P5OUT |= 0x40; +! } +! void leds_sync_toggle(void) { +! P5OUT ^= 0x40; +! } +! uint8_t leds_sync_isOn(void) { +! return (uint8_t)(P5OUT & 0x40)>>6; +! } +! +! void leds_debug_on(void) { +! // TelosB doesn't have a debug LED :( +! } +! void leds_debug_off(void) { +! // TelosB doesn't have a debug LED :( +! } +! void leds_debug_toggle(void) { +! // TelosB doesn't have a debug LED :( +! } +! uint8_t leds_debug_isOn(void) { +! // TelosB doesn't have a debug LED :( +! return 0; +! } +! +! void leds_all_on(void) { +! P5OUT &= ~0x70; +! } +! void leds_all_off(void) { +! P5OUT |= 0x70; +! } +! void leds_all_toggle(void) { +! P5OUT ^= 0x70; +! } +! +! void leds_circular_shift(void) { +! uint8_t leds_on; +! // get LED state +! leds_on = (~P5OUT & 0x70) >> 4; +! // modify LED state +! if (leds_on==0) { // if no LEDs on, switch on one +! leds_on = 0x01; +! } else { +! leds_on <<= 1; // shift by one position +! if ((leds_on & 0x08)!=0) { +! leds_on &= ~0x08; +! leds_on |= 0x01; // handle overflow +! } +! } +! // apply updated LED state +! leds_on <<= 4; // send back to position 4 +! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on +! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on +! } +! +! void leds_increment(void) { +! uint8_t leds_on; +! // get LED state +! leds_on = (~P5OUT & 0x70) >> 4; +! // modify LED state +! if (leds_on==0) { // if no LEDs on, switch on one +! leds_on = 0x01; +! } else { +! leds_on += 1; +! } +! // apply updated LED state +! leds_on <<= 4; // send back to position 4 +! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on +! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on +! } +! + //=========================== private ========================================= +\ No newline at end of file +diff -crB openwsn/leds.h ../../../sys/net/openwsn/leds.h +*** openwsn/leds.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/leds.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,50 **** +! /** +! \brief Cross-platform declaration "leds" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __LEDS_H +! #define __LEDS_H +! +! #include "stdint.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void leds_init(); +! +! void leds_error_on(); +! void leds_error_off(); +! void leds_error_toggle(); +! uint8_t leds_error_isOn(); +! void leds_error_blink(); +! +! void leds_radio_on(); +! void leds_radio_off(); +! void leds_radio_toggle(); +! uint8_t leds_radio_isOn(); +! +! void leds_sync_on(); +! void leds_sync_off(); +! void leds_sync_toggle(); +! uint8_t leds_sync_isOn(); +! +! void leds_debug_on(); +! void leds_debug_off(); +! void leds_debug_toggle(); +! uint8_t leds_debug_isOn(); +! +! void leds_all_on(); +! void leds_all_off(); +! void leds_all_toggle(); +! +! void leds_circular_shift(); +! void leds_increment(); +! +! #endif +--- 1,60 ---- +! #ifndef __LEDS_H +! #define __LEDS_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup leds +! \{ +! +! \brief Cross-platform declaration "leds" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "stdint.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void leds_init(void); +! +! void leds_error_on(void); +! void leds_error_off(void); +! void leds_error_toggle(void); +! uint8_t leds_error_isOn(void); +! void leds_error_blink(void); +! +! void leds_radio_on(void); +! void leds_radio_off(void); +! void leds_radio_toggle(void); +! uint8_t leds_radio_isOn(void); +! +! void leds_sync_on(void); +! void leds_sync_off(void); +! void leds_sync_toggle(void); +! uint8_t leds_sync_isOn(void); +! +! void leds_debug_on(void); +! void leds_debug_off(void); +! void leds_debug_toggle(void); +! uint8_t leds_debug_isOn(void); +! +! void leds_all_on(void); +! void leds_all_off(void); +! void leds_all_toggle(void); +! +! void leds_circular_shift(void); +! void leds_increment(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/openhdlc.c ../../../sys/net/openwsn/openhdlc.c +*** openwsn/openhdlc.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/openhdlc.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,20 **** +! /** +! \brief Definition of the "openserial" driver. +! +! \author Min Ting , October 2012. +! \author Fabien Chraim , October 2012. +! */ +! +! #include "openhdlc.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! uint16_t crcIteration(uint16_t crc, uint8_t byte) { +! return (crc >> 8) ^ fcstab[(crc ^ byte) & 0xff]; +! } +! +! //=========================== private ========================================= +--- 1,20 ---- +! /** +! \brief Definition of the "openserial" driver. +! +! \author Min Ting , October 2012. +! \author Fabien Chraim , October 2012. +! */ +! +! #include "openhdlc.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! uint16_t crcIteration(uint16_t crc, uint8_t byte) { +! return (crc >> 8) ^ fcstab[(crc ^ byte) & 0xff]; +! } +! +! //=========================== private ========================================= +diff -crB openwsn/openhdlc.h ../../../sys/net/openwsn/openhdlc.h +*** openwsn/openhdlc.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/openhdlc.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,75 **** +! /** +! \brief Declaraion of the "openserial" driver. +! +! \author Min Ting , October 2012. +! \author Fabien Chraim , October 2012. +! */ +! +! #ifndef __OPENHDLC_H +! #define __OPENHDLC_H +! +! #include "openwsn.h" +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup HDLC +! \{ +! */ +! +! //=========================== define ========================================== +! +! #define HDLC_FLAG 0x7e +! #define HDLC_ESCAPE 0x7d +! #define HDLC_ESCAPE_MASK 0x20 +! #define HDLC_CRCINIT 0xffff +! #define HDLC_CRCGOOD 0xf0b8 +! +! //this table is used to expedite execution (at the expense of memory usage) +! static const uint16_t fcstab[256] = { +! 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, +! 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, +! 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, +! 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, +! 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, +! 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, +! 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, +! 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, +! 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, +! 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, +! 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, +! 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, +! 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, +! 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, +! 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, +! 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, +! 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, +! 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, +! 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, +! 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, +! 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, +! 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, +! 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, +! 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, +! 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, +! 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, +! 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, +! 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, +! 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, +! 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, +! 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, +! 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +! }; +! +! //=========================== typedef ========================================= +! +! //=========================== prototypes ====================================== +! +! uint16_t crcIteration(uint16_t crc, uint8_t byte); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,75 ---- +! /** +! \brief Declaraion of the "openserial" driver. +! +! \author Min Ting , October 2012. +! \author Fabien Chraim , October 2012. +! */ +! +! #ifndef __OPENHDLC_H +! #define __OPENHDLC_H +! +! #include "openwsn.h" +! +! /** +! \addtogroup drivers +! \{ +! \addtogroup HDLC +! \{ +! */ +! +! //=========================== define ========================================== +! +! #define HDLC_FLAG 0x7e +! #define HDLC_ESCAPE 0x7d +! #define HDLC_ESCAPE_MASK 0x20 +! #define HDLC_CRCINIT 0xffff +! #define HDLC_CRCGOOD 0xf0b8 +! +! //this table is used to expedite execution (at the expense of memory usage) +! static const uint16_t fcstab[256] = { +! 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, +! 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, +! 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, +! 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, +! 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, +! 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, +! 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, +! 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, +! 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, +! 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, +! 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, +! 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, +! 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, +! 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, +! 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, +! 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, +! 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, +! 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, +! 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, +! 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, +! 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, +! 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, +! 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, +! 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, +! 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, +! 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, +! 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, +! 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, +! 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, +! 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, +! 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, +! 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +! }; +! +! //=========================== typedef ========================================= +! +! //=========================== prototypes ====================================== +! +! uint16_t crcIteration(uint16_t crc, uint8_t byte); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/openserial.c ../../../sys/net/openwsn/openserial.c +*** openwsn/openserial.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/openserial.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,633 **** +! /** +! \brief Definition of the "openserial" driver. +! +! \author Fabien Chraim , March 2012. +! */ +! +! #include "openwsn.h" +! #include "openserial.h" +! #include "IEEE802154E.h" +! #include "neighbors.h" +! #include "res.h" +! #include "icmpv6echo.h" +! #include "idmanager.h" +! #include "openqueue.h" +! #include "tcpinject.h" +! #include "udpinject.h" +! #include "openbridge.h" +! #include "leds.h" +! #include "schedule.h" +! #include "uart.h" +! #include "opentimers.h" +! #include "openhdlc.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! // admin +! uint8_t mode; +! uint8_t debugPrintCounter; +! // input +! uint8_t reqFrame[1+1+2+1]; // flag (1B), command (2B), CRC (2B), flag (1B) +! uint8_t reqFrameIdx; +! uint8_t lastRxByte; +! bool busyReceiving; +! bool inputEscaping; +! uint16_t inputCrc; +! uint8_t inputBufFill; +! uint8_t inputBuf[SERIAL_INPUT_BUFFER_SIZE]; +! // output +! bool outputBufFilled; +! uint16_t outputCrc; +! uint8_t outputBufIdxW; +! uint8_t outputBufIdxR; +! uint8_t outputBuf[SERIAL_OUTPUT_BUFFER_SIZE]; +! } openserial_vars_t; +! +! openserial_vars_t openserial_vars; +! +! //=========================== prototypes ====================================== +! +! error_t openserial_printInfoErrorCritical( +! char severity, +! uint8_t calling_component, +! uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2 +! ); +! // HDLC output +! void outputHdlcOpen(); +! void outputHdlcWrite(uint8_t b); +! void outputHdlcClose(); +! // HDLC input +! void inputHdlcOpen(); +! void inputHdlcWrite(uint8_t b); +! void inputHdlcClose(); +! +! //=========================== public ========================================== +! +! void openserial_init() { +! uint16_t crc; +! +! // reset variable +! memset(&openserial_vars,0,sizeof(openserial_vars_t)); +! +! // admin +! openserial_vars.mode = MODE_OFF; +! openserial_vars.debugPrintCounter = 0; +! +! // input +! openserial_vars.reqFrame[0] = HDLC_FLAG; +! openserial_vars.reqFrame[1] = SERFRAME_MOTE2PC_REQUEST; +! crc = HDLC_CRCINIT; +! crc = crcIteration(crc,openserial_vars.reqFrame[1]); +! crc = ~crc; +! openserial_vars.reqFrame[2] = (crc>>0)&0xff; +! openserial_vars.reqFrame[3] = (crc>>8)&0xff; +! openserial_vars.reqFrame[4] = HDLC_FLAG; +! openserial_vars.reqFrameIdx = 0; +! openserial_vars.lastRxByte = HDLC_FLAG; +! openserial_vars.busyReceiving = FALSE; +! openserial_vars.inputEscaping = FALSE; +! openserial_vars.inputBufFill = 0; +! +! // ouput +! openserial_vars.outputBufFilled = FALSE; +! openserial_vars.outputBufIdxR = 0; +! openserial_vars.outputBufIdxW = 0; +! +! // set callbacks +! uart_setCallbacks(isr_openserial_tx, +! isr_openserial_rx); +! } +! +! error_t openserial_printStatus(uint8_t statusElement,uint8_t* buffer, uint16_t length) { +! uint8_t i; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! openserial_vars.outputBufFilled = TRUE; +! outputHdlcOpen(); +! outputHdlcWrite(SERFRAME_MOTE2PC_STATUS); +! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); +! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); +! outputHdlcWrite(statusElement); +! for (i=0;iaddr_16b[0]); +! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); +! outputHdlcWrite(calling_component); +! outputHdlcWrite(error_code); +! outputHdlcWrite((uint8_t)((arg1 & 0xff00)>>8)); +! outputHdlcWrite((uint8_t) (arg1 & 0x00ff)); +! outputHdlcWrite((uint8_t)((arg2 & 0xff00)>>8)); +! outputHdlcWrite((uint8_t) (arg2 & 0x00ff)); +! outputHdlcClose(); +! ENABLE_INTERRUPTS(); +! +! return E_SUCCESS; +! } +! +! error_t openserial_printData(uint8_t* buffer, uint8_t length) { +! uint8_t i; +! uint8_t asn[5]; +! INTERRUPT_DECLARATION(); +! +! // retrieve ASN +! asnWriteToSerial(asn);// byte01,byte23,byte4 +! +! DISABLE_INTERRUPTS(); +! openserial_vars.outputBufFilled = TRUE; +! outputHdlcOpen(); +! outputHdlcWrite(SERFRAME_MOTE2PC_DATA); +! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); +! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); +! outputHdlcWrite(asn[0]); +! outputHdlcWrite(asn[1]); +! outputHdlcWrite(asn[2]); +! outputHdlcWrite(asn[3]); +! outputHdlcWrite(asn[4]); +! for (i=0;i0) { +! openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUTBUFFER_LENGTH, +! (errorparameter_t)openserial_vars.inputBufFill, +! (errorparameter_t)0); +! openserial_vars.inputBufFill = 0; +! } +! +! uart_clearTxInterrupts(); +! uart_clearRxInterrupts(); // clear possible pending interrupts +! uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt +! +! DISABLE_INTERRUPTS(); +! openserial_vars.mode = MODE_INPUT; +! openserial_vars.reqFrameIdx = 0; +! uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]); +! ENABLE_INTERRUPTS(); +! } +! +! void openserial_startOutput() { +! //schedule a task to get new status in the output buffer +! uint8_t debugPrintCounter; +! +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! openserial_vars.debugPrintCounter = (openserial_vars.debugPrintCounter+1)%STATUS_MAX; +! debugPrintCounter = openserial_vars.debugPrintCounter; +! ENABLE_INTERRUPTS(); +! +! // print debug information +! switch (debugPrintCounter) { +! case STATUS_ISSYNC: +! if (debugPrint_isSync()==TRUE) { +! break; +! } +! case STATUS_ID: +! if (debugPrint_id()==TRUE) { +! break; +! } +! case STATUS_DAGRANK: +! if (debugPrint_myDAGrank()==TRUE) { +! break; +! } +! case STATUS_OUTBUFFERINDEXES: +! if (debugPrint_outBufferIndexes()==TRUE) { +! break; +! } +! case STATUS_ASN: +! if (debugPrint_asn()==TRUE) { +! break; +! } +! case STATUS_MACSTATS: +! if (debugPrint_macStats()==TRUE) { +! break; +! } +! case STATUS_SCHEDULE: +! if(debugPrint_schedule()==TRUE) { +! break; +! } +! case STATUS_BACKOFF: +! if(debugPrint_backoff()==TRUE) { +! break; +! } +! case STATUS_QUEUE: +! if(debugPrint_queue()==TRUE) { +! break; +! } +! case STATUS_NEIGHBORS: +! if (debugPrint_neighbors()==TRUE) { +! break; +! } +! default: +! DISABLE_INTERRUPTS(); +! openserial_vars.debugPrintCounter=0; +! ENABLE_INTERRUPTS(); +! } +! +! // flush buffer +! uart_clearTxInterrupts(); +! uart_clearRxInterrupts(); // clear possible pending interrupts +! uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt +! DISABLE_INTERRUPTS(); +! openserial_vars.mode=MODE_OUTPUT; +! if (openserial_vars.outputBufFilled) { +! uart_writeByte(openserial_vars.outputBuf[openserial_vars.outputBufIdxR++]); +! } else { +! openserial_stop(); +! } +! ENABLE_INTERRUPTS(); +! } +! +! void openserial_stop() { +! uint8_t inputBufFill; +! uint8_t cmdByte; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! inputBufFill = openserial_vars.inputBufFill; +! ENABLE_INTERRUPTS(); +! +! // disable USCI_A1 TX & RX interrupt +! uart_disableInterrupts(); +! +! DISABLE_INTERRUPTS(); +! openserial_vars.mode=MODE_OFF; +! ENABLE_INTERRUPTS(); +! +! if (inputBufFill>0) { +! DISABLE_INTERRUPTS(); +! cmdByte = openserial_vars.inputBuf[0]; +! ENABLE_INTERRUPTS(); +! switch (cmdByte) { +! case SERFRAME_PC2MOTE_SETROOT: +! idmanager_triggerAboutRoot(); +! break; +! case SERFRAME_PC2MOTE_SETBRIDGE: +! idmanager_triggerAboutBridge(); +! break; +! case SERFRAME_PC2MOTE_DATA: +! openbridge_triggerData(); +! break; +! case SERFRAME_PC2MOTE_TRIGGERTCPINJECT: +! tcpinject_trigger(); +! break; +! case SERFRAME_PC2MOTE_TRIGGERUDPINJECT: +! udpinject_trigger(); +! break; +! case SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO: +! icmpv6echo_trigger(); +! break; +! case SERFRAME_PC2MOTE_TRIGGERSERIALECHO: +! openserial_echo(&openserial_vars.inputBuf[1],inputBufFill-1); +! break; +! default: +! openserial_printError(COMPONENT_OPENSERIAL,ERR_UNSUPPORTED_COMMAND, +! (errorparameter_t)cmdByte, +! (errorparameter_t)0); +! DISABLE_INTERRUPTS(); +! openserial_vars.inputBufFill = 0; +! ENABLE_INTERRUPTS(); +! break; +! } +! DISABLE_INTERRUPTS(); +! openserial_vars.inputBufFill = 0; +! ENABLE_INTERRUPTS(); +! } +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_outBufferIndexes() { +! uint16_t temp_buffer[2]; +! INTERRUPT_DECLARATION(); +! DISABLE_INTERRUPTS(); +! temp_buffer[0] = openserial_vars.outputBufIdxW; +! temp_buffer[1] = openserial_vars.outputBufIdxR; +! ENABLE_INTERRUPTS(); +! openserial_printStatus(STATUS_OUTBUFFERINDEXES,(uint8_t*)temp_buffer,sizeof(temp_buffer)); +! return TRUE; +! } +! +! //=========================== private ========================================= +! +! //===== hdlc (output) +! +! /** +! \brief Start an HDLC frame in the output buffer. +! */ +! inline void outputHdlcOpen() { +! // initialize the value of the CRC +! openserial_vars.outputCrc = HDLC_CRCINIT; +! +! // write the opening HDLC flag +! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; +! } +! /** +! \brief Add a byte to the outgoing HDLC frame being built. +! +! \todo escape 0x7e and 0x7d. +! */ +! inline void outputHdlcWrite(uint8_t b) { +! +! // iterate through CRC calculator +! openserial_vars.outputCrc = crcIteration(openserial_vars.outputCrc,b); +! +! // add byte to buffer +! if (b==HDLC_FLAG || b==HDLC_ESCAPE) { +! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_ESCAPE; +! b = b^HDLC_ESCAPE_MASK; +! } +! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = b; +! +! } +! /** +! \brief Finalize the outgoing HDLC frame. +! */ +! inline void outputHdlcClose() { +! // finalize the calculation of the CRC +! openserial_vars.outputCrc = ~openserial_vars.outputCrc; +! +! // write the CRC value +! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = (openserial_vars.outputCrc>>0)&0xff; +! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = (openserial_vars.outputCrc>>8)&0xff; +! +! // write the closing HDLC flag +! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; +! } +! +! //===== hdlc (input) +! +! /** +! \brief Start an HDLC frame in the input buffer. +! */ +! inline void inputHdlcOpen() { +! // reset the input buffer index +! openserial_vars.inputBufFill = 0; +! +! // initialize the value of the CRC +! openserial_vars.inputCrc = HDLC_CRCINIT; +! } +! /** +! \brief Add a byte to the incoming HDLC frame. +! +! \todo escape 0x7e and 0x7d. +! */ +! inline void inputHdlcWrite(uint8_t b) { +! if (b==HDLC_ESCAPE) { +! openserial_vars.inputEscaping = TRUE; +! } else { +! if (openserial_vars.inputEscaping==TRUE) { +! b = b^HDLC_ESCAPE_MASK; +! openserial_vars.inputEscaping = FALSE; +! } +! +! // add byte to input buffer +! openserial_vars.inputBuf[openserial_vars.inputBufFill] = b; +! openserial_vars.inputBufFill++; +! +! // iterate through CRC calculator +! openserial_vars.inputCrc = crcIteration(openserial_vars.inputCrc,b); +! } +! } +! /** +! \brief Finalize the incoming HDLC frame. +! */ +! inline void inputHdlcClose() { +! +! // verify the validity of the frame +! if (openserial_vars.inputCrc==HDLC_CRCGOOD) { +! // the CRC is correct +! +! // remove the CRC from the input buffer +! openserial_vars.inputBufFill -= 2; +! } else { +! // the CRC is incorrect +! +! // drop the incoming fram +! openserial_vars.inputBufFill = 0; +! } +! } +! +! //=========================== interrupt handlers ============================== +! +! //executed in ISR, called from scheduler.c +! void isr_openserial_tx() { +! switch (openserial_vars.mode) { +! case MODE_INPUT: +! openserial_vars.reqFrameIdx++; +! if (openserial_vars.reqFrameIdxSERIAL_INPUT_BUFFER_SIZE){ +! // input buffer overflow +! openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUT_BUFFER_OVERFLOW, +! (errorparameter_t)0, +! (errorparameter_t)0); +! openserial_vars.inputBufFill = 0; +! openserial_vars.busyReceiving = FALSE; +! openserial_stop(); +! } +! } else if ( +! openserial_vars.busyReceiving==TRUE && +! rxbyte==HDLC_FLAG +! ) { +! // end of frame +! +! // finalize the HDLC frame +! inputHdlcClose(); +! +! if (openserial_vars.inputBufFill==0){ +! // invalid HDLC frame +! openserial_printError(COMPONENT_OPENSERIAL,ERR_INVALIDSERIALFRAME, +! (errorparameter_t)0, +! (errorparameter_t)0); +! +! } +! +! openserial_vars.busyReceiving = FALSE; +! openserial_stop(); +! } +! +! openserial_vars.lastRxByte = rxbyte; +! } +! +! +! //======== SERIAL ECHO ============= +! +! void openserial_echo(uint8_t* buf, uint8_t bufLen){ +! // echo back what you received +! openserial_printData( +! buf, +! bufLen +! ); +! } +--- 1,648 ---- +! /** +! \brief Definition of the "openserial" driver. +! +! \author Fabien Chraim , March 2012. +! */ +! +! #include "openwsn.h" +! #include "openserial.h" +! #include "IEEE802154E.h" +! #include "neighbors.h" +! #include "res.h" +! #include "icmpv6echo.h" +! #include "idmanager.h" +! #include "openqueue.h" +! #include "tcpinject.h" +! #include "udpinject.h" +! #include "openbridge.h" +! #include "leds.h" +! #include "schedule.h" +! #include "uart.h" +! #include "opentimers.h" +! #include "openhdlc.h" +! +! //=========================== variables ======================================= +! +! openserial_vars_t openserial_vars; +! +! //=========================== prototypes ====================================== +! +! owerror_t openserial_printInfoErrorCritical( +! char severity, +! uint8_t calling_component, +! uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2 +! ); +! // HDLC output +! void outputHdlcOpen(void); +! void outputHdlcWrite(uint8_t b); +! void outputHdlcClose(void); +! // HDLC input +! void inputHdlcOpen(void); +! void inputHdlcWrite(uint8_t b); +! void inputHdlcClose(void); +! +! //=========================== public ========================================== +! +! void openserial_init(void) { +! // uint16_t crc; +! // +! // // reset variable +! // memset(&openserial_vars,0,sizeof(openserial_vars_t)); +! // +! // // admin +! // openserial_vars.mode = MODE_OFF; +! // openserial_vars.debugPrintCounter = 0; +! // +! // // input +! // openserial_vars.reqFrame[0] = HDLC_FLAG; +! // openserial_vars.reqFrame[1] = SERFRAME_MOTE2PC_REQUEST; +! // crc = HDLC_CRCINIT; +! // crc = crcIteration(crc,openserial_vars.reqFrame[1]); +! // crc = ~crc; +! // openserial_vars.reqFrame[2] = (crc>>0)&0xff; +! // openserial_vars.reqFrame[3] = (crc>>8)&0xff; +! // openserial_vars.reqFrame[4] = HDLC_FLAG; +! // openserial_vars.reqFrameIdx = 0; +! // openserial_vars.lastRxByte = HDLC_FLAG; +! // openserial_vars.busyReceiving = FALSE; +! // openserial_vars.inputEscaping = FALSE; +! // openserial_vars.inputBufFill = 0; +! // +! // // ouput +! // openserial_vars.outputBufFilled = FALSE; +! // openserial_vars.outputBufIdxR = 0; +! // openserial_vars.outputBufIdxW = 0; +! // +! // // set callbacks +! // uart_setCallbacks(isr_openserial_tx, +! // isr_openserial_rx); +! } +! +! owerror_t openserial_printStatus(uint8_t statusElement,uint8_t* buffer, uint8_t length) { +! // uint8_t i; +! // INTERRUPT_DECLARATION(); +! // +! // DISABLE_INTERRUPTS(); +! // openserial_vars.outputBufFilled = TRUE; +! // outputHdlcOpen(); +! // outputHdlcWrite(SERFRAME_MOTE2PC_STATUS); +! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); +! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); +! // outputHdlcWrite(statusElement); +! // for (i=0;iaddr_16b[0]); +! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); +! // outputHdlcWrite(calling_component); +! // outputHdlcWrite(error_code); +! // outputHdlcWrite((uint8_t)((arg1 & 0xff00)>>8)); +! // outputHdlcWrite((uint8_t) (arg1 & 0x00ff)); +! // outputHdlcWrite((uint8_t)((arg2 & 0xff00)>>8)); +! // outputHdlcWrite((uint8_t) (arg2 & 0x00ff)); +! // outputHdlcClose(); +! // ENABLE_INTERRUPTS(); +! +! return E_SUCCESS; +! } +! +! owerror_t openserial_printData(uint8_t* buffer, uint8_t length) { +! (void)length; +! puts(buffer); +! // uint8_t i; +! // uint8_t asn[5]; +! // INTERRUPT_DECLARATION(); +! // +! // // retrieve ASN +! // ieee154e_getAsn(asn);// byte01,byte23,byte4 +! // +! // DISABLE_INTERRUPTS(); +! // openserial_vars.outputBufFilled = TRUE; +! // outputHdlcOpen(); +! // outputHdlcWrite(SERFRAME_MOTE2PC_DATA); +! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); +! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); +! // outputHdlcWrite(asn[0]); +! // outputHdlcWrite(asn[1]); +! // outputHdlcWrite(asn[2]); +! // outputHdlcWrite(asn[3]); +! // outputHdlcWrite(asn[4]); +! // for (i=0;i0) { +! // openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUTBUFFER_LENGTH, +! // (errorparameter_t)openserial_vars.inputBufFill, +! // (errorparameter_t)0); +! // DISABLE_INTERRUPTS(); +! // openserial_vars.inputBufFill=0; +! // ENABLE_INTERRUPTS(); +! // } +! // +! // uart_clearTxInterrupts(); +! // uart_clearRxInterrupts(); // clear possible pending interrupts +! // uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt +! // +! // DISABLE_INTERRUPTS(); +! // openserial_vars.busyReceiving = FALSE; +! // openserial_vars.mode = MODE_INPUT; +! // openserial_vars.reqFrameIdx = 0; +! // #ifdef FASTSIM +! // uart_writeBufferByLen_FASTSIM( +! // openserial_vars.reqFrame, +! // sizeof(openserial_vars.reqFrame) +! // ); +! // openserial_vars.reqFrameIdx = sizeof(openserial_vars.reqFrame); +! // #else +! // uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]); +! // #endif +! // ENABLE_INTERRUPTS(); +! } +! +! void openserial_startOutput(void) { +! // //schedule a task to get new status in the output buffer +! // uint8_t debugPrintCounter; +! // +! // INTERRUPT_DECLARATION(); +! // DISABLE_INTERRUPTS(); +! // openserial_vars.debugPrintCounter = (openserial_vars.debugPrintCounter+1)%STATUS_MAX; +! // debugPrintCounter = openserial_vars.debugPrintCounter; +! // ENABLE_INTERRUPTS(); +! // +! // // print debug information +! // switch (debugPrintCounter) { +! // case STATUS_ISSYNC: +! // if (debugPrint_isSync()==TRUE) { +! // break; +! // } +! // case STATUS_ID: +! // if (debugPrint_id()==TRUE) { +! // break; +! // } +! // case STATUS_DAGRANK: +! // if (debugPrint_myDAGrank()==TRUE) { +! // break; +! // } +! // case STATUS_OUTBUFFERINDEXES: +! // if (debugPrint_outBufferIndexes()==TRUE) { +! // break; +! // } +! // case STATUS_ASN: +! // if (debugPrint_asn()==TRUE) { +! // break; +! // } +! // case STATUS_MACSTATS: +! // if (debugPrint_macStats()==TRUE) { +! // break; +! // } +! // case STATUS_SCHEDULE: +! // if(debugPrint_schedule()==TRUE) { +! // break; +! // } +! // case STATUS_BACKOFF: +! // if(debugPrint_backoff()==TRUE) { +! // break; +! // } +! // case STATUS_QUEUE: +! // if(debugPrint_queue()==TRUE) { +! // break; +! // } +! // case STATUS_NEIGHBORS: +! // if (debugPrint_neighbors()==TRUE) { +! // break; +! // } +! // default: +! // DISABLE_INTERRUPTS(); +! // openserial_vars.debugPrintCounter=0; +! // ENABLE_INTERRUPTS(); +! // } +! // +! // // flush buffer +! // uart_clearTxInterrupts(); +! // uart_clearRxInterrupts(); // clear possible pending interrupts +! // uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt +! // DISABLE_INTERRUPTS(); +! // openserial_vars.mode=MODE_OUTPUT; +! // if (openserial_vars.outputBufFilled) { +! // #ifdef FASTSIM +! // uart_writeCircularBuffer_FASTSIM( +! // openserial_vars.outputBuf, +! // &openserial_vars.outputBufIdxR, +! // &openserial_vars.outputBufIdxW +! // ); +! // #else +! // uart_writeByte(openserial_vars.outputBuf[openserial_vars.outputBufIdxR++]); +! // #endif +! // } else { +! // openserial_stop(); +! // } +! // ENABLE_INTERRUPTS(); +! } +! +! void openserial_stop(void) { +! // uint8_t inputBufFill; +! // uint8_t cmdByte; +! // bool busyReceiving; +! // INTERRUPT_DECLARATION(); +! // +! // DISABLE_INTERRUPTS(); +! // busyReceiving = openserial_vars.busyReceiving; +! // inputBufFill = openserial_vars.inputBufFill; +! // ENABLE_INTERRUPTS(); +! // +! // // disable USCI_A1 TX & RX interrupt +! // uart_disableInterrupts(); +! // +! // DISABLE_INTERRUPTS(); +! // openserial_vars.mode=MODE_OFF; +! // ENABLE_INTERRUPTS(); +! // //the inputBuffer has to be reset if it is not reset where the data is read. +! // //or the function openserial_getInputBuffer is called (which resets the buffer) +! // if (busyReceiving==TRUE){ +! // openserial_printError(COMPONENT_OPENSERIAL,ERR_BUSY_RECEIVING, +! // (errorparameter_t)0, +! // (errorparameter_t)inputBufFill); +! // } +! // +! // if (busyReceiving == FALSE && inputBufFill>0) { +! // DISABLE_INTERRUPTS(); +! // cmdByte = openserial_vars.inputBuf[0]; +! // ENABLE_INTERRUPTS(); +! // switch (cmdByte) { +! // case SERFRAME_PC2MOTE_SETROOT: +! // idmanager_triggerAboutRoot(); +! // break; +! // case SERFRAME_PC2MOTE_SETBRIDGE: +! // idmanager_triggerAboutBridge(); +! // break; +! // case SERFRAME_PC2MOTE_DATA: +! // openbridge_triggerData(); +! // break; +! // case SERFRAME_PC2MOTE_TRIGGERTCPINJECT: +! // tcpinject_trigger(); +! // break; +! // case SERFRAME_PC2MOTE_TRIGGERUDPINJECT: +! // udpinject_trigger(); +! // break; +! // case SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO: +! // icmpv6echo_trigger(); +! // break; +! // case SERFRAME_PC2MOTE_TRIGGERSERIALECHO: +! // //echo function must reset input buffer after reading the data. +! // openserial_echo(&openserial_vars.inputBuf[1],inputBufFill-1); +! // break; +! // default: +! // openserial_printError(COMPONENT_OPENSERIAL,ERR_UNSUPPORTED_COMMAND, +! // (errorparameter_t)cmdByte, +! // (errorparameter_t)0); +! // //reset here as it is not being reset in any other callback +! // DISABLE_INTERRUPTS(); +! // openserial_vars.inputBufFill = 0; +! // ENABLE_INTERRUPTS(); +! // break; +! // } +! // } +! // +! // DISABLE_INTERRUPTS(); +! // openserial_vars.inputBufFill = 0; +! // openserial_vars.busyReceiving = FALSE; +! // ENABLE_INTERRUPTS(); +! } +! +! /** +! \brief Trigger this module to print status information, over serial. +! +! debugPrint_* functions are used by the openserial module to continuously print +! status information about several modules in the OpenWSN stack. +! +! \returns TRUE if this function printed something, FALSE otherwise. +! */ +! bool debugPrint_outBufferIndexes(void) { +! // uint16_t temp_buffer[2]; +! // INTERRUPT_DECLARATION(); +! // DISABLE_INTERRUPTS(); +! // temp_buffer[0] = openserial_vars.outputBufIdxW; +! // temp_buffer[1] = openserial_vars.outputBufIdxR; +! // ENABLE_INTERRUPTS(); +! // openserial_printStatus(STATUS_OUTBUFFERINDEXES,(uint8_t*)temp_buffer,sizeof(temp_buffer)); +! return TRUE; +! } +! +! //=========================== private ========================================= +! +! //===== hdlc (output) +! +! /** +! \brief Start an HDLC frame in the output buffer. +! */ +! // inline void outputHdlcOpen(void) { +! // // initialize the value of the CRC +! // openserial_vars.outputCrc = HDLC_CRCINIT; +! // +! // // write the opening HDLC flag +! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; +! // } +! /** +! \brief Add a byte to the outgoing HDLC frame being built. +! */ +! // inline void outputHdlcWrite(uint8_t b) { +! // +! // // iterate through CRC calculator +! // openserial_vars.outputCrc = crcIteration(openserial_vars.outputCrc,b); +! // +! // // add byte to buffer +! // if (b==HDLC_FLAG || b==HDLC_ESCAPE) { +! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_ESCAPE; +! // b = b^HDLC_ESCAPE_MASK; +! // } +! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = b; +! // +! // } +! /** +! \brief Finalize the outgoing HDLC frame. +! */ +! // inline void outputHdlcClose(void) { +! // uint16_t finalCrc; +! // +! // // finalize the calculation of the CRC +! // finalCrc = ~openserial_vars.outputCrc; +! // +! // // write the CRC value +! // outputHdlcWrite((finalCrc>>0)&0xff); +! // outputHdlcWrite((finalCrc>>8)&0xff); +! // +! // // write the closing HDLC flag +! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; +! // } +! +! //===== hdlc (input) +! +! /** +! \brief Start an HDLC frame in the input buffer. +! */ +! // inline void inputHdlcOpen(void) { +! // // reset the input buffer index +! // openserial_vars.inputBufFill = 0; +! // +! // // initialize the value of the CRC +! // openserial_vars.inputCrc = HDLC_CRCINIT; +! // } +! /** +! \brief Add a byte to the incoming HDLC frame. +! */ +! // inline void inputHdlcWrite(uint8_t b) { +! // if (b==HDLC_ESCAPE) { +! // openserial_vars.inputEscaping = TRUE; +! // } else { +! // if (openserial_vars.inputEscaping==TRUE) { +! // b = b^HDLC_ESCAPE_MASK; +! // openserial_vars.inputEscaping = FALSE; +! // } +! // +! // // add byte to input buffer +! // openserial_vars.inputBuf[openserial_vars.inputBufFill] = b; +! // openserial_vars.inputBufFill++; +! // +! // // iterate through CRC calculator +! // openserial_vars.inputCrc = crcIteration(openserial_vars.inputCrc,b); +! // } +! // } +! /** +! \brief Finalize the incoming HDLC frame. +! */ +! // inline void inputHdlcClose(void) { +! // +! // // verify the validity of the frame +! // if (openserial_vars.inputCrc==HDLC_CRCGOOD) { +! // // the CRC is correct +! // +! // // remove the CRC from the input buffer +! // openserial_vars.inputBufFill -= 2; +! // } else { +! // // the CRC is incorrect +! // +! // // drop the incoming fram +! // openserial_vars.inputBufFill = 0; +! // } +! // } +! +! //=========================== interrupt handlers ============================== +! +! // executed in ISR, called from scheduler.c +! // void isr_openserial_tx(void) { +! // switch (openserial_vars.mode) { +! // case MODE_INPUT: +! // openserial_vars.reqFrameIdx++; +! // if (openserial_vars.reqFrameIdxSERIAL_INPUT_BUFFER_SIZE){ +! // // input buffer overflow +! // openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUT_BUFFER_OVERFLOW, +! // (errorparameter_t)0, +! // (errorparameter_t)0); +! // openserial_vars.inputBufFill = 0; +! // openserial_vars.busyReceiving = FALSE; +! // openserial_stop(); +! // } +! // } else if ( +! // openserial_vars.busyReceiving==TRUE && +! // rxbyte==HDLC_FLAG +! // ) { +! // // end of frame +! // +! // // finalize the HDLC frame +! // inputHdlcClose(); +! // +! // if (openserial_vars.inputBufFill==0){ +! // // invalid HDLC frame +! // openserial_printError(COMPONENT_OPENSERIAL,ERR_WRONG_CRC_INPUT, +! // (errorparameter_t)inputBufFill, +! // (errorparameter_t)0); +! // +! // } +! // +! // openserial_vars.busyReceiving = FALSE; +! // openserial_stop(); +! // } +! // +! // openserial_vars.lastRxByte = rxbyte; +! // } +! +! //======== SERIAL ECHO ============= +! +! void openserial_echo(uint8_t* buf, uint8_t bufLen){ +! INTERRUPT_DECLARATION(); +! // echo back what you received +! openserial_printData( +! buf, +! bufLen +! ); +! +! DISABLE_INTERRUPTS(); +! openserial_vars.inputBufFill = 0; +! ENABLE_INTERRUPTS(); +! } +diff -crB openwsn/openserial.h ../../../sys/net/openwsn/openserial.h +*** openwsn/openserial.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/openserial.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,94 **** +! /** +! \brief Declaration of the "openserial" driver. +! +! \author Fabien Chraim , March 2012. +! */ +! +! #ifndef __OPENSERIAL_H +! #define __OPENSERIAL_H +! +! #include "openwsn.h" +! +! /** +! \addtogroup cross-layers +! \{ +! \addtogroup OpenSerial +! \{ +! */ +! +! //=========================== define ========================================== +! +! /** +! \brief Number of bytes of the serial output buffer, in bytes. +! +! \warning should be exactly 256 so wrap-around on the index does not require +! the use of a slow modulo operator. +! */ +! #define SERIAL_OUTPUT_BUFFER_SIZE 256 // leave at 256! +! +! /** +! \brief Number of bytes of the serial input buffer, in bytes. +! +! \warning Do not pick a number greater than 255, since its filling level is +! encoded by a single byte in the code. +! */ +! #define SERIAL_INPUT_BUFFER_SIZE 200 +! +! /// Modes of the openserial module. +! enum { +! MODE_OFF = 0, ///< The module is off, no serial activity. +! MODE_INPUT = 1, ///< The serial is listening or receiving bytes. +! MODE_OUTPUT = 2 ///< The serial is transmitting bytes. +! }; +! +! // frames sent mote->PC +! #define SERFRAME_MOTE2PC_DATA ((uint8_t)'D') +! #define SERFRAME_MOTE2PC_STATUS ((uint8_t)'S') +! #define SERFRAME_MOTE2PC_INFO ((uint8_t)'I') +! #define SERFRAME_MOTE2PC_ERROR ((uint8_t)'E') +! #define SERFRAME_MOTE2PC_CRITICAL ((uint8_t)'C') +! #define SERFRAME_MOTE2PC_REQUEST ((uint8_t)'R') +! +! // frames sent PC->mote +! #define SERFRAME_PC2MOTE_SETROOT ((uint8_t)'R') +! #define SERFRAME_PC2MOTE_SETBRIDGE ((uint8_t)'B') +! #define SERFRAME_PC2MOTE_DATA ((uint8_t)'D') +! #define SERFRAME_PC2MOTE_TRIGGERTCPINJECT ((uint8_t)'T') +! #define SERFRAME_PC2MOTE_TRIGGERUDPINJECT ((uint8_t)'U') +! #define SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO ((uint8_t)'E') +! #define SERFRAME_PC2MOTE_TRIGGERSERIALECHO ((uint8_t)'S') +! +! //=========================== typedef ========================================= +! +! //=========================== prototypes ====================================== +! +! void openserial_init(); +! error_t openserial_printStatus(uint8_t statusElement, uint8_t* buffer, uint16_t length); +! error_t openserial_printInfo(uint8_t calling_component, uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2); +! error_t openserial_printError(uint8_t calling_component, uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2); +! error_t openserial_printCritical(uint8_t calling_component, uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2); +! error_t openserial_printData(uint8_t* buffer, uint8_t length); +! uint8_t openserial_getNumDataBytes(); +! uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes); +! void openserial_startInput(); +! void openserial_startOutput(); +! void openserial_stop(); +! bool debugPrint_outBufferIndexes(); +! void openserial_echo(uint8_t* but, uint8_t bufLen); +! +! // interrupt handlers +! void isr_openserial_rx(); +! void isr_openserial_tx(); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +--- 1,117 ---- +! /** +! \brief Declaration of the "openserial" driver. +! +! \author Fabien Chraim , March 2012. +! */ +! +! #ifndef __OPENSERIAL_H +! #define __OPENSERIAL_H +! +! #include "openwsn.h" +! +! /** +! \addtogroup drivers +! \{ +! \addtogroup OpenSerial +! \{ +! */ +! +! //=========================== define ========================================== +! +! /** +! \brief Number of bytes of the serial output buffer, in bytes. +! +! \warning should be exactly 256 so wrap-around on the index does not require +! the use of a slow modulo operator. +! */ +! #define SERIAL_OUTPUT_BUFFER_SIZE 256 // leave at 256! +! +! /** +! \brief Number of bytes of the serial input buffer, in bytes. +! +! \warning Do not pick a number greater than 255, since its filling level is +! encoded by a single byte in the code. +! */ +! #define SERIAL_INPUT_BUFFER_SIZE 200 +! +! /// Modes of the openserial module. +! enum { +! MODE_OFF = 0, ///< The module is off, no serial activity. +! MODE_INPUT = 1, ///< The serial is listening or receiving bytes. +! MODE_OUTPUT = 2 ///< The serial is transmitting bytes. +! }; +! +! // frames sent mote->PC +! #define SERFRAME_MOTE2PC_DATA ((uint8_t)'D') +! #define SERFRAME_MOTE2PC_STATUS ((uint8_t)'S') +! #define SERFRAME_MOTE2PC_INFO ((uint8_t)'I') +! #define SERFRAME_MOTE2PC_ERROR ((uint8_t)'E') +! #define SERFRAME_MOTE2PC_CRITICAL ((uint8_t)'C') +! #define SERFRAME_MOTE2PC_REQUEST ((uint8_t)'R') +! +! // frames sent PC->mote +! #define SERFRAME_PC2MOTE_SETROOT ((uint8_t)'R') +! #define SERFRAME_PC2MOTE_SETBRIDGE ((uint8_t)'B') +! #define SERFRAME_PC2MOTE_DATA ((uint8_t)'D') +! #define SERFRAME_PC2MOTE_TRIGGERTCPINJECT ((uint8_t)'T') +! #define SERFRAME_PC2MOTE_TRIGGERUDPINJECT ((uint8_t)'U') +! #define SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO ((uint8_t)'E') +! #define SERFRAME_PC2MOTE_TRIGGERSERIALECHO ((uint8_t)'S') +! +! //=========================== typedef ========================================= +! +! //=========================== module variables ================================ +! +! typedef struct { +! // admin +! uint8_t mode; +! uint8_t debugPrintCounter; +! // input +! uint8_t reqFrame[1+1+2+1]; // flag (1B), command (2B), CRC (2B), flag (1B) +! uint8_t reqFrameIdx; +! uint8_t lastRxByte; +! bool busyReceiving; +! bool inputEscaping; +! uint16_t inputCrc; +! uint8_t inputBufFill; +! uint8_t inputBuf[SERIAL_INPUT_BUFFER_SIZE]; +! // output +! bool outputBufFilled; +! uint16_t outputCrc; +! uint8_t outputBufIdxW; +! uint8_t outputBufIdxR; +! uint8_t outputBuf[SERIAL_OUTPUT_BUFFER_SIZE]; +! } openserial_vars_t; +! +! //=========================== prototypes ====================================== +! +! void openserial_init(void); +! owerror_t openserial_printStatus(uint8_t statusElement, uint8_t* buffer, uint8_t length); +! owerror_t openserial_printInfo(uint8_t calling_component, uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2); +! owerror_t openserial_printError(uint8_t calling_component, uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2); +! owerror_t openserial_printCritical(uint8_t calling_component, uint8_t error_code, +! errorparameter_t arg1, +! errorparameter_t arg2); +! owerror_t openserial_printData(uint8_t* buffer, uint8_t length); +! uint8_t openserial_getNumDataBytes(void); +! uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes); +! void openserial_startInput(void); +! void openserial_startOutput(void); +! void openserial_stop(void); +! bool debugPrint_outBufferIndexes(void); +! void openserial_echo(uint8_t* but, uint8_t bufLen); +! +! // interrupt handlers +! void isr_openserial_rx(void); +! void isr_openserial_tx(void); +! +! /** +! \} +! \} +! */ +! + #endif +\ No newline at end of file +diff -crB openwsn/opentimers.c ../../../sys/net/openwsn/opentimers.c +*** openwsn/opentimers.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/opentimers.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,284 **** +! /** +! \brief Definition of the "opentimers" driver. +! +! This driver uses a single hardware timer, which it virtualizes to support +! at most MAX_NUM_TIMERS timers. +! +! \author Xavi Vilajosana , March 2012. +! */ +! +! #include "openwsn.h" +! #include "opentimers.h" +! #include "bsp_timer.h" +! #include "leds.h" +! +! //=========================== define ========================================== +! +! //=========================== variables ======================================= +! +! typedef struct { +! opentimers_t timersBuf[MAX_NUM_TIMERS]; +! bool running; +! PORT_TIMER_WIDTH currentTimeout; // current timeout, in ticks +! } opentimers_vars_t; +! +! opentimers_vars_t opentimers_vars; +! //uint32_t counter; //counts the elapsed time. +! +! //=========================== prototypes ====================================== +! +! void opentimers_timer_callback(); +! +! //=========================== public ========================================== +! +! /** +! \brief Initialize this module. +! +! Initializes data structures and hardware timer. +! */ +! void opentimers_init(){ +! uint8_t i; +! +! // initialize local variables +! opentimers_vars.running=FALSE; +! for (i=0;i= opentimers_vars.timersBuf[id].ticks_remaining) { +! // this timer has expired +! //check to see if we have completed the whole timer, or we're just wrapping around the max 16bit value +! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ +! // declare as so +! opentimers_vars.timersBuf[id].hasExpired = TRUE; +! }else{ +! opentimers_vars.timersBuf[id].wraps_remaining--; +! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ +! //if we have fully wrapped around, then set the remainring ticks to the modulus of the total ticks and the max clock value +! opentimers_vars.timersBuf[id].ticks_remaining = (opentimers_vars.timersBuf[id].period_ticks) % MAX_TICKS_IN_SINGLE_CLOCK; +! }else{ +! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK; +! } +! } +! } else { +! // this timer is not expired +! +! // update its counter +! opentimers_vars.timersBuf[id].ticks_remaining -= opentimers_vars.currentTimeout; +! } +! } +! } +! +! // step 2. call callbacks of expired timers +! for(id=0; id, March 2012. +! */ +! +! #include "openwsn.h" +! #include "opentimers.h" +! //#include "bsp_timer.h" +! #include "leds.h" +! +! #include "hwtimer_arch.h" +! #include "hwtimer_cpu.h" +! +! //=========================== define ========================================== +! +! //=========================== variables ======================================= +! +! opentimers_vars_t opentimers_vars; +! //uint32_t counter; //counts the elapsed time. +! +! //=========================== prototypes ====================================== +! +! void opentimers_int_handler(int); +! void opentimers_timer_callback(void); +! +! //=========================== public ========================================== +! +! /** +! \brief Initialize this module. +! +! Initializes data structures and hardware timer. +! */ +! void opentimers_init(void){ +! uint8_t i; +! +! // initialize local variables +! opentimers_vars.running=FALSE; +! for (i=0;iduration: +! - #TIME_MS when duration is in ms. +! - #TIME_TICS when duration is in clock ticks. +! \param callback The function to call when the timer fires. +! +! \returns The id of the timer (which serves as a handler to stop it) if the +! timer could be started. +! \returns TOO_MANY_TIMERS_ERROR if the timer could NOT be started. +! */ +! opentimer_id_t opentimers_start(uint32_t duration, timer_type_t type, time_type_t timetype, opentimers_cbt callback) { +! +! uint8_t id; +! +! // find an unused timer +! for (id=0; id= opentimers_vars.timersBuf[id].ticks_remaining) { +! // this timer has expired +! //check to see if we have completed the whole timer, or we're just wrapping around the max 16bit value +! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ +! // declare as so +! opentimers_vars.timersBuf[id].hasExpired = TRUE; +! }else{ +! opentimers_vars.timersBuf[id].wraps_remaining--; +! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ +! //if we have fully wrapped around, then set the remainring ticks to the modulus of the total ticks and the max clock value +! opentimers_vars.timersBuf[id].ticks_remaining = (opentimers_vars.timersBuf[id].period_ticks) % MAX_TICKS_IN_SINGLE_CLOCK; +! }else{ +! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK; +! } +! } +! } else { +! // this timer is not expired +! +! // update its counter +! opentimers_vars.timersBuf[id].ticks_remaining -= opentimers_vars.currentTimeout; +! } +! } +! } +! +! // step 2. call callbacks of expired timers +! for(id=0; id sleepTime) +! { +! opentimers_vars.timersBuf[id].ticks_remaining -= sleepTime; +! } +! else +! { +! if(opentimers_vars.timersBuf[id].wraps_remaining > 0) +! { +! opentimers_vars.timersBuf[id].wraps_remaining--; +! opentimers_vars.timersBuf[id].ticks_remaining += (MAX_TICKS_IN_SINGLE_CLOCK - sleepTime); +! } +! else +! { +! opentimers_vars.timersBuf[id].hasExpired = TRUE; +! } +! } +! } +! } +! +! // step 2. call callbacks of expired timers +! for(id=0; id, March 2012. +! */ +! +! #ifndef __OPENTIMERS_H +! #define __OPENTIMERS_H +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! /// Maximum number of timers that can run concurrently +! #define MAX_NUM_TIMERS 10 +! +! #define MAX_TICKS_IN_SINGLE_CLOCK ((PORT_TIMER_WIDTH)0xFFFFFFFF) +! +! #define TOO_MANY_TIMERS_ERROR 255 +! +! #define opentimer_id_t uint8_t +! +! typedef void (*opentimers_cbt)(void); +! +! //=========================== typedef ========================================= +! +! typedef enum { +! TIMER_PERIODIC, +! TIMER_ONESHOT, +! } timer_type_t; +! +! /*the time can be in tics or in ms*/ +! typedef enum { +! TIME_MS, +! TIME_TICS, +! } time_type_t; +! +! typedef struct { +! uint32_t period_ticks; // total number of clock ticks +! PORT_TIMER_WIDTH ticks_remaining; // ticks remaining before elapses +! uint16_t wraps_remaining; // the clock register is 16 bit, and can't count beyond 32k... +! // so period_ticks = wraps_remaining*(32k or uint16_t) +! timer_type_t type; // periodic or one-shot +! bool isrunning; // is running? +! opentimers_cbt callback; // function to call when elapses +! bool hasExpired; // whether the callback has to be called +! } opentimers_t; +! +! //=========================== prototypes ====================================== +! +! void opentimers_init(); +! opentimer_id_t opentimers_start(uint32_t duration, +! timer_type_t type, +! time_type_t timetype, +! opentimers_cbt callback); +! void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype, uint32_t newPeriod); +! void opentimers_stop(opentimer_id_t id); +! void opentimers_restart(opentimer_id_t id); +! +! #endif +--- 1,86 ---- +! /** +! \brief Declaration of the "opentimers" driver. +! +! \author Xavi Vilajosana , March 2012. +! */ +! +! #ifndef __OPENTIMERS_H +! #define __OPENTIMERS_H +! +! #include "openwsn.h" +! +! #include "hwtimer_cpu.h" +! +! /** +! \addtogroup drivers +! \{ +! \addtogroup OpenTimers +! \{ +! */ +! +! //=========================== define ========================================== +! +! /// Maximum number of timers that can run concurrently +! #define MAX_NUM_TIMERS 10 +! +! #define MAX_TICKS_IN_SINGLE_CLOCK ((PORT_TIMER_WIDTH)0xFFFFFFFF) +! +! #define TOO_MANY_TIMERS_ERROR 255 +! +! #define opentimer_id_t uint8_t +! +! typedef void (*opentimers_cbt)(void); +! +! #define OPENTIMERS_HWTIMER_ID (ARCH_MAXTIMERS - 1) +! +! //=========================== typedef ========================================= +! +! typedef enum { +! TIMER_PERIODIC, +! TIMER_ONESHOT, +! } timer_type_t; +! +! /*the time can be in tics or in ms*/ +! typedef enum { +! TIME_MS, +! TIME_TICS, +! } time_type_t; +! +! typedef struct { +! uint32_t period_ticks; // total number of clock ticks +! PORT_TIMER_WIDTH ticks_remaining; // ticks remaining before elapses +! uint16_t wraps_remaining; // the clock register is 16 bit, and can't count beyond 32k... +! // so period_ticks = wraps_remaining*(32k or uint16_t) +! timer_type_t type; // periodic or one-shot +! bool isrunning; // is running? +! opentimers_cbt callback; // function to call when elapses +! bool hasExpired; // whether the callback has to be called +! } opentimers_t; +! +! //=========================== module variables ================================ +! +! typedef struct { +! opentimers_t timersBuf[MAX_NUM_TIMERS]; +! bool running; +! PORT_TIMER_WIDTH currentTimeout; // current timeout, in ticks +! } opentimers_vars_t; +! +! //=========================== prototypes ====================================== +! +! void opentimers_init(void); +! opentimer_id_t opentimers_start(uint32_t duration, +! timer_type_t type, +! time_type_t timetype, +! opentimers_cbt callback); +! void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype, uint32_t newPeriod); +! void opentimers_stop(opentimer_id_t id); +! void opentimers_restart(opentimer_id_t id); +! +! void opentimers_sleepTimeCompesation(uint16_t sleepTime); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/openwsn.c ../../../sys/net/openwsn/openwsn.c +*** openwsn/openwsn.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/openwsn.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,134 **** +! /** +! \brief General OpenWSN definitions +! +! \author Thomas Watteyne , September 2012 +! */ +! +! #include "openwsn.h" +! //===== drivers +! #include "openserial.h" +! //===== stack +! //-- cross-layer +! #include "idmanager.h" +! #include "openqueue.h" +! #include "openrandom.h" +! #include "opentimers.h" +! //-- 02a-TSCH +! #include "IEEE802154E.h" +! //-- 02b-RES +! #include "schedule.h" +! #include "res.h" +! #include "neighbors.h" +! //-- 03a-IPHC +! #include "openbridge.h" +! #include "iphc.h" +! //-- 03b-IPv6 +! #include "forwarding.h" +! #include "icmpv6.h" +! #include "icmpv6echo.h" +! #include "icmpv6rpl.h" +! //-- 04-TRAN +! #include "opentcp.h" +! #include "openudp.h" +! #include "opencoap.h" +! //-- app (common) +! //#include "rreg.h" +! //#include "rwellknown.h" +! //#include "rinfo.h" +! //===== applications +! //-- TCP +! #include "tcpecho.h" +! #include "tcpinject.h" +! #include "tcpprint.h" +! #include "ohlone.h" +! //-- UDP +! #include "udpecho.h" +! #include "udpinject.h" +! #include "udpprint.h" +! //#include "udprand.h" +! //#include "udplatency.h" +! //#include "udpstorm.h" +! //-- CoAP +! //#include "rleds.h" +! //#include "rt.h" +! //#include "rex.h" +! //#include "rheli.h" +! //#include "rrube.h" +! //#include "rxl1.h" +! //#include "layerdebug.h" +! //-- misc +! //#include "heli.h" +! //#include "imu.h" +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openwsn_init(); +! +! //=========================== public ========================================== +! +! //=========================== private ========================================= +! +! void openwsn_init() { +! //===== drivers +! openserial_init(); +! +! //===== stack +! //-- cross-layer +! idmanager_init(); // call first since initializes EUI64 and isDAGroot +! openqueue_init(); +! openrandom_init(); +! opentimers_init(); +! //-- 02a-TSCH +! ieee154e_init(); +! //-- 02b-RES +! schedule_init(); +! res_init(); +! neighbors_init(); +! //-- 03a-IPHC +! openbridge_init(); +! iphc_init(); +! //-- 03b-IPv6 +! forwarding_init(); +! icmpv6_init(); +! icmpv6echo_init(); +! icmpv6rpl_init(); +! //-- 04-TRAN +! opentcp_init(); +! openudp_init(); +! opencoap_init(); // initialize before any of the CoAP applications +! //-- app (common) +! //rreg_init(); +! //rwellknown_init(); +! //rinfo_init(); +! +! //===== applications +! //-- TCP +! tcpecho_init(); +! tcpinject_init(); +! tcpprint_init(); +! ohlone_init(); +! //-- UDP +! udpecho_init(); +! udpinject_init(); +! udpprint_init(); +! //udprand_init(); +! //udplatency_init(); +! //udpstorm_init(); +! //-- CoAP +! //rleds_init(); +! //rt_init(); +! //rex_init(); +! //rheli_init(); +! //rrube_init(); +! //rxl1_init(); +! //layerdebug_init(); +! //-- misc +! //heli_init(); +! //imu_init(); +! +! openserial_printInfo(COMPONENT_OPENWSN,ERR_BOOTED, +! (errorparameter_t)0, +! (errorparameter_t)0); + } +\ No newline at end of file +--- 1,158 ---- +! /** +! \brief General OpenWSN definitions +! +! \author Thomas Watteyne , September 2012 +! */ +! +! #include "openwsn.h" +! #include "scheduler.h" +! #include "thread.h" +! #include "board_ow.h" +! //===== drivers +! #include "openserial.h" +! //===== stack +! //-- cross-layer +! #include "idmanager.h" +! #include "openqueue.h" +! #include "openrandom.h" +! #include "opentimers.h" +! //-- 02a-TSCH +! #include "IEEE802154E.h" +! //-- 02b-RES +! #include "schedule.h" +! #include "res.h" +! #include "neighbors.h" +! //-- 03a-IPHC +! #include "openbridge.h" +! #include "iphc.h" +! //-- 03b-IPv6 +! #include "forwarding.h" +! #include "icmpv6.h" +! #include "icmpv6echo.h" +! #include "icmpv6rpl.h" +! //-- 04-TRAN +! #include "opentcp.h" +! #include "openudp.h" +! #include "opencoap.h" +! //-- app (common) +! //#include "rreg.h" +! #include "rwellknown.h" +! #include "rinfo.h" +! //===== applications +! //-- TCP +! //#include "tcpecho.h" +! //#include "tcpinject.h" +! //#include "tcpprint.h" +! #include "ohlone.h" +! //-- UDP +! #include "udpecho.h" +! #include "udpinject.h" +! #include "udpprint.h" +! //#include "udprand.h" +! //#include "udplatency.h" +! //#include "udpstorm.h" +! //-- CoAP +! //#include "rleds.h" +! //#include "rt.h" +! //#include "rex.h" +! //#include "rheli.h" +! //#include "rrube.h" +! //#include "rxl1.h" +! //#include "layerdebug.h" +! //#include "r6tus.h" +! //-- misc +! //#include "heli.h" +! //#include "imu.h" +! +! //=========================== variables ======================================= +! +! static char openwsn_stack[KERNEL_CONF_STACKSIZE_MAIN]; +! +! //=========================== prototypes ====================================== +! +! void openwsn_init(void); +! void openwsn_start(void); +! +! //=========================== public ========================================== +! +! void openwsn_start_thread(void) { +! puts(__PRETTY_FUNCTION__); +! thread_create(openwsn_stack, KERNEL_CONF_STACKSIZE_MAIN, +! PRIORITY_OPENWSN, CREATE_STACKTEST, +! openwsn_start, "openwsn thread"); +! } +! +! void openwsn_start(void) { +! puts(__PRETTY_FUNCTION__); +! //board_init_ow(); +! scheduler_init(); +! openwsn_init(); +! scheduler_start(); +! } +! +! //=========================== private ========================================= +! +! void openwsn_init(void) { +! puts(__PRETTY_FUNCTION__); +! //===== drivers +! openserial_init(); +! +! //===== stack +! //-- cross-layer +! idmanager_init(); // call first since initializes EUI64 and isDAGroot +! openqueue_init(); +! openrandom_init(); +! opentimers_init(); +! //-- 02a-TSCH +! ieee154e_init(); +! //-- 02b-RES +! schedule_init(); +! res_init(); +! neighbors_init(); +! //-- 03a-IPHC +! openbridge_init(); +! iphc_init(); +! //-- 03b-IPv6 +! forwarding_init(); +! icmpv6_init(); +! icmpv6echo_init(); +! icmpv6rpl_init(); +! //-- 04-TRAN +! opentcp_init(); +! openudp_init(); +! opencoap_init(); // initialize before any of the CoAP applications +! //-- app (common) +! //rreg_init(); +! rwellknown_init(); +! rinfo_init(); +! +! //===== applications +! //-- TCP +! //tcpecho_init(); +! //tcpinject_init(); +! //tcpprint_init(); +! //ohlone_init(); +! //-- UDP +! udpecho_init(); +! udpinject_init(); +! udpprint_init(); +! //udprand_init(); +! //udplatency_init(); +! //udpstorm_init(); +! //-- CoAP +! //rleds_init(); +! //rt_init(); +! //rex_init(); +! //rheli_init(); +! //rrube_init(); +! //rxl1_init(); +! //layerdebug_init(); +! //r6tus_init(); +! //-- misc +! //heli_init(); +! //imu_init(); +! +! openserial_printInfo(COMPONENT_OPENWSN,ERR_BOOTED, +! (errorparameter_t)0, +! (errorparameter_t)0); + } +\ No newline at end of file +diff -crB openwsn/openwsn.h ../../../sys/net/openwsn/openwsn.h +*** openwsn/openwsn.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/openwsn.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,314 **** +! /** +! \brief General OpenWSN definitions +! +! \author Thomas Watteyne , August 2010 +! \author Ankur Mehta , September 2010 +! */ +! +! #ifndef __OPENWSN_H +! #define __OPENWSN_H +! +! //general +! #include // needed for uin8_t, uint16_t +! #include "board_info.h" +! +! //=========================== define ========================================== +! +! static const uint8_t infoStackName[] = "OpenWSN "; +! #define OPENWSN_VERSION_MAJOR 1 +! #define OPENWSN_VERSION_MINOR 2 +! #define OPENWSN_VERSION_PATCH 1 +! +! // enter the last byte of your mote's address if you want it to be an LBR +! #define DEBUG_MOTEID_MASTER 0xe8 +! +! #ifndef TRUE +! #define TRUE 1 +! #endif +! +! #ifndef FALSE +! #define FALSE 0 +! #endif +! +! #define LENGTH_ADDR16b 2 +! #define LENGTH_ADDR64b 8 +! #define LENGTH_ADDR128b 16 +! +! enum { +! E_SUCCESS = 0, +! E_FAIL = 1, +! }; +! +! // types of addresses +! enum { +! ADDR_NONE = 0, +! ADDR_16B = 1, +! ADDR_64B = 2, +! ADDR_128B = 3, +! ADDR_PANID = 4, +! ADDR_PREFIX = 5, +! ADDR_ANYCAST = 6, +! }; +! +! enum { +! LITTLE_ENDIAN = TRUE, +! BIG_ENDIAN = FALSE, +! }; +! +! // protocol numbers, as defined by the IANA +! enum { +! IANA_UNDEFINED = 0x00, +! IANA_TCP = 0x06, +! IANA_UDP = 0x11, +! IANA_IPv6ROUTE = 43, +! IANA_ICMPv6 = 0x3a, +! IANA_ICMPv6_ECHO_REQUEST = 128, +! IANA_ICMPv6_ECHO_REPLY = 129, +! IANA_ICMPv6_RS = 133, +! IANA_ICMPv6_RA = 134, +! IANA_ICMPv6_RA_PREFIX_INFORMATION = 3, +! IANA_ICMPv6_RPL = 155, +! IANA_ICMPv6_RPL_DIO = 0x01, +! IANA_ICMPv6_RPL_DAO = 0x04, +! IANA_RSVP = 46, +! }; +! +! // well known ports (which we define) +! enum { +! //TCP +! WKP_TCP_HTTP = 80, +! WKP_TCP_ECHO = 7, +! WKP_TCP_INJECT = 2188, +! WKP_TCP_DISCARD = 9, +! //UDP +! WKP_UDP_COAP = 5683, +! WKP_UDP_HELI = 2192, +! WKP_UDP_IMU = 2190, +! WKP_UDP_ECHO = 7, +! WKP_UDP_INJECT = 2188, +! WKP_UDP_DISCARD = 9, +! WKP_UDP_RAND = 61000, +! WKP_UDP_LATENCY = 61001, +! }; +! +! //status elements +! enum { +! STATUS_ISSYNC = 0, +! STATUS_ID = 1, +! STATUS_DAGRANK = 2, +! STATUS_OUTBUFFERINDEXES = 3, +! STATUS_ASN = 4, +! STATUS_MACSTATS = 5, +! STATUS_SCHEDULE = 6, +! STATUS_BACKOFF = 7, +! STATUS_QUEUE = 8, +! STATUS_NEIGHBORS = 9, +! STATUS_MAX = 10, +! }; +! +! //component identifiers +! //the order is important because +! enum { +! COMPONENT_NULL = 0x00, +! COMPONENT_OPENWSN = 0x01, +! //cross-layers +! COMPONENT_IDMANAGER = 0x02, +! COMPONENT_OPENQUEUE = 0x03, +! COMPONENT_OPENSERIAL = 0x04, +! COMPONENT_PACKETFUNCTIONS = 0x05, +! COMPONENT_RANDOM = 0x06, +! //PHY +! COMPONENT_RADIO = 0x07, +! //MAClow +! COMPONENT_IEEE802154 = 0x08, +! COMPONENT_IEEE802154E = 0x09, +! +! //All components with higher component id than COMPONENT_IEEE802154E +! //won't be able to get free packets from the queue +! //when the mote is not synch +! +! //MAClow<->MAChigh ("virtual components") +! COMPONENT_RES_TO_IEEE802154E = 0x0a, +! COMPONENT_IEEE802154E_TO_RES = 0x0b, +! //MAChigh +! COMPONENT_RES = 0x0c, +! COMPONENT_NEIGHBORS = 0x0d, +! COMPONENT_SCHEDULE = 0x0e, +! //IPHC +! COMPONENT_OPENBRIDGE = 0x0f, +! COMPONENT_IPHC = 0x10, +! //IPv6 +! COMPONENT_FORWARDING = 0x11, +! COMPONENT_ICMPv6 = 0x12, +! COMPONENT_ICMPv6ECHO = 0x13, +! COMPONENT_ICMPv6ROUTER = 0x14, +! COMPONENT_ICMPv6RPL = 0x15, +! //TRAN +! COMPONENT_OPENTCP = 0x16, +! COMPONENT_OPENUDP = 0x17, +! COMPONENT_OPENCOAP = 0x18, +! //App test +! COMPONENT_TCPECHO = 0x19, +! COMPONENT_TCPINJECT = 0x1a, +! COMPONENT_TCPPRINT = 0x1b, +! COMPONENT_UDPECHO = 0x1c, +! COMPONENT_UDPINJECT = 0x1d, +! COMPONENT_UDPPRINT = 0x1e, +! COMPONENT_RSVP = 0x1f, +! //App +! COMPONENT_OHLONE = 0x20, +! COMPONENT_HELI = 0x21, +! COMPONENT_IMU = 0x22, +! COMPONENT_RLEDS = 0x23, +! COMPONENT_RREG = 0x24, +! COMPONENT_RWELLKNOWN = 0x25, +! COMPONENT_RT = 0x26, +! COMPONENT_REX = 0x27, +! COMPONENT_RXL1 = 0x28, +! COMPONENT_RINFO = 0x29, +! COMPONENT_RHELI = 0x2a, +! COMPONENT_RRUBE = 0x2b, +! COMPONENT_LAYERDEBUG = 0x2c, +! COMPONENT_UDPRAND = 0x2d, +! COMPONENT_UDPSTORM = 0x2e, +! COMPONENT_UDPLATENCY = 0x2f, +! COMPONENT_TEST = 0x30, +! }; +! +! /** +! \brief error codes used throughout the OpenWSN stack +! +! \note The comments are used in the Python parsing tool: +! - {0} refers to the value of the first argument, +! - {1} refers to the value of the second argument, +! */ +! enum { +! // l7 +! ERR_RCVD_ECHO_REQUEST = 0x01, // received an echo request +! ERR_RCVD_ECHO_REPLY = 0x02, // received an echo reply +! ERR_GETDATA_ASKS_TOO_FEW_BYTES = 0x03, // getData asks for too few bytes, maxNumBytes={0}, fill level={1} +! ERR_INPUT_BUFFER_OVERFLOW = 0x04, // the input buffer has overflown +! // l4 +! ERR_WRONG_TRAN_PROTOCOL = 0x05, // unknown transport protocol {0} (code location {1}) +! ERR_WRONG_TCP_STATE = 0x06, // wrong TCP state {0} (code location {1}) +! ERR_TCP_RESET = 0x07, // TCP reset while in state {0} (code location {1}) +! ERR_UNSUPPORTED_PORT_NUMBER = 0x08, // unsupported port number {0} (code location {1}) +! // l3 +! ERR_UNEXPECTED_DAO = 0x09, // unexpected DAO (code location {0}) +! ERR_UNSUPPORTED_ICMPV6_TYPE = 0x0a, // unsupported ICMPv6 type {0} (code location {1}) +! ERR_6LOWPAN_UNSUPPORTED = 0x0b, // unsupported 6LoWPAN parameter {1} at location {0} +! ERR_NO_NEXTHOP = 0x0c, // no next hop +! ERR_INVALID_PARAM = 0x0d, // invalid parameter +! ERR_INVALID_FWDMODE = 0x0e, // invalid forward mode +! ERR_LARGE_DAGRANK = 0x0f, // large DAGrank {0}, set to {1} +! ERR_HOP_LIMIT_REACHED = 0x10, // packet discarded hop limit reached +! // l2b +! ERR_NEIGHBORS_FULL = 0x11, // neighbors table is full (max number of neighbor is {0}) +! ERR_NO_SENT_PACKET = 0x12, // there is no sent packet in queue +! ERR_NO_RECEIVED_PACKET = 0x13, // there is no received packet in queue +! ERR_SCHEDULE_OVERFLOWN = 0x14, // schedule overflown +! // l2a +! ERR_WRONG_CELLTYPE = 0x15, // wrong celltype {0} at slotOffset {1} +! ERR_IEEE154_UNSUPPORTED = 0x16, // unsupported IEEE802.15.4 parameter {1} at location {0} +! ERR_DESYNCHRONIZED = 0x17, // got desynchronized at slotOffset {0} +! ERR_SYNCHRONIZED = 0x18, // synchronized at slotOffset {0} +! ERR_LARGE_TIMECORRECTION = 0x19, // large timeCorr.: {0} ticks (code loc. {1}) +! ERR_WRONG_STATE_IN_ENDFRAME_SYNC = 0x1a, // wrong state {0} in end of frame+sync +! ERR_WRONG_STATE_IN_STARTSLOT = 0x1b, // wrong state {0} in startSlot, at slotOffset {1} +! ERR_WRONG_STATE_IN_TIMERFIRES = 0x1c, // wrong state {0} in timer fires, at slotOffset {1} +! ERR_WRONG_STATE_IN_NEWSLOT = 0x1d, // wrong state {0} in start of frame, at slotOffset {1} +! ERR_WRONG_STATE_IN_ENDOFFRAME = 0x1e, // wrong state {0} in end of frame, at slotOffset {1} +! ERR_MAXTXDATAPREPARE_OVERFLOW = 0x1f, // maxTxDataPrepare overflows while at state {0} in slotOffset {1} +! ERR_MAXRXACKPREPARE_OVERFLOWS = 0x20, // maxRxAckPrepapare overflows while at state {0} in slotOffset {1} +! ERR_MAXRXDATAPREPARE_OVERFLOWS = 0x21, // maxRxDataPrepapre overflows while at state {0} in slotOffset {1} +! ERR_MAXTXACKPREPARE_OVERFLOWS = 0x22, // maxTxAckPrepapre overflows while at state {0} in slotOffset {1} +! ERR_WDDATADURATION_OVERFLOWS = 0x23, // wdDataDuration overflows while at state {0} in slotOffset {1} +! ERR_WDRADIO_OVERFLOWS = 0x24, // wdRadio overflows while at state {0} in slotOffset {1} +! ERR_WDRADIOTX_OVERFLOWS = 0x25, // wdRadioTx overflows while at state {0} in slotOffset {1} +! ERR_WDACKDURATION_OVERFLOWS = 0x26, // wdAckDuration overflows while at state {0} in slotOffset {1} +! // general +! ERR_BUSY_SENDING = 0x27, // busy sending +! ERR_UNEXPECTED_SENDDONE = 0x28, // sendDone for packet I didn't send +! ERR_NO_FREE_PACKET_BUFFER = 0x29, // no free packet buffer (code location {0}) +! ERR_FREEING_UNUSED = 0x2a, // freeing unused memory +! ERR_FREEING_ERROR = 0x2b, // freeing memory unsupported memory +! ERR_UNSUPPORTED_COMMAND = 0x2c, // unsupported command {0} +! ERR_MSG_UNKNOWN_TYPE = 0x2d, // unknown message type {0} +! ERR_WRONG_ADDR_TYPE = 0x2e, // wrong address type {0} (code location {1}) +! ERR_BRIDGE_MISMATCH = 0x2f, // isBridge mismatch (code location {0}) +! ERR_HEADER_TOO_LONG = 0x30, // header too long, length {1} (code location {0}) +! ERR_INPUTBUFFER_LENGTH = 0x31, // input length problem, length={0} +! ERR_BOOTED = 0x32, // booted +! ERR_INVALIDSERIALFRAME = 0x33, // invalid serial frame +! ERR_INVALIDPACKETFROMRADIO = 0x34, // invalid packet from radio, length {1} (code location {0}) +! }; +! +! //=========================== typedef ========================================= +! +! typedef uint16_t errorparameter_t; +! typedef uint16_t dagrank_t; +! typedef uint8_t error_t; +! #define bool uint8_t +! +! PRAGMA(pack(1)); +! typedef struct { +! uint8_t byte4; +! uint16_t bytes2and3; +! uint16_t bytes0and1; +! } asn_t; +! PRAGMA(pack()); +! +! PRAGMA(pack(1)); +! typedef struct { // always written big endian, i.e. MSB in addr[0] +! uint8_t type; +! union { +! uint8_t addr_16b[2]; +! uint8_t addr_64b[8]; +! uint8_t addr_128b[16]; +! uint8_t panid[2]; +! uint8_t prefix[8]; +! }; +! } open_addr_t; +! PRAGMA(pack()); +! +! typedef struct { +! //admin +! uint8_t creator; // the component which called getFreePacketBuffer() +! uint8_t owner; // the component which currently owns the entry +! uint8_t* payload; // pointer to the start of the payload within 'packet' +! uint8_t length; // length in bytes of the payload +! //l4 +! uint8_t l4_protocol; // l4 protocol to be used +! bool l4_protocol_compressed; // is the l4 protocol header compressed? +! uint16_t l4_sourcePortORicmpv6Type; // l4 source port +! uint16_t l4_destination_port; // l4 destination port +! uint8_t* l4_payload; // pointer to the start of the payload of l4 (used for retransmits) +! uint8_t l4_length; // length of the payload of l4 (used for retransmits) +! //l3 +! open_addr_t l3_destinationAdd; // 128b IPv6 destination (down stack) +! open_addr_t l3_sourceAdd; // 128b IPv6 source address +! //l2 +! error_t l2_sendDoneError; // outcome of trying to send this packet +! open_addr_t l2_nextORpreviousHop; // 64b IEEE802.15.4 next (down stack) or previous (up) hop address +! uint8_t l2_frameType; // beacon, data, ack, cmd +! uint8_t l2_dsn; // sequence number of the received frame +! uint8_t l2_retriesLeft; // number Tx retries left before packet dropped (dropped when hits 0) +! uint8_t l2_numTxAttempts; // number Tx attempts +! asn_t l2_asn; // at what ASN the packet was Tx'ed or Rx'ed +! uint8_t* l2_payload; // pointer to the start of the payload of l2 (used for MAC to fill in ASN in ADV) +! //l1 (drivers) +! uint8_t l1_txPower; // power for packet to Tx at +! int8_t l1_rssi; // RSSI of received packet +! uint8_t l1_lqi; // LQI of received packet +! bool l1_crc; // did received packet pass CRC check? +! //the packet +! uint8_t packet[1+1+125+2+1]; // 1B spi address, 1B length, 125B data, 2B CRC, 1B LQI +! } OpenQueueEntry_t; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void openwsn_init(); +! +! #endif +--- 1,330 ---- +! /** +! \brief General OpenWSN definitions +! +! \author Thomas Watteyne , August 2010 +! \author Ankur Mehta , September 2010 +! */ +! +! #ifndef __OPENWSN_H +! #define __OPENWSN_H +! +! //general +! #include // needed for uin8_t, uint16_t +! #include "board_info.h" +! +! #include +! #include "kernel.h" +! //========================= prototypes ======================================== +! void openwsn_start_thread(void); +! +! //=========================== define ========================================== +! +! #define PRIORITY_OPENWSN PRIORITY_MAIN-1 +! +! static const uint8_t infoStackName[] = "OpenWSN "; +! #define OPENWSN_VERSION_MAJOR 1 +! #define OPENWSN_VERSION_MINOR 4 +! #define OPENWSN_VERSION_PATCH 1 +! +! #ifndef TRUE +! #define TRUE 1 +! #endif +! +! #ifndef FALSE +! #define FALSE 0 +! #endif +! +! #define LENGTH_ADDR16b 2 +! #define LENGTH_ADDR64b 8 +! #define LENGTH_ADDR128b 16 +! +! enum { +! E_SUCCESS = 0, +! E_FAIL = 1, +! }; +! +! // types of addresses +! enum { +! ADDR_NONE = 0, +! ADDR_16B = 1, +! ADDR_64B = 2, +! ADDR_128B = 3, +! ADDR_PANID = 4, +! ADDR_PREFIX = 5, +! ADDR_ANYCAST = 6, +! }; +! +! enum { +! OW_LITTLE_ENDIAN = TRUE, +! OW_BIG_ENDIAN = FALSE, +! }; +! +! // protocol numbers, as defined by the IANA +! enum { +! IANA_IPv6HOPOPT = 0x00, +! IANA_TCP = 0x06, +! IANA_UDP = 0x11, +! IANA_IPv6ROUTE = 0x2b, +! IANA_ICMPv6 = 0x3a, +! IANA_ICMPv6_ECHO_REQUEST = 128, +! IANA_ICMPv6_ECHO_REPLY = 129, +! IANA_ICMPv6_RS = 133, +! IANA_ICMPv6_RA = 134, +! IANA_ICMPv6_RA_PREFIX_INFORMATION = 3, +! IANA_ICMPv6_RPL = 155, +! IANA_ICMPv6_RPL_DIO = 0x01, +! IANA_ICMPv6_RPL_DAO = 0x02, +! IANA_RSVP = 46, +! IANA_UNDEFINED = 250, //use an unassigned +! }; +! +! // well known ports (which we define) +! // warning: first 4 MSB of 2° octect may coincide with previous protocol number +! enum { +! //TCP +! WKP_TCP_HTTP = 80, +! WKP_TCP_ECHO = 7, +! WKP_TCP_INJECT = 2188, +! WKP_TCP_DISCARD = 9, +! //UDP +! WKP_UDP_COAP = 5683, +! WKP_UDP_HELI = 2192, +! WKP_UDP_IMU = 2190, +! WKP_UDP_ECHO = 7, +! WKP_UDP_INJECT = 2188, +! WKP_UDP_DISCARD = 9, +! WKP_UDP_RAND = 61000, +! WKP_UDP_LATENCY = 61001, +! }; +! +! //status elements +! enum { +! STATUS_ISSYNC = 0, +! STATUS_ID = 1, +! STATUS_DAGRANK = 2, +! STATUS_OUTBUFFERINDEXES = 3, +! STATUS_ASN = 4, +! STATUS_MACSTATS = 5, +! STATUS_SCHEDULE = 6, +! STATUS_BACKOFF = 7, +! STATUS_QUEUE = 8, +! STATUS_NEIGHBORS = 9, +! STATUS_MAX = 10, +! }; +! +! //component identifiers +! //the order is important because +! enum { +! COMPONENT_NULL = 0x00, +! COMPONENT_OPENWSN = 0x01, +! //cross-layers +! COMPONENT_IDMANAGER = 0x02, +! COMPONENT_OPENQUEUE = 0x03, +! COMPONENT_OPENSERIAL = 0x04, +! COMPONENT_PACKETFUNCTIONS = 0x05, +! COMPONENT_RANDOM = 0x06, +! //PHY +! COMPONENT_RADIO = 0x07, +! //MAClow +! COMPONENT_IEEE802154 = 0x08, +! COMPONENT_IEEE802154E = 0x09, +! +! //All components with higher component id than COMPONENT_IEEE802154E +! //won't be able to get free packets from the queue +! //when the mote is not synch +! +! //MAClow<->MAChigh ("virtual components") +! COMPONENT_RES_TO_IEEE802154E = 0x0a, +! COMPONENT_IEEE802154E_TO_RES = 0x0b, +! //MAChigh +! COMPONENT_RES = 0x0c, +! COMPONENT_NEIGHBORS = 0x0d, +! COMPONENT_SCHEDULE = 0x0e, +! //IPHC +! COMPONENT_OPENBRIDGE = 0x0f, +! COMPONENT_IPHC = 0x10, +! //IPv6 +! COMPONENT_FORWARDING = 0x11, +! COMPONENT_ICMPv6 = 0x12, +! COMPONENT_ICMPv6ECHO = 0x13, +! COMPONENT_ICMPv6ROUTER = 0x14, +! COMPONENT_ICMPv6RPL = 0x15, +! //TRAN +! COMPONENT_OPENTCP = 0x16, +! COMPONENT_OPENUDP = 0x17, +! COMPONENT_OPENCOAP = 0x18, +! //App test +! COMPONENT_TCPECHO = 0x19, +! COMPONENT_TCPINJECT = 0x1a, +! COMPONENT_TCPPRINT = 0x1b, +! COMPONENT_UDPECHO = 0x1c, +! COMPONENT_UDPINJECT = 0x1d, +! COMPONENT_UDPPRINT = 0x1e, +! COMPONENT_RSVP = 0x1f, +! //App +! COMPONENT_OHLONE = 0x20, +! COMPONENT_HELI = 0x21, +! COMPONENT_IMU = 0x22, +! COMPONENT_RLEDS = 0x23, +! COMPONENT_RREG = 0x24, +! COMPONENT_RWELLKNOWN = 0x25, +! COMPONENT_RT = 0x26, +! COMPONENT_REX = 0x27, +! COMPONENT_RXL1 = 0x28, +! COMPONENT_RINFO = 0x29, +! COMPONENT_RHELI = 0x2a, +! COMPONENT_RRUBE = 0x2b, +! COMPONENT_LAYERDEBUG = 0x2c, +! COMPONENT_UDPRAND = 0x2d, +! COMPONENT_UDPSTORM = 0x2e, +! COMPONENT_UDPLATENCY = 0x2f, +! COMPONENT_TEST = 0x30, +! COMPONENT_R6TUS = 0x31, +! }; +! +! /** +! \brief error codes used throughout the OpenWSN stack +! +! \note The comments are used in the Python parsing tool: +! - {0} refers to the value of the first argument, +! - {1} refers to the value of the second argument, +! */ +! enum { +! // l7 +! ERR_RCVD_ECHO_REQUEST = 0x01, // received an echo request +! ERR_RCVD_ECHO_REPLY = 0x02, // received an echo reply +! ERR_GETDATA_ASKS_TOO_FEW_BYTES = 0x03, // getData asks for too few bytes, maxNumBytes={0}, fill level={1} +! ERR_INPUT_BUFFER_OVERFLOW = 0x04, // the input buffer has overflown +! ERR_COMMAND_NOT_ALLOWED = 0x05, // the command is not allowerd, command = {0} +! // l4 +! ERR_WRONG_TRAN_PROTOCOL = 0x06, // unknown transport protocol {0} (code location {1}) +! ERR_WRONG_TCP_STATE = 0x07, // wrong TCP state {0} (code location {1}) +! ERR_TCP_RESET = 0x08, // TCP reset while in state {0} (code location {1}) +! ERR_UNSUPPORTED_PORT_NUMBER = 0x09, // unsupported port number {0} (code location {1}) +! // l3 +! ERR_UNEXPECTED_DAO = 0x0a, // unexpected DAO (code location {0}) +! ERR_UNSUPPORTED_ICMPV6_TYPE = 0x0b, // unsupported ICMPv6 type {0} (code location {1}) +! ERR_6LOWPAN_UNSUPPORTED = 0x0c, // unsupported 6LoWPAN parameter {1} at location {0} +! ERR_NO_NEXTHOP = 0x0d, // no next hop +! ERR_INVALID_PARAM = 0x0e, // invalid parameter +! ERR_INVALID_FWDMODE = 0x0f, // invalid forward mode +! ERR_LARGE_DAGRANK = 0x10, // large DAGrank {0}, set to {1} +! ERR_HOP_LIMIT_REACHED = 0x11, // packet discarded hop limit reached +! ERR_LOOP_DETECTED = 0x12, // loop detected due to previous rank {0} lower than current node rank {1} +! ERR_WRONG_DIRECTION = 0x13, // upstream packet set to be downstream, possible loop. +! // l2b +! ERR_NEIGHBORS_FULL = 0x14, // neighbors table is full (max number of neighbor is {0}) +! ERR_NO_SENT_PACKET = 0x15, // there is no sent packet in queue +! ERR_NO_RECEIVED_PACKET = 0x16, // there is no received packet in queue +! ERR_SCHEDULE_OVERFLOWN = 0x17, // schedule overflown +! // l2a +! ERR_WRONG_CELLTYPE = 0x18, // wrong celltype {0} at slotOffset {1} +! ERR_IEEE154_UNSUPPORTED = 0x19, // unsupported IEEE802.15.4 parameter {1} at location {0} +! ERR_DESYNCHRONIZED = 0x1a, // got desynchronized at slotOffset {0} +! ERR_SYNCHRONIZED = 0x1b, // synchronized at slotOffset {0} +! ERR_LARGE_TIMECORRECTION = 0x1c, // large timeCorr.: {0} ticks (code loc. {1}) +! ERR_WRONG_STATE_IN_ENDFRAME_SYNC = 0x1d, // wrong state {0} in end of frame+sync +! ERR_WRONG_STATE_IN_STARTSLOT = 0x1e, // wrong state {0} in startSlot, at slotOffset {1} +! ERR_WRONG_STATE_IN_TIMERFIRES = 0x1f, // wrong state {0} in timer fires, at slotOffset {1} +! ERR_WRONG_STATE_IN_NEWSLOT = 0x20, // wrong state {0} in start of frame, at slotOffset {1} +! ERR_WRONG_STATE_IN_ENDOFFRAME = 0x21, // wrong state {0} in end of frame, at slotOffset {1} +! ERR_MAXTXDATAPREPARE_OVERFLOW = 0x22, // maxTxDataPrepare overflows while at state {0} in slotOffset {1} +! ERR_MAXRXACKPREPARE_OVERFLOWS = 0x23, // maxRxAckPrepapare overflows while at state {0} in slotOffset {1} +! ERR_MAXRXDATAPREPARE_OVERFLOWS = 0x24, // maxRxDataPrepapre overflows while at state {0} in slotOffset {1} +! ERR_MAXTXACKPREPARE_OVERFLOWS = 0x25, // maxTxAckPrepapre overflows while at state {0} in slotOffset {1} +! ERR_WDDATADURATION_OVERFLOWS = 0x26, // wdDataDuration overflows while at state {0} in slotOffset {1} +! ERR_WDRADIO_OVERFLOWS = 0x27, // wdRadio overflows while at state {0} in slotOffset {1} +! ERR_WDRADIOTX_OVERFLOWS = 0x28, // wdRadioTx overflows while at state {0} in slotOffset {1} +! ERR_WDACKDURATION_OVERFLOWS = 0x29, // wdAckDuration overflows while at state {0} in slotOffset {1} +! // general +! ERR_BUSY_SENDING = 0x2a, // busy sending +! ERR_UNEXPECTED_SENDDONE = 0x2b, // sendDone for packet I didn't send +! ERR_NO_FREE_PACKET_BUFFER = 0x2c, // no free packet buffer (code location {0}) +! ERR_FREEING_UNUSED = 0x2d, // freeing unused memory +! ERR_FREEING_ERROR = 0x2e, // freeing memory unsupported memory +! ERR_UNSUPPORTED_COMMAND = 0x2f, // unsupported command {0} +! ERR_MSG_UNKNOWN_TYPE = 0x30, // unknown message type {0} +! ERR_WRONG_ADDR_TYPE = 0x31, // wrong address type {0} (code location {1}) +! ERR_BRIDGE_MISMATCH = 0x32, // isBridge mismatch (code location {0}) +! ERR_HEADER_TOO_LONG = 0x33, // header too long, length {1} (code location {0}) +! ERR_INPUTBUFFER_LENGTH = 0x34, // input length problem, length={0} +! ERR_BOOTED = 0x35, // booted +! ERR_INVALIDSERIALFRAME = 0x36, // invalid serial frame +! ERR_INVALIDPACKETFROMRADIO = 0x37, // invalid packet frome radio, length {1} (code location {0}) +! ERR_BUSY_RECEIVING = 0x38, // busy receiving when stop of serial activity, buffer input length {1} (code location {0}) +! ERR_WRONG_CRC_INPUT = 0x39, // wrong CRC in input Buffer (input length {0}) +! }; +! +! //=========================== typedef ========================================= +! +! +! typedef uint16_t errorparameter_t; +! typedef uint16_t dagrank_t; +! typedef uint8_t owerror_t; +! //#define bool uint8_t +! +! //PRAGMA(pack(1)); +! typedef struct { +! uint8_t byte4; +! uint16_t bytes2and3; +! uint16_t bytes0and1; +! } asn_t; +! //PRAGMA(pack()); +! +! //PRAGMA(pack(1)); +! typedef struct { // always written big endian, i.e. MSB in addr[0] +! uint8_t type; +! union { +! uint8_t addr_16b[2]; +! uint8_t addr_64b[8]; +! uint8_t addr_128b[16]; +! uint8_t panid[2]; +! uint8_t prefix[8]; +! }; +! } open_addr_t; +! //PRAGMA(pack()); +! +! typedef struct { +! //admin +! uint8_t creator; // the component which called getFreePacketBuffer() +! uint8_t owner; // the component which currently owns the entry +! uint8_t* payload; // pointer to the start of the payload within 'packet' +! uint8_t length; // length in bytes of the payload +! //l4 +! uint8_t l4_protocol; // l4 protocol to be used +! bool l4_protocol_compressed; // is the l4 protocol header compressed? +! uint16_t l4_sourcePortORicmpv6Type; // l4 source port +! uint16_t l4_destination_port; // l4 destination port +! uint8_t* l4_payload; // pointer to the start of the payload of l4 (used for retransmits) +! uint8_t l4_length; // length of the payload of l4 (used for retransmits) +! //l3 +! open_addr_t l3_destinationAdd; // 128b IPv6 destination (down stack) +! open_addr_t l3_sourceAdd; // 128b IPv6 source address +! //l2 +! owerror_t l2_sendDoneError; // outcome of trying to send this packet +! open_addr_t l2_nextORpreviousHop; // 64b IEEE802.15.4 next (down stack) or previous (up) hop address +! uint8_t l2_frameType; // beacon, data, ack, cmd +! uint8_t l2_dsn; // sequence number of the received frame +! uint8_t l2_retriesLeft; // number Tx retries left before packet dropped (dropped when hits 0) +! uint8_t l2_numTxAttempts; // number Tx attempts +! asn_t l2_asn; // at what ASN the packet was Tx'ed or Rx'ed +! uint8_t* l2_payload; // pointer to the start of the payload of l2 (used for MAC to fill in ASN in ADV) +! uint8_t* l2_ASNpayload; // pointer to the ASN in EB +! uint8_t l2_joinPriority; // the join priority received in EB +! bool l2_joinPriorityPresent; +! //l1 (drivers) +! uint8_t l1_txPower; // power for packet to Tx at +! int8_t l1_rssi; // RSSI of received packet +! uint8_t l1_lqi; // LQI of received packet +! bool l1_crc; // did received packet pass CRC check? +! //the packet +! uint8_t packet[1+1+125+2+1]; // 1B spi address, 1B length, 125B data, 2B CRC, 1B LQI +! } OpenQueueEntry_t; +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! extern void openwsn_init(void); +! +! #endif +diff -crB openwsn/radio.c ../../../sys/net/openwsn/radio.c +*** openwsn/radio.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/radio.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,409 **** +! /** +! \brief CC2420-specific definition of the "radio" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "board.h" +! #include "radio.h" +! #include "cc2420.h" +! #include "spi.h" +! #include "debugpins.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! cc2420_status_t radioStatusByte; +! radio_state_t state; +! } radio_vars_t; +! +! radio_vars_t radio_vars; +! +! //=========================== prototypes ====================================== +! +! void radio_spiStrobe (uint8_t strobe, cc2420_status_t* statusRead); +! void radio_spiWriteReg (uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite); +! void radio_spiReadReg (uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead); +! void radio_spiWriteTxFifo( cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t lenToWrite); +! void radio_spiReadRxFifo ( cc2420_status_t* statusRead, uint8_t* bufRead, uint8_t* lenRead, uint8_t maxBufLen); +! +! //=========================== public ========================================== +! +! //===== admin +! +! void radio_init() { +! // clear variables +! memset(&radio_vars,0,sizeof(radio_vars_t)); +! +! // change state +! radio_vars.state = RADIOSTATE_STOPPED; +! +! // reset radio +! radio_reset(); +! +! // change state +! radio_vars.state = RADIOSTATE_RFOFF; +! +! // start radiotimer with dummy setting to activate SFD pin interrupt +! radiotimer_start(0xffff); +! } +! +! void radio_setOverflowCb(radiotimer_compare_cbt cb) { +! radiotimer_setOverflowCb(cb); +! } +! +! void radio_setCompareCb(radiotimer_compare_cbt cb) { +! radiotimer_setCompareCb(cb); +! } +! +! void radio_setStartFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_setStartFrameCb(cb); +! } +! +! void radio_setEndFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_setEndFrameCb(cb); +! } +! +! //===== reset +! +! void radio_reset() { +! volatile uint16_t delay; +! cc2420_MDMCTRL0_reg_t cc2420_MDMCTRL0_reg; +! cc2420_TXCTRL_reg_t cc2420_TXCTRL_reg; +! cc2420_RXCTRL1_reg_t cc2420_RXCTRL1_reg; +! +! // set radio VREG pin high +! PORT_PIN_RADIO_VREG_HIGH(); +! for (delay=0xffff;delay>0;delay--); // max. VREG start-up time is 0.6ms +! +! // set radio RESET pin low +! PORT_PIN_RADIO_RESET_LOW(); +! for (delay=0xffff;delay>0;delay--); +! +! // set radio RESET pin high +! PORT_PIN_RADIO_RESET_HIGH(); +! for (delay=0xffff;delay>0;delay--); +! +! // disable address recognition +! cc2420_MDMCTRL0_reg.PREAMBLE_LENGTH = 2; // 3 leading zero's (IEEE802.15.4 compliant) +! cc2420_MDMCTRL0_reg.AUTOACK = 0; +! cc2420_MDMCTRL0_reg.AUTOCRC = 1; +! cc2420_MDMCTRL0_reg.CCA_MODE = 3; +! cc2420_MDMCTRL0_reg.CCA_HYST = 2; +! cc2420_MDMCTRL0_reg.ADR_DECODE = 0; // turn OFF address recognition +! cc2420_MDMCTRL0_reg.PAN_COORDINATOR = 0; +! cc2420_MDMCTRL0_reg.RESERVED_FRAME_MODE = 1; // accept all frame types +! cc2420_MDMCTRL0_reg.reserved_w0 = 0; +! radio_spiWriteReg(CC2420_MDMCTRL0_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_MDMCTRL0_reg); +! +! // speed up time to TX +! cc2420_TXCTRL_reg.PA_LEVEL = 31;// max. TX power (~0dBm) +! cc2420_TXCTRL_reg.reserved_w1 = 1; +! cc2420_TXCTRL_reg.PA_CURRENT = 3; +! cc2420_TXCTRL_reg.TXMIX_CURRENT = 0; +! cc2420_TXCTRL_reg.TXMIX_CAP_ARRAY = 0; +! cc2420_TXCTRL_reg.TX_TURNAROUND = 0; // faster STXON->SFD timing (128us) +! cc2420_TXCTRL_reg.TXMIXBUF_CUR = 2; +! radio_spiWriteReg(CC2420_TXCTRL_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_TXCTRL_reg); +! +! // apply correction recommended in datasheet +! cc2420_RXCTRL1_reg.RXMIX_CURRENT = 2; +! cc2420_RXCTRL1_reg.RXMIX_VCM = 1; +! cc2420_RXCTRL1_reg.RXMIX_TAIL = 1; +! cc2420_RXCTRL1_reg.LNA_CAP_ARRAY = 1; +! cc2420_RXCTRL1_reg.MED_HGM = 0; +! cc2420_RXCTRL1_reg.HIGH_HGM = 1; +! cc2420_RXCTRL1_reg.MED_LOWGAIN = 0; +! cc2420_RXCTRL1_reg.LOW_LOWGAIN = 1; +! cc2420_RXCTRL1_reg.RXBPF_MIDCUR = 0; +! cc2420_RXCTRL1_reg.RXBPF_LOCUR = 1; // use this setting as per datasheet +! cc2420_RXCTRL1_reg.reserved_w0 = 0; +! radio_spiWriteReg(CC2420_RXCTRL1_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_RXCTRL1_reg); +! } +! +! //===== timer +! +! void radio_startTimer(uint16_t period) { +! radiotimer_start(period); +! } +! +! uint16_t radio_getTimerValue() { +! return radiotimer_getValue(); +! } +! +! void radio_setTimerPeriod(uint16_t period) { +! radiotimer_setPeriod(period); +! } +! +! uint16_t radio_getTimerPeriod() { +! return radiotimer_getPeriod(); +! } +! +! //===== RF admin +! +! void radio_setFrequency(uint8_t frequency) { +! cc2420_FSCTRL_reg_t cc2420_FSCTRL_reg; +! +! // change state +! radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; +! +! cc2420_FSCTRL_reg.FREQ = frequency-11; +! cc2420_FSCTRL_reg.FREQ *= 5; +! cc2420_FSCTRL_reg.FREQ += 357; +! cc2420_FSCTRL_reg.LOCK_STATUS = 0; +! cc2420_FSCTRL_reg.LOCK_LENGTH = 0; +! cc2420_FSCTRL_reg.CAL_RUNNING = 0; +! cc2420_FSCTRL_reg.CAL_DONE = 0; +! cc2420_FSCTRL_reg.LOCK_THR = 1; +! +! radio_spiWriteReg(CC2420_FSCTRL_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_FSCTRL_reg); +! +! // change state +! radio_vars.state = RADIOSTATE_FREQUENCY_SET; +! } +! +! void radio_rfOn() { +! radio_spiStrobe(CC2420_SXOSCON, &radio_vars.radioStatusByte); +! while (radio_vars.radioStatusByte.xosc16m_stable==0) { +! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); +! } +! } +! +! void radio_rfOff() { +! +! // change state +! radio_vars.state = RADIOSTATE_TURNING_OFF; +! +! radio_spiStrobe(CC2420_SRFOFF, &radio_vars.radioStatusByte); +! // poipoipoi wait until off +! +! // wiggle debug pin +! debugpins_radio_clr(); +! leds_radio_off(); +! +! // change state +! radio_vars.state = RADIOSTATE_RFOFF; +! } +! +! //===== TX +! +! void radio_loadPacket(uint8_t* packet, uint8_t len) { +! // change state +! radio_vars.state = RADIOSTATE_LOADING_PACKET; +! +! radio_spiStrobe(CC2420_SFLUSHTX, &radio_vars.radioStatusByte); +! radio_spiWriteTxFifo(&radio_vars.radioStatusByte, packet, len); +! +! // change state +! radio_vars.state = RADIOSTATE_PACKET_LOADED; +! } +! +! void radio_txEnable() { +! // change state +! radio_vars.state = RADIOSTATE_ENABLING_TX; +! +! // wiggle debug pin +! debugpins_radio_set(); +! leds_radio_on(); +! +! // I don't fully understand how the CC2420_STXCA the can be used here. +! +! // change state +! radio_vars.state = RADIOSTATE_TX_ENABLED; +! } +! +! void radio_txNow() { +! // change state +! radio_vars.state = RADIOSTATE_TRANSMITTING; +! +! radio_spiStrobe(CC2420_STXON, &radio_vars.radioStatusByte); +! } +! +! //===== RX +! +! void radio_rxEnable() { +! // change state +! radio_vars.state = RADIOSTATE_ENABLING_RX; +! +! // put radio in reception mode +! radio_spiStrobe(CC2420_SRXON, &radio_vars.radioStatusByte); +! radio_spiStrobe(CC2420_SFLUSHRX, &radio_vars.radioStatusByte); +! +! // wiggle debug pin +! debugpins_radio_set(); +! leds_radio_on(); +! +! // busy wait until radio really listening +! while (radio_vars.radioStatusByte.rssi_valid==0) { +! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); +! } +! +! // change state +! radio_vars.state = RADIOSTATE_LISTENING; +! } +! +! void radio_rxNow() { +! // nothing to do, the radio is already listening. +! } +! +! void radio_getReceivedFrame(uint8_t* bufRead, +! uint8_t* lenRead, +! uint8_t maxBufLen, +! int8_t* rssi, +! uint8_t* lqi, +! uint8_t* crc) { +! // read the received packet from the RXFIFO +! radio_spiReadRxFifo(&radio_vars.radioStatusByte, bufRead, lenRead, maxBufLen); +! +! // On reception, when MODEMCTRL0.AUTOCRC is set, the CC2420 replaces the +! // received CRC by: +! // - [1B] the rssi, a signed value. The actual value in dBm is that - 45. +! // - [1B] whether CRC checked (bit 7) and LQI (bit 6-0) +! *rssi = *(bufRead+*lenRead-2); +! *rssi -= 45; +! *crc = ((*(bufRead+*lenRead-1))&0x80)>>7; +! *lqi = (*(bufRead+*lenRead-1))&0x7f; +! } +! +! //=========================== private ========================================= +! +! void radio_spiStrobe(uint8_t strobe, cc2420_status_t* statusRead) { +! uint8_t spi_tx_buffer[1]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | strobe); +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_FIRSTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_FIRST, +! SPI_LAST); +! } +! +! void radio_spiWriteReg(uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite) { +! uint8_t spi_tx_buffer[3]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | reg); +! spi_tx_buffer[1] = regValueToWrite/256; +! spi_tx_buffer[2] = regValueToWrite%256; +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_FIRSTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_FIRST, +! SPI_LAST); +! } +! +! void radio_spiReadReg(uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead) { +! uint8_t spi_tx_buffer[3]; +! uint8_t spi_rx_buffer[3]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | reg); +! spi_tx_buffer[1] = 0x00; +! spi_tx_buffer[2] = 0x00; +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_BUFFER, +! spi_rx_buffer, +! sizeof(spi_rx_buffer), +! SPI_FIRST, +! SPI_LAST); +! +! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; +! *(regValueRead+0) = spi_rx_buffer[2]; +! *(regValueRead+1) = spi_rx_buffer[1]; +! } +! +! void radio_spiWriteTxFifo(cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t len) { +! uint8_t spi_tx_buffer[2]; +! +! // step 1. send SPI address and length byte +! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | CC2420_TXFIFO_ADDR); +! spi_tx_buffer[1] = len; +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_FIRSTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_FIRST, +! SPI_NOTLAST); +! +! // step 2. send payload +! spi_txrx(bufToWrite, +! len, +! SPI_LASTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_NOTFIRST, +! SPI_LAST); +! } +! +! void radio_spiReadRxFifo(cc2420_status_t* statusRead, +! uint8_t* pBufRead, +! uint8_t* pLenRead, +! uint8_t maxBufLen) { +! // when reading the packet over SPI from the RX buffer, you get the following: +! // - *[1B] dummy byte because of SPI +! // - *[1B] length byte +! // - [0-125B] packet (excluding CRC) +! // - *[2B] CRC +! uint8_t spi_tx_buffer[125]; +! uint8_t spi_rx_buffer[3]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | CC2420_RXFIFO_ADDR); +! +! // 2 first bytes +! spi_txrx(spi_tx_buffer, +! 2, +! SPI_BUFFER, +! spi_rx_buffer, +! sizeof(spi_rx_buffer), +! SPI_FIRST, +! SPI_NOTLAST); +! +! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; +! *pLenRead = spi_rx_buffer[1]; +! +! if (*pLenRead>2 && *pLenRead<=127) { +! // valid length +! +! //read packet +! spi_txrx(spi_tx_buffer, +! *pLenRead, +! SPI_BUFFER, +! pBufRead, +! 125, +! SPI_NOTFIRST, +! SPI_LAST); +! +! } else { +! // invalid length +! +! // read a just byte to close spi +! spi_txrx(spi_tx_buffer, +! 1, +! SPI_BUFFER, +! spi_rx_buffer, +! sizeof(spi_rx_buffer), +! SPI_NOTFIRST, +! SPI_LAST); +! } +! } +! +! //=========================== callbacks ======================================= +--- 1,409 ---- +! /** +! \brief CC2420-specific definition of the "radio" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "board.h" +! #include "radio.h" +! #include "cc2420.h" +! #include "spi.h" +! #include "debugpins.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! cc2420_status_t radioStatusByte; +! radio_state_t state; +! } radio_vars_t; +! +! radio_vars_t radio_vars; +! +! //=========================== prototypes ====================================== +! +! void radio_spiStrobe (uint8_t strobe, cc2420_status_t* statusRead); +! void radio_spiWriteReg (uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite); +! void radio_spiReadReg (uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead); +! void radio_spiWriteTxFifo( cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t lenToWrite); +! void radio_spiReadRxFifo ( cc2420_status_t* statusRead, uint8_t* bufRead, uint8_t* lenRead, uint8_t maxBufLen); +! +! //=========================== public ========================================== +! +! //===== admin +! +! void radio_init(void) { +! // clear variables +! memset(&radio_vars,0,sizeof(radio_vars_t)); +! +! // change state +! radio_vars.state = RADIOSTATE_STOPPED; +! +! // reset radio +! radio_reset(); +! +! // change state +! radio_vars.state = RADIOSTATE_RFOFF; +! +! // start radiotimer with dummy setting to activate SFD pin interrupt +! radiotimer_start(0xffff); +! } +! +! void radio_setOverflowCb(radiotimer_compare_cbt cb) { +! radiotimer_setOverflowCb(cb); +! } +! +! void radio_setCompareCb(radiotimer_compare_cbt cb) { +! radiotimer_setCompareCb(cb); +! } +! +! void radio_setStartFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_setStartFrameCb(cb); +! } +! +! void radio_setEndFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_setEndFrameCb(cb); +! } +! +! //===== reset +! +! void radio_reset(void) { +! volatile uint16_t delay; +! cc2420_MDMCTRL0_reg_t cc2420_MDMCTRL0_reg; +! cc2420_TXCTRL_reg_t cc2420_TXCTRL_reg; +! cc2420_RXCTRL1_reg_t cc2420_RXCTRL1_reg; +! +! // set radio VREG pin high +! PORT_PIN_RADIO_VREG_HIGH(); +! for (delay=0xffff;delay>0;delay--); // max. VREG start-up time is 0.6ms +! +! // set radio RESET pin low +! PORT_PIN_RADIO_RESET_LOW(); +! for (delay=0xffff;delay>0;delay--); +! +! // set radio RESET pin high +! PORT_PIN_RADIO_RESET_HIGH(); +! for (delay=0xffff;delay>0;delay--); +! +! // disable address recognition +! cc2420_MDMCTRL0_reg.PREAMBLE_LENGTH = 2; // 3 leading zero's (IEEE802.15.4 compliant) +! cc2420_MDMCTRL0_reg.AUTOACK = 0; +! cc2420_MDMCTRL0_reg.AUTOCRC = 1; +! cc2420_MDMCTRL0_reg.CCA_MODE = 3; +! cc2420_MDMCTRL0_reg.CCA_HYST = 2; +! cc2420_MDMCTRL0_reg.ADR_DECODE = 0; // turn OFF address recognition +! cc2420_MDMCTRL0_reg.PAN_COORDINATOR = 0; +! cc2420_MDMCTRL0_reg.RESERVED_FRAME_MODE = 1; // accept all frame types +! cc2420_MDMCTRL0_reg.reserved_w0 = 0; +! radio_spiWriteReg(CC2420_MDMCTRL0_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_MDMCTRL0_reg); +! +! // speed up time to TX +! cc2420_TXCTRL_reg.PA_LEVEL = 31;// max. TX power (~0dBm) +! cc2420_TXCTRL_reg.reserved_w1 = 1; +! cc2420_TXCTRL_reg.PA_CURRENT = 3; +! cc2420_TXCTRL_reg.TXMIX_CURRENT = 0; +! cc2420_TXCTRL_reg.TXMIX_CAP_ARRAY = 0; +! cc2420_TXCTRL_reg.TX_TURNAROUND = 0; // faster STXON->SFD timing (128us) +! cc2420_TXCTRL_reg.TXMIXBUF_CUR = 2; +! radio_spiWriteReg(CC2420_TXCTRL_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_TXCTRL_reg); +! +! // apply correction recommended in datasheet +! cc2420_RXCTRL1_reg.RXMIX_CURRENT = 2; +! cc2420_RXCTRL1_reg.RXMIX_VCM = 1; +! cc2420_RXCTRL1_reg.RXMIX_TAIL = 1; +! cc2420_RXCTRL1_reg.LNA_CAP_ARRAY = 1; +! cc2420_RXCTRL1_reg.MED_HGM = 0; +! cc2420_RXCTRL1_reg.HIGH_HGM = 1; +! cc2420_RXCTRL1_reg.MED_LOWGAIN = 0; +! cc2420_RXCTRL1_reg.LOW_LOWGAIN = 1; +! cc2420_RXCTRL1_reg.RXBPF_MIDCUR = 0; +! cc2420_RXCTRL1_reg.RXBPF_LOCUR = 1; // use this setting as per datasheet +! cc2420_RXCTRL1_reg.reserved_w0 = 0; +! radio_spiWriteReg(CC2420_RXCTRL1_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_RXCTRL1_reg); +! } +! +! //===== timer +! +! void radio_startTimer(uint16_t period) { +! radiotimer_start(period); +! } +! +! uint16_t radio_getTimerValue(void) { +! return radiotimer_getValue(); +! } +! +! void radio_setTimerPeriod(uint16_t period) { +! radiotimer_setPeriod(period); +! } +! +! uint16_t radio_getTimerPeriod(void) { +! return radiotimer_getPeriod(); +! } +! +! //===== RF admin +! +! void radio_setFrequency(uint8_t frequency) { +! cc2420_FSCTRL_reg_t cc2420_FSCTRL_reg; +! +! // change state +! radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; +! +! cc2420_FSCTRL_reg.FREQ = frequency-11; +! cc2420_FSCTRL_reg.FREQ *= 5; +! cc2420_FSCTRL_reg.FREQ += 357; +! cc2420_FSCTRL_reg.LOCK_STATUS = 0; +! cc2420_FSCTRL_reg.LOCK_LENGTH = 0; +! cc2420_FSCTRL_reg.CAL_RUNNING = 0; +! cc2420_FSCTRL_reg.CAL_DONE = 0; +! cc2420_FSCTRL_reg.LOCK_THR = 1; +! +! radio_spiWriteReg(CC2420_FSCTRL_ADDR, +! &radio_vars.radioStatusByte, +! *(uint16_t*)&cc2420_FSCTRL_reg); +! +! // change state +! radio_vars.state = RADIOSTATE_FREQUENCY_SET; +! } +! +! void radio_rfOn(void) { +! radio_spiStrobe(CC2420_SXOSCON, &radio_vars.radioStatusByte); +! while (radio_vars.radioStatusByte.xosc16m_stable==0) { +! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); +! } +! } +! +! void radio_rfOff(void) { +! +! // change state +! radio_vars.state = RADIOSTATE_TURNING_OFF; +! +! radio_spiStrobe(CC2420_SRFOFF, &radio_vars.radioStatusByte); +! // poipoipoi wait until off +! +! // wiggle debug pin +! debugpins_radio_clr(); +! leds_radio_off(); +! +! // change state +! radio_vars.state = RADIOSTATE_RFOFF; +! } +! +! //===== TX +! +! void radio_loadPacket(uint8_t* packet, uint8_t len) { +! // change state +! radio_vars.state = RADIOSTATE_LOADING_PACKET; +! +! radio_spiStrobe(CC2420_SFLUSHTX, &radio_vars.radioStatusByte); +! radio_spiWriteTxFifo(&radio_vars.radioStatusByte, packet, len); +! +! // change state +! radio_vars.state = RADIOSTATE_PACKET_LOADED; +! } +! +! void radio_txEnable(void) { +! // change state +! radio_vars.state = RADIOSTATE_ENABLING_TX; +! +! // wiggle debug pin +! debugpins_radio_set(); +! leds_radio_on(); +! +! // I don't fully understand how the CC2420_STXCA the can be used here. +! +! // change state +! radio_vars.state = RADIOSTATE_TX_ENABLED; +! } +! +! void radio_txNow(void) { +! // change state +! radio_vars.state = RADIOSTATE_TRANSMITTING; +! +! radio_spiStrobe(CC2420_STXON, &radio_vars.radioStatusByte); +! } +! +! //===== RX +! +! void radio_rxEnable(void) { +! // change state +! radio_vars.state = RADIOSTATE_ENABLING_RX; +! +! // put radio in reception mode +! radio_spiStrobe(CC2420_SRXON, &radio_vars.radioStatusByte); +! radio_spiStrobe(CC2420_SFLUSHRX, &radio_vars.radioStatusByte); +! +! // wiggle debug pin +! debugpins_radio_set(); +! leds_radio_on(); +! +! // busy wait until radio really listening +! while (radio_vars.radioStatusByte.rssi_valid==0) { +! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); +! } +! +! // change state +! radio_vars.state = RADIOSTATE_LISTENING; +! } +! +! void radio_rxNow(void) { +! // nothing to do, the radio is already listening. +! } +! +! void radio_getReceivedFrame(uint8_t* bufRead, +! uint8_t* lenRead, +! uint8_t maxBufLen, +! int8_t* rssi, +! uint8_t* lqi, +! uint8_t* crc) { +! // read the received packet from the RXFIFO +! radio_spiReadRxFifo(&radio_vars.radioStatusByte, bufRead, lenRead, maxBufLen); +! +! // On reception, when MODEMCTRL0.AUTOCRC is set, the CC2420 replaces the +! // received CRC by: +! // - [1B] the rssi, a signed value. The actual value in dBm is that - 45. +! // - [1B] whether CRC checked (bit 7) and LQI (bit 6-0) +! *rssi = *(bufRead+*lenRead-2); +! *rssi -= 45; +! *crc = ((*(bufRead+*lenRead-1))&0x80)>>7; +! *lqi = (*(bufRead+*lenRead-1))&0x7f; +! } +! +! //=========================== private ========================================= +! +! void radio_spiStrobe(uint8_t strobe, cc2420_status_t* statusRead) { +! uint8_t spi_tx_buffer[1]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | strobe); +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_FIRSTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_FIRST, +! SPI_LAST); +! } +! +! void radio_spiWriteReg(uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite) { +! uint8_t spi_tx_buffer[3]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | reg); +! spi_tx_buffer[1] = regValueToWrite/256; +! spi_tx_buffer[2] = regValueToWrite%256; +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_FIRSTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_FIRST, +! SPI_LAST); +! } +! +! void radio_spiReadReg(uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead) { +! uint8_t spi_tx_buffer[3]; +! uint8_t spi_rx_buffer[3]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | reg); +! spi_tx_buffer[1] = 0x00; +! spi_tx_buffer[2] = 0x00; +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_BUFFER, +! spi_rx_buffer, +! sizeof(spi_rx_buffer), +! SPI_FIRST, +! SPI_LAST); +! +! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; +! *(regValueRead+0) = spi_rx_buffer[2]; +! *(regValueRead+1) = spi_rx_buffer[1]; +! } +! +! void radio_spiWriteTxFifo(cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t len) { +! uint8_t spi_tx_buffer[2]; +! +! // step 1. send SPI address and length byte +! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | CC2420_TXFIFO_ADDR); +! spi_tx_buffer[1] = len; +! +! spi_txrx(spi_tx_buffer, +! sizeof(spi_tx_buffer), +! SPI_FIRSTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_FIRST, +! SPI_NOTLAST); +! +! // step 2. send payload +! spi_txrx(bufToWrite, +! len, +! SPI_LASTBYTE, +! (uint8_t*)statusRead, +! 1, +! SPI_NOTFIRST, +! SPI_LAST); +! } +! +! void radio_spiReadRxFifo(cc2420_status_t* statusRead, +! uint8_t* pBufRead, +! uint8_t* pLenRead, +! uint8_t maxBufLen) { +! // when reading the packet over SPI from the RX buffer, you get the following: +! // - *[1B] dummy byte because of SPI +! // - *[1B] length byte +! // - [0-125B] packet (excluding CRC) +! // - *[2B] CRC +! uint8_t spi_tx_buffer[125]; +! uint8_t spi_rx_buffer[3]; +! +! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | CC2420_RXFIFO_ADDR); +! +! // 2 first bytes +! spi_txrx(spi_tx_buffer, +! 2, +! SPI_BUFFER, +! spi_rx_buffer, +! sizeof(spi_rx_buffer), +! SPI_FIRST, +! SPI_NOTLAST); +! +! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; +! *pLenRead = spi_rx_buffer[1]; +! +! if (*pLenRead>2 && *pLenRead<=127) { +! // valid length +! +! //read packet +! spi_txrx(spi_tx_buffer, +! *pLenRead, +! SPI_BUFFER, +! pBufRead, +! 125, +! SPI_NOTFIRST, +! SPI_LAST); +! +! } else { +! // invalid length +! +! // read a just byte to close spi +! spi_txrx(spi_tx_buffer, +! 1, +! SPI_BUFFER, +! spi_rx_buffer, +! sizeof(spi_rx_buffer), +! SPI_NOTFIRST, +! SPI_LAST); +! } +! } +! +! //=========================== callbacks ======================================= +diff -crB openwsn/radio.h ../../../sys/net/openwsn/radio.h +*** openwsn/radio.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/radio.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,80 **** +! /** +! \brief Cross-platform declaration "radio" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __RADIO_H +! #define __RADIO_H +! +! #include "radiotimer.h" +! +! //=========================== define ========================================== +! +! #define LENGTH_CRC 2 +! +! /** +! \brief Current state of the radio. +! +! \note This radio driver is very minimal in that it does not follow a state machine. +! It is up to the MAC layer to ensure that the different radio operations +! are called in the righr order. The radio keeps a state for debugging purposes only. +! */ +! typedef enum { +! RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. +! RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. +! RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. +! RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. +! RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. +! RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. +! RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). +! RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. +! RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. +! RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). +! RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. +! RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. +! RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. +! RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. +! } radio_state_t; +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void radio_init(); +! void radio_setOverflowCb(radiotimer_compare_cbt cb); +! void radio_setCompareCb(radiotimer_compare_cbt cb); +! void radio_setStartFrameCb(radiotimer_capture_cbt cb); +! void radio_setEndFrameCb(radiotimer_capture_cbt cb); +! // reset +! void radio_reset(); +! // timer +! void radio_startTimer(PORT_TIMER_WIDTH period); +! PORT_TIMER_WIDTH radio_getTimerValue(); +! void radio_setTimerPeriod(PORT_TIMER_WIDTH period); +! PORT_TIMER_WIDTH radio_getTimerPeriod(); +! // RF admin +! void radio_setFrequency(uint8_t frequency); +! void radio_rfOn(); +! void radio_rfOff(); +! // TX +! void radio_loadPacket(uint8_t* packet, uint8_t len); +! void radio_txEnable(); +! void radio_txNow(); +! // RX +! void radio_rxEnable(); +! void radio_rxNow(); +! void radio_getReceivedFrame(uint8_t* bufRead, +! uint8_t* lenRead, +! uint8_t maxBufLen, +! int8_t* rssi, +! uint8_t* lqi, +! uint8_t* crc); +! +! // interrupt handlers +! kick_scheduler_t radio_isr(); +! +! #endif +--- 1,90 ---- +! #ifndef __RADIO_H +! #define __RADIO_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup radio +! \{ +! +! \brief Cross-platform declaration "radio" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "radiotimer.h" +! +! //=========================== define ========================================== +! +! #define LENGTH_CRC 2 +! +! /** +! \brief Current state of the radio. +! +! \note This radio driver is very minimal in that it does not follow a state machine. +! It is up to the MAC layer to ensure that the different radio operations +! are called in the righr order. The radio keeps a state for debugging purposes only. +! */ +! typedef enum { +! RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. +! RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. +! RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. +! RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. +! RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. +! RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. +! RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). +! RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. +! RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. +! RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). +! RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. +! RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. +! RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. +! RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. +! } radio_state_t; +! +! //=========================== typedef ========================================= +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void radio_init(void); +! void radio_setOverflowCb(radiotimer_compare_cbt cb); +! void radio_setCompareCb(radiotimer_compare_cbt cb); +! void radio_setStartFrameCb(radiotimer_capture_cbt cb); +! void radio_setEndFrameCb(radiotimer_capture_cbt cb); +! // reset +! void radio_reset(void); +! // timer +! void radio_startTimer(PORT_TIMER_WIDTH period); +! PORT_TIMER_WIDTH radio_getTimerValue(void); +! void radio_setTimerPeriod(PORT_TIMER_WIDTH period); +! PORT_TIMER_WIDTH radio_getTimerPeriod(void); +! // RF admin +! void radio_setFrequency(uint8_t frequency); +! void radio_rfOn(void); +! void radio_rfOff(void); +! // TX +! void radio_loadPacket(uint8_t* packet, uint8_t len); +! void radio_txEnable(void); +! void radio_txNow(void); +! // RX +! void radio_rxEnable(void); +! void radio_rxNow(void); +! void radio_getReceivedFrame(uint8_t* bufRead, +! uint8_t* lenRead, +! uint8_t maxBufLen, +! int8_t* rssi, +! uint8_t* lqi, +! uint8_t* crc); +! +! // interrupt handlers +! kick_scheduler_t radio_isr(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/radiotimer.c ../../../sys/net/openwsn/radiotimer.c +*** openwsn/radiotimer.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/radiotimer.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,176 **** +! /** +! \brief TelosB-specific definition of the "radiotimer" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "radiotimer.h" +! #include "leds.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! radiotimer_compare_cbt overflowCb; +! radiotimer_compare_cbt compareCb; +! radiotimer_capture_cbt startFrameCb; +! radiotimer_capture_cbt endFrameCb; +! } radiotimer_vars_t; +! +! radiotimer_vars_t radiotimer_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! //===== admin +! +! void radiotimer_init() { +! // clear local variables +! memset(&radiotimer_vars,0,sizeof(radiotimer_vars_t)); +! } +! +! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb) { +! radiotimer_vars.overflowCb = cb; +! } +! +! void radiotimer_setCompareCb(radiotimer_compare_cbt cb) { +! radiotimer_vars.compareCb = cb; +! } +! +! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_vars.startFrameCb = cb; +! } +! +! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_vars.endFrameCb = cb; +! } +! +! void radiotimer_start(uint16_t period) { +! // radio's SFD pin connected to P4.1 +! P4DIR &= ~0x02; // input +! P4SEL |= 0x02; // in CCI1a/B mode +! +! // CCR0 contains period of counter +! // do not interrupt when counter reaches TBCCR0, but when it resets +! TBCCR0 = period-1; +! +! // CCR1 in capture mode +! TBCCTL1 = CM_3+SCS+CAP+CCIE; +! TBCCR1 = 0; +! +! // CCR2 in compare mode (disabled for now) +! TBCCTL2 = 0; +! TBCCR2 = 0; +! +! // start counting +! TBCTL = TBIE+TBCLR; // interrupt when counter resets +! TBCTL |= MC_1+TBSSEL_1; // up mode, clocked from ACLK +! } +! +! //===== direct access +! +! uint16_t radiotimer_getValue() { +! return TBR; +! } +! +! void radiotimer_setPeriod(uint16_t period) { +! TBCCR0 = period; +! } +! +! uint16_t radiotimer_getPeriod() { +! return TBCCR0; +! } +! +! //===== compare +! +! void radiotimer_schedule(uint16_t offset) { +! // offset when to fire +! TBCCR2 = offset; +! +! // enable compare interrupt (this also cancels any pending interrupts) +! TBCCTL2 = CCIE; +! } +! +! void radiotimer_cancel() { +! // reset compare value (also resets interrupt flag) +! TBCCR2 = 0; +! +! // disable compare interrupt +! TBCCTL2 &= ~CCIE; +! } +! +! //===== capture +! +! inline uint16_t radiotimer_getCapturedTime() { +! // this should never happpen! +! +! // we can not print from within the BSP. Instead: +! // blink the error LED +! leds_error_blink(); +! // reset the board +! board_reset(); +! +! return 0;// this line is never reached, but here to satisfy compiler +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! /** +! \brief TimerB CCR1-6 interrupt service routine +! */ +! kick_scheduler_t radiotimer_isr() { +! uint16_t tbiv_local; +! +! // reading TBIV returns the value of the highest pending interrupt flag +! // and automatically resets that flag. We therefore copy its value to the +! // tbiv_local local variable exactly once. If there is more than one +! // interrupt pending, we will reenter this function after having just left +! // it. +! tbiv_local = TBIV; +! +! switch (tbiv_local) { +! case 0x0002: // CCR1 fires +! if (TBCCTL1 & CCI) { +! // SFD pin is high: this was the start of a frame +! if (radiotimer_vars.startFrameCb!=NULL) { +! radiotimer_vars.startFrameCb(TBCCR1); +! // kick the OS +! return KICK_SCHEDULER; +! } +! } else { +! // SFD pin is low: this was the end of a frame +! if (radiotimer_vars.endFrameCb!=NULL) { +! radiotimer_vars.endFrameCb(TBCCR1); +! // kick the OS +! return KICK_SCHEDULER; +! } +! } +! break; +! case 0x0004: // CCR2 fires +! if (radiotimer_vars.compareCb!=NULL) { +! radiotimer_vars.compareCb(); +! // kick the OS +! return KICK_SCHEDULER; +! } +! break; +! case 0x0006: // CCR3 fires +! break; +! case 0x0008: // CCR4 fires +! break; +! case 0x000a: // CCR5 fires +! break; +! case 0x000c: // CCR6 fires +! break; +! case 0x000e: // timer overflow +! if (radiotimer_vars.overflowCb!=NULL) { +! radiotimer_vars.overflowCb(); +! // kick the OS +! return KICK_SCHEDULER; +! } +! break; +! } +! return DO_NOT_KICK_SCHEDULER; +! } +--- 1,176 ---- +! /** +! \brief TelosB-specific definition of the "radiotimer" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "radiotimer.h" +! #include "leds.h" +! +! //=========================== variables ======================================= +! +! typedef struct { +! radiotimer_compare_cbt overflowCb; +! radiotimer_compare_cbt compareCb; +! radiotimer_capture_cbt startFrameCb; +! radiotimer_capture_cbt endFrameCb; +! } radiotimer_vars_t; +! +! radiotimer_vars_t radiotimer_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! //===== admin +! +! void radiotimer_init(void) { +! // clear local variables +! memset(&radiotimer_vars,0,sizeof(radiotimer_vars_t)); +! } +! +! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb) { +! radiotimer_vars.overflowCb = cb; +! } +! +! void radiotimer_setCompareCb(radiotimer_compare_cbt cb) { +! radiotimer_vars.compareCb = cb; +! } +! +! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_vars.startFrameCb = cb; +! } +! +! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb) { +! radiotimer_vars.endFrameCb = cb; +! } +! +! void radiotimer_start(PORT_RADIOTIMER_WIDTH period) { +! // radio's SFD pin connected to P4.1 +! P4DIR &= ~0x02; // input +! P4SEL |= 0x02; // in CCI1a/B mode +! +! // CCR0 contains period of counter +! // do not interrupt when counter reaches TBCCR0, but when it resets +! TBCCR0 = period-1; +! +! // CCR1 in capture mode +! TBCCTL1 = CM_3+SCS+CAP+CCIE; +! TBCCR1 = 0; +! +! // CCR2 in compare mode (disabled for now) +! TBCCTL2 = 0; +! TBCCR2 = 0; +! +! // start counting +! TBCTL = TBIE+TBCLR; // interrupt when counter resets +! TBCTL |= MC_1+TBSSEL_1; // up mode, clocked from ACLK +! } +! +! //===== direct access +! +! PORT_RADIOTIMER_WIDTH radiotimer_getValue(void) { +! return TBR; +! } +! +! void radiotimer_setPeriod(PORT_RADIOTIMER_WIDTH period) { +! TBCCR0 = period; +! } +! +! PORT_RADIOTIMER_WIDTH radiotimer_getPeriod(void) { +! return TBCCR0; +! } +! +! //===== compare +! +! void radiotimer_schedule(PORT_RADIOTIMER_WIDTH offset) { +! // offset when to fire +! TBCCR2 = offset; +! +! // enable compare interrupt (this also cancels any pending interrupts) +! TBCCTL2 = CCIE; +! } +! +! void radiotimer_cancel(void) { +! // reset compare value (also resets interrupt flag) +! TBCCR2 = 0; +! +! // disable compare interrupt +! TBCCTL2 &= ~CCIE; +! } +! +! //===== capture +! +! inline PORT_RADIOTIMER_WIDTH radiotimer_getCapturedTime(void) { +! // this should never happpen! +! +! // we can not print from within the BSP. Instead: +! // blink the error LED +! leds_error_blink(); +! // reset the board +! board_reset(); +! +! return 0;// this line is never reached, but here to satisfy compiler +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! /** +! \brief TimerB CCR1-6 interrupt service routine +! */ +! kick_scheduler_t radiotimer_isr(void) { +! PORT_RADIOTIMER_WIDTH tbiv_local; +! +! // reading TBIV returns the value of the highest pending interrupt flag +! // and automatically resets that flag. We therefore copy its value to the +! // tbiv_local local variable exactly once. If there is more than one +! // interrupt pending, we will reenter this function after having just left +! // it. +! tbiv_local = TBIV; +! +! switch (tbiv_local) { +! case 0x0002: // CCR1 fires +! if (TBCCTL1 & CCI) { +! // SFD pin is high: this was the start of a frame +! if (radiotimer_vars.startFrameCb!=NULL) { +! radiotimer_vars.startFrameCb(TBCCR1); +! // kick the OS +! return KICK_SCHEDULER; +! } +! } else { +! // SFD pin is low: this was the end of a frame +! if (radiotimer_vars.endFrameCb!=NULL) { +! radiotimer_vars.endFrameCb(TBCCR1); +! // kick the OS +! return KICK_SCHEDULER; +! } +! } +! break; +! case 0x0004: // CCR2 fires +! if (radiotimer_vars.compareCb!=NULL) { +! radiotimer_vars.compareCb(); +! // kick the OS +! return KICK_SCHEDULER; +! } +! break; +! case 0x0006: // CCR3 fires +! break; +! case 0x0008: // CCR4 fires +! break; +! case 0x000a: // CCR5 fires +! break; +! case 0x000c: // CCR6 fires +! break; +! case 0x000e: // timer overflow +! if (radiotimer_vars.overflowCb!=NULL) { +! radiotimer_vars.overflowCb(); +! // kick the OS +! return KICK_SCHEDULER; +! } +! break; +! } +! return DO_NOT_KICK_SCHEDULER; +! } +diff -crB openwsn/radiotimer.h ../../../sys/net/openwsn/radiotimer.h +*** openwsn/radiotimer.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/radiotimer.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,44 **** +! /** +! \brief Cross-platform declaration "radiotimer" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __RADIOTIMER_H +! #define __RADIOTIMER_H +! +! #include "stdint.h" +! #include "board.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef void (*radiotimer_compare_cbt)(); +! typedef void (*radiotimer_capture_cbt)(PORT_TIMER_WIDTH timestamp); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void radiotimer_init(); +! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb); +! void radiotimer_setCompareCb(radiotimer_compare_cbt cb); +! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb); +! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb); +! void radiotimer_start(PORT_TIMER_WIDTH period); +! // direct access +! PORT_TIMER_WIDTH radiotimer_getValue(); +! void radiotimer_setPeriod(PORT_TIMER_WIDTH period); +! PORT_TIMER_WIDTH radiotimer_getPeriod(); +! // compare +! void radiotimer_schedule(PORT_TIMER_WIDTH offset); +! void radiotimer_cancel(); +! // capture +! PORT_TIMER_WIDTH radiotimer_getCapturedTime(); +! +! // interrupt handlers +! kick_scheduler_t radiotimer_isr(); +! +! #endif +--- 1,54 ---- +! #ifndef __RADIOTIMER_H +! #define __RADIOTIMER_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup radiotimer +! \{ +! +! \brief Cross-platform declaration "radiotimer" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "stdint.h" +! #include "board_ow.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef void (*radiotimer_compare_cbt)(void); +! typedef void (*radiotimer_capture_cbt)(PORT_TIMER_WIDTH timestamp); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // admin +! void radiotimer_init(void); +! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb); +! void radiotimer_setCompareCb(radiotimer_compare_cbt cb); +! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb); +! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb); +! void radiotimer_start(PORT_RADIOTIMER_WIDTH period); +! // direct access +! PORT_RADIOTIMER_WIDTH radiotimer_getValue(void); +! void radiotimer_setPeriod(PORT_RADIOTIMER_WIDTH period); +! PORT_RADIOTIMER_WIDTH radiotimer_getPeriod(void); +! // compare +! void radiotimer_schedule(PORT_RADIOTIMER_WIDTH offset); +! void radiotimer_cancel(void); +! // capture +! PORT_RADIOTIMER_WIDTH radiotimer_getCapturedTime(void); +! +! // interrupt handlers +! kick_scheduler_t radiotimer_isr(void); +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/scheduler.c ../../../sys/net/openwsn/scheduler.c +*** openwsn/scheduler.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/scheduler.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,124 **** +! /** +! \brief OpenOS scheduler. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "openwsn.h" +! #include "scheduler.h" +! #include "board.h" +! #include "debugpins.h" +! #include "leds.h" +! +! //=========================== variables ======================================= +! +! typedef struct task_llist_t { +! task_cbt cb; +! task_prio_t prio; +! void* next; +! } taskList_item_t; +! +! typedef struct { +! taskList_item_t taskBuf[TASK_LIST_DEPTH]; +! taskList_item_t* task_list; +! uint8_t numTasksCur; +! uint8_t numTasksMax; +! } scheduler_vars_t; +! +! scheduler_vars_t scheduler_vars; +! +! typedef struct { +! uint8_t numTasksCur; +! uint8_t numTasksMax; +! } scheduler_dbg_t; +! +! scheduler_dbg_t scheduler_dbg; +! +! //=========================== prototypes ====================================== +! +! void consumeTask(uint8_t taskId); +! +! //=========================== public ========================================== +! +! void scheduler_init() { +! +! // initialization module variables +! memset(&scheduler_vars,0,sizeof(scheduler_vars_t)); +! memset(&scheduler_dbg,0,sizeof(scheduler_dbg_t)); +! +! // enable the scheduler's interrupt so SW can wake up the scheduler +! SCHEDULER_ENABLE_INTERRUPT(); +! } +! +! void scheduler_start() { +! taskList_item_t* pThisTask; +! while (1) { +! while(scheduler_vars.task_list!=NULL) { +! // there is still at least one task in the linked-list of tasks +! +! // the task to execute is the one at the head of the queue +! pThisTask = scheduler_vars.task_list; +! +! // shift the queue by one task +! scheduler_vars.task_list = pThisTask->next; +! +! // execute the current task +! pThisTask->cb(); +! +! // free up this task container +! pThisTask->cb = NULL; +! pThisTask->prio = TASKPRIO_NONE; +! pThisTask->next = NULL; +! scheduler_dbg.numTasksCur--; +! } +! debugpins_task_clr(); +! board_sleep(); +! debugpins_task_set(); // IAR should halt here if nothing to do +! } +! } +! +! void scheduler_push_task(task_cbt cb, task_prio_t prio) { +! taskList_item_t* taskContainer; +! taskList_item_t** taskListWalker; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! +! // find an empty task container +! taskContainer = &scheduler_vars.taskBuf[0]; +! while (taskContainer->cb!=NULL && +! taskContainer<=&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { +! taskContainer++; +! } +! if (taskContainer>&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { +! // task list has overflown. This should never happpen! +! +! // we can not print from within the kernel. Instead: +! // blink the error LED +! leds_error_blink(); +! // reset the board +! board_reset(); +! } +! // fill that task container with this task +! taskContainer->cb = cb; +! taskContainer->prio = prio; +! +! // find position in queue +! taskListWalker = &scheduler_vars.task_list; +! while (*taskListWalker!=NULL && +! (*taskListWalker)->prio < taskContainer->prio) { +! taskListWalker = (taskList_item_t**)&((*taskListWalker)->next); +! } +! // insert at that position +! taskContainer->next = *taskListWalker; +! *taskListWalker = taskContainer; +! // maintain debug stats +! scheduler_dbg.numTasksCur++; +! if (scheduler_dbg.numTasksCur>scheduler_dbg.numTasksMax) { +! scheduler_dbg.numTasksMax = scheduler_dbg.numTasksCur; +! } +! +! ENABLE_INTERRUPTS(); +! } +! +! //=========================== private ========================================= +--- 1,108 ---- +! /** +! \brief OpenOS scheduler. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "openwsn.h" +! #include "scheduler.h" +! #include "board.h" +! #include "debugpins.h" +! #include "leds.h" +! +! //=========================== variables ======================================= +! +! scheduler_vars_t scheduler_vars; +! scheduler_dbg_t scheduler_dbg; +! +! //=========================== prototypes ====================================== +! +! void consumeTask(uint8_t taskId); +! +! //=========================== public ========================================== +! +! void scheduler_init() { +! // initialization module variables +! memset(&scheduler_vars,0,sizeof(scheduler_vars_t)); +! memset(&scheduler_dbg,0,sizeof(scheduler_dbg_t)); +! +! // enable the scheduler's interrupt so SW can wake up the scheduler +! //SCHEDULER_ENABLE_INTERRUPT(); +! puts(__PRETTY_FUNCTION__); +! } +! +! void scheduler_start() { +! puts(__PRETTY_FUNCTION__); +! taskList_item_t* pThisTask; +! while (1) { +! while(scheduler_vars.task_list!=NULL) { +! // there is still at least one task in the linked-list of tasks +! +! // the task to execute is the one at the head of the queue +! pThisTask = scheduler_vars.task_list; +! printf("run task %p with prio %d\n", pThisTask->cb, pThisTask->prio); +! // shift the queue by one task +! scheduler_vars.task_list = pThisTask->next; +! +! // execute the current task +! pThisTask->cb(); +! +! // free up this task container +! pThisTask->cb = NULL; +! pThisTask->prio = TASKPRIO_NONE; +! pThisTask->next = NULL; +! scheduler_dbg.numTasksCur--; +! } +! //debugpins_task_clr(); +! board_sleep(); +! //debugpins_task_set(); // IAR should halt here if nothing to do +! } +! puts("leaving... WTF?!"); +! } +! +! void scheduler_push_task(task_cbt cb, task_prio_t prio) { +! puts(__PRETTY_FUNCTION__); +! taskList_item_t* taskContainer; +! taskList_item_t** taskListWalker; +! INTERRUPT_DECLARATION(); +! +! DISABLE_INTERRUPTS(); +! +! // find an empty task container +! taskContainer = &scheduler_vars.taskBuf[0]; +! while (taskContainer->cb!=NULL && +! taskContainer<=&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { +! taskContainer++; +! } +! if (taskContainer>&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { +! // task list has overflown. This should never happpen! +! +! // we can not print from within the kernel. Instead: +! // blink the error LED +! leds_error_blink(); +! // reset the board +! board_reset(); +! } +! // fill that task container with this task +! taskContainer->cb = cb; +! taskContainer->prio = prio; +! +! // find position in queue +! taskListWalker = &scheduler_vars.task_list; +! while (*taskListWalker!=NULL && +! (*taskListWalker)->prio < taskContainer->prio) { +! taskListWalker = (taskList_item_t**)&((*taskListWalker)->next); +! } +! // insert at that position +! taskContainer->next = *taskListWalker; +! *taskListWalker = taskContainer; +! // maintain debug stats +! scheduler_dbg.numTasksCur++; +! if (scheduler_dbg.numTasksCur>scheduler_dbg.numTasksMax) { +! scheduler_dbg.numTasksMax = scheduler_dbg.numTasksCur; +! } +! +! ENABLE_INTERRUPTS(); +! } +! +! //=========================== private ========================================= +diff -crB openwsn/scheduler.h ../../../sys/net/openwsn/scheduler.h +*** openwsn/scheduler.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/scheduler.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,64 **** +! #ifndef __SCHEDULER_H +! #define __SCHEDULER_H +! +! /** +! \addtogroup drivers +! \{ +! \addtogroup Scheduler +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! typedef enum { +! TASKPRIO_NONE = 0x00, +! // tasks trigger by radio +! TASKPRIO_RESNOTIF_RX = 0x01, // scheduled by IEEE802.15.4e +! TASKPRIO_RESNOTIF_TXDONE = 0x02, // scheduled by IEEE802.15.4e +! // tasks triggered by timers +! TASKPRIO_RES = 0x03, // scheduled by timerB CCR0 interrupt +! TASKPRIO_RPL = 0x04, // scheduled by timerB CCR1 interrupt +! TASKPRIO_TCP_TIMEOUT = 0x05, // scheduled by timerB CCR2 interrupt +! TASKPRIO_COAP = 0x06, // scheduled by timerB CCR3 interrupt +! // tasks trigger by other interrupts +! TASKPRIO_BUTTON = 0x07, // scheduled by P2.7 interrupt +! TASKPRIO_MAX = 0x08, +! } task_prio_t; +! +! #define TASK_LIST_DEPTH 10 +! +! //=========================== typedef ========================================= +! +! typedef void (*task_cbt)(void); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! // public functions +! void scheduler_init(); +! void scheduler_start(); +! void scheduler_push_task(task_cbt task_cb, task_prio_t prio); +! +! // interrupt handlers +! void isr_ieee154e_newSlot(); +! void isr_ieee154e_timer(); +! void isr_adc(); +! #ifdef ISR_GYRO +! void isr_gyro(); +! #endif +! #ifdef ISR_LARGE_RANGE_ACCEL +! void isr_large_range_accel(); +! #endif +! #ifdef ISR_BUTTON +! void isr_button(); +! #endif +! +! /** +! \} +! \} +! */ +! +! #endif +--- 1,82 ---- +! #ifndef __SCHEDULER_H +! #define __SCHEDULER_H +! +! /** +! \addtogroup kernel +! \{ +! \addtogroup Scheduler +! \{ +! */ +! +! #include "openwsn.h" +! +! //=========================== define ========================================== +! +! typedef enum { +! TASKPRIO_NONE = 0x00, +! // tasks trigger by radio +! TASKPRIO_RESNOTIF_RX = 0x01, // scheduled by IEEE802.15.4e +! TASKPRIO_RESNOTIF_TXDONE = 0x02, // scheduled by IEEE802.15.4e +! // tasks triggered by timers +! TASKPRIO_RES = 0x03, // scheduled by timerB CCR0 interrupt +! TASKPRIO_RPL = 0x04, // scheduled by timerB CCR1 interrupt +! TASKPRIO_TCP_TIMEOUT = 0x05, // scheduled by timerB CCR2 interrupt +! TASKPRIO_COAP = 0x06, // scheduled by timerB CCR3 interrupt +! // tasks trigger by other interrupts +! TASKPRIO_BUTTON = 0x07, // scheduled by P2.7 interrupt +! TASKPRIO_MAX = 0x08, +! } task_prio_t; +! +! #define TASK_LIST_DEPTH 10 +! +! //=========================== typedef ========================================= +! +! typedef void (*task_cbt)(void); +! +! typedef struct task_llist_t { +! task_cbt cb; +! task_prio_t prio; +! void* next; +! } taskList_item_t; +! +! //=========================== module variables ================================ +! +! typedef struct { +! taskList_item_t taskBuf[TASK_LIST_DEPTH]; +! taskList_item_t* task_list; +! uint8_t numTasksCur; +! uint8_t numTasksMax; +! } scheduler_vars_t; +! +! typedef struct { +! uint8_t numTasksCur; +! uint8_t numTasksMax; +! } scheduler_dbg_t; +! +! //=========================== prototypes ====================================== +! +! // public functions +! void scheduler_init(void); +! void scheduler_start(void); +! void scheduler_push_task(task_cbt task_cb, task_prio_t prio); +! +! // interrupt handlers +! void isr_ieee154e_newSlot(void); +! void isr_ieee154e_timer(void); +! void isr_adc(void); +! #ifdef ISR_GYRO +! void isr_gyro(); +! #endif +! #ifdef ISR_LARGE_RANGE_ACCEL +! void isr_large_range_accel(); +! #endif +! #ifdef ISR_BUTTON +! void isr_button(); +! #endif +! +! /** +! \} +! \} +! */ +! +! #endif +diff -crB openwsn/spi.c ../../../sys/net/openwsn/spi.c +*** openwsn/spi.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/spi.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,246 **** +! /** +! \brief TelosB-specific definition of the "spi" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "spi.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! // information about the current transaction +! uint8_t* pNextTxByte; +! uint8_t numTxedBytes; +! uint8_t txBytesLeft; +! spi_return_t returnType; +! uint8_t* pNextRxByte; +! uint8_t maxRxBytes; +! spi_first_t isFirst; +! spi_last_t isLast; +! // state of the module +! uint8_t busy; +! #ifdef SPI_IN_INTERRUPT_MODE +! // callback when module done +! spi_cbt callback; +! #endif +! } spi_vars_t; +! +! spi_vars_t spi_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void spi_init() { +! // clear variables +! memset(&spi_vars,0,sizeof(spi_vars_t)); +! +! // hold USART state machine in reset mode during configuration +! U0CTL = SWRST; // [b0] SWRST=1: Enabled. USART logic held in reset state +! +! // configure SPI-related pins +! P3SEL |= 0x02; // P3.1 in SIMO mode +! P3DIR |= 0x02; // P3.1 as output +! P3SEL |= 0x04; // P3.2 in SOMI mode +! P3DIR |= 0x04; // P3.2 as output +! P3SEL |= 0x08; // P3.3 in SCL mode +! P3DIR |= 0x08; // P3.3 as output +! P4OUT |= 0x04; // P4.2 radio CS, hold high +! P4DIR |= 0x04; // P4.2 radio CS, output +! +! // initialize USART registers +! U0CTL |= CHAR | SYNC | MM ; // [b7] 0: unused +! // [b6] 0: unused +! // [b5] I2C=0: SPI mode (not I2C) +! // [b4] CHAR=1: 8-bit data +! // [b3] LISTEN=0: Disabled +! // [b2] SYNC=1: SPI mode (not UART) +! // [b1] MM=1: USART is master +! // [b0] SWRST=x: don't change +! +! U0TCTL = CKPH | SSEL1 | STC | TXEPT; // [b7] CKPH=1: UCLK is delayed by one half cycle +! // [b6] CKPL=0: normal clock polarity +! // [b5] SSEL1=1: +! // [b4] SSEL0=0: SMCLK +! // [b3] 0: unused +! // [b2] 0: unused +! // [b1] STC=1: 3-pin SPI mode +! // [b0] TXEPT=1: UxTXBUF and TX shift register are empty +! +! U0BR1 = 0x00; +! U0BR0 = 0x02; // U0BR = [U0BR1<<8|U0BR0] = 2 +! U0MCTL = 0x00; // no modulation needed in SPI mode +! +! // enable USART module +! ME1 |= UTXE0 | URXE0; // [b7] UTXE0=1: USART0 transmit enabled +! // [b6] URXE0=1: USART0 receive enabled +! // [b5] x: don't touch! +! // [b4] x: don't touch! +! // [b3] x: don't touch! +! // [b2] x: don't touch! +! // [b1] x: don't touch! +! // [b0] x: don't touch! +! +! // clear USART state machine from reset, starting operation +! U0CTL &= ~SWRST; +! +! // enable interrupts via the IEx SFRs +! #ifdef SPI_IN_INTERRUPT_MODE +! IE1 |= URXIE0; // we only enable the SPI RX interrupt +! // since TX and RX happen concurrently, +! // i.e. an RX completion necessarily +! // implies a TX completion. +! #endif +! } +! +! #ifdef SPI_IN_INTERRUPT_MODE +! void spi_setCb(spi_cbt cb) { +! spi_vars.spi_cb = cb; +! } +! #endif +! +! void spi_txrx(uint8_t* bufTx, +! uint8_t lenbufTx, +! spi_return_t returnType, +! uint8_t* bufRx, +! uint8_t maxLenBufRx, +! spi_first_t isFirst, +! spi_last_t isLast) { +! +! #ifdef SPI_IN_INTERRUPT_MODE +! // disable interrupts +! __disable_interrupt(); +! #endif +! +! // register spi frame to send +! spi_vars.pNextTxByte = bufTx; +! spi_vars.numTxedBytes = 0; +! spi_vars.txBytesLeft = lenbufTx; +! spi_vars.returnType = returnType; +! spi_vars.pNextRxByte = bufRx; +! spi_vars.maxRxBytes = maxLenBufRx; +! spi_vars.isFirst = isFirst; +! spi_vars.isLast = isLast; +! +! // SPI is now busy +! spi_vars.busy = 1; +! +! // lower CS signal to have slave listening +! if (spi_vars.isFirst==SPI_FIRST) { +! P4OUT &= ~0x04; +! } +! +! #ifdef SPI_IN_INTERRUPT_MODE +! // implementation 1. use a callback function when transaction finishes +! +! // write first byte to TX buffer +! U0TXBUF = *spi_vars.pNextTxByte; +! +! // re-enable interrupts +! __enable_interrupt(); +! #else +! // implementation 2. busy wait for each byte to be sent +! +! // send all bytes +! while (spi_vars.txBytesLeft>0) { +! // write next byte to TX buffer +! U0TXBUF = *spi_vars.pNextTxByte; +! // busy wait on the interrupt flag +! while ((IFG1 & URXIFG0)==0); +! // clear the interrupt flag +! IFG1 &= ~URXIFG0; +! // save the byte just received in the RX buffer +! switch (spi_vars.returnType) { +! case SPI_FIRSTBYTE: +! if (spi_vars.numTxedBytes==0) { +! *spi_vars.pNextRxByte = U0RXBUF; +! } +! break; +! case SPI_BUFFER: +! *spi_vars.pNextRxByte = U0RXBUF; +! spi_vars.pNextRxByte++; +! break; +! case SPI_LASTBYTE: +! *spi_vars.pNextRxByte = U0RXBUF; +! break; +! } +! // one byte less to go +! spi_vars.pNextTxByte++; +! spi_vars.numTxedBytes++; +! spi_vars.txBytesLeft--; +! } +! +! // put CS signal high to signal end of transmission to slave +! if (spi_vars.isLast==SPI_LAST) { +! P4OUT |= 0x04; +! } +! +! // SPI is not busy anymore +! spi_vars.busy = 0; +! #endif +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! kick_scheduler_t spi_isr() { +! #ifdef SPI_IN_INTERRUPT_MODE +! // save the byte just received in the RX buffer +! switch (spi_vars.returnType) { +! case SPI_FIRSTBYTE: +! if (spi_vars.numTxedBytes==0) { +! *spi_vars.pNextRxByte = U0RXBUF; +! } +! break; +! case SPI_BUFFER: +! *spi_vars.pNextRxByte = U0RXBUF; +! spi_vars.pNextRxByte++; +! break; +! case SPI_LASTBYTE: +! *spi_vars.pNextRxByte = U0RXBUF; +! break; +! } +! +! // one byte less to go +! spi_vars.pNextTxByte++; +! spi_vars.numTxedBytes++; +! spi_vars.txBytesLeft--; +! +! if (spi_vars.txBytesLeft>0) { +! // write next byte to TX buffer +! U0TXBUF = *spi_vars.pNextTxByte; +! } else { +! // put CS signal high to signal end of transmission to slave +! if (spi_vars.isLast==SPI_LAST) { +! P4OUT |= 0x04; +! } +! // SPI is not busy anymore +! spi_vars.busy = 0; +! +! // SPI is done! +! if (spi_vars.callback!=NULL) { +! // call the callback +! spi_vars.spi_cb(); +! // kick the OS +! return KICK_SCHEDULER; +! } +! } +! return DO_NOT_KICK_SCHEDULER; +! #else +! // this should never happpen! +! +! // we can not print from within the BSP. Instead: +! // blink the error LED +! leds_error_blink(); +! // reset the board +! board_reset(); +! +! return DO_NOT_KICK_SCHEDULER; // we will not get here, statement to please compiler +! #endif +! } +--- 1,251 ---- +! /** +! \brief TelosB-specific definition of the "spi" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "spi.h" +! #include "leds.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! // information about the current transaction +! uint8_t* pNextTxByte; +! uint8_t numTxedBytes; +! uint8_t txBytesLeft; +! spi_return_t returnType; +! uint8_t* pNextRxByte; +! uint8_t maxRxBytes; +! spi_first_t isFirst; +! spi_last_t isLast; +! // state of the module +! uint8_t busy; +! #ifdef SPI_IN_INTERRUPT_MODE +! // callback when module done +! spi_cbt spi_cb; +! #endif +! } spi_vars_t; +! +! spi_vars_t spi_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void spi_init(void) { +! // clear variables +! memset(&spi_vars,0,sizeof(spi_vars_t)); +! +! // hold USART state machine in reset mode during configuration +! U0CTL = SWRST; // [b0] SWRST=1: Enabled. USART logic held in reset state +! +! // configure SPI-related pins +! P3SEL |= 0x02; // P3.1 in SIMO mode +! P3DIR |= 0x02; // P3.1 as output +! P3SEL |= 0x04; // P3.2 in SOMI mode +! P3DIR |= 0x04; // P3.2 as output +! P3SEL |= 0x08; // P3.3 in SCL mode +! P3DIR |= 0x08; // P3.3 as output +! P4OUT |= 0x04; // P4.2 radio CS, hold high +! P4DIR |= 0x04; // P4.2 radio CS, output +! +! // initialize USART registers +! U0CTL |= CHAR | SYNC | MM ; // [b7] 0: unused +! // [b6] 0: unused +! // [b5] I2C=0: SPI mode (not I2C) +! // [b4] CHAR=1: 8-bit data +! // [b3] LISTEN=0: Disabled +! // [b2] SYNC=1: SPI mode (not UART) +! // [b1] MM=1: USART is master +! // [b0] SWRST=x: don't change +! +! U0TCTL = CKPH | SSEL1 | STC | TXEPT; // [b7] CKPH=1: UCLK is delayed by one half cycle +! // [b6] CKPL=0: normal clock polarity +! // [b5] SSEL1=1: +! // [b4] SSEL0=0: SMCLK +! // [b3] 0: unused +! // [b2] 0: unused +! // [b1] STC=1: 3-pin SPI mode +! // [b0] TXEPT=1: UxTXBUF and TX shift register are empty +! +! U0BR1 = 0x00; +! U0BR0 = 0x02; // U0BR = [U0BR1<<8|U0BR0] = 2 +! U0MCTL = 0x00; // no modulation needed in SPI mode +! +! // enable USART module +! ME1 |= UTXE0 | URXE0; // [b7] UTXE0=1: USART0 transmit enabled +! // [b6] URXE0=1: USART0 receive enabled +! // [b5] x: don't touch! +! // [b4] x: don't touch! +! // [b3] x: don't touch! +! // [b2] x: don't touch! +! // [b1] x: don't touch! +! // [b0] x: don't touch! +! +! // clear USART state machine from reset, starting operation +! U0CTL &= ~SWRST; +! +! // enable interrupts via the IEx SFRs +! #ifdef SPI_IN_INTERRUPT_MODE +! IE1 |= URXIE0; // we only enable the SPI RX interrupt +! // since TX and RX happen concurrently, +! // i.e. an RX completion necessarily +! // implies a TX completion. +! #endif +! } +! +! #ifdef SPI_IN_INTERRUPT_MODE +! void spi_setCb(spi_cbt cb) { +! spi_vars.spi_cb = cb; +! } +! #endif +! +! void spi_txrx(uint8_t* bufTx, +! uint8_t lenbufTx, +! spi_return_t returnType, +! uint8_t* bufRx, +! uint8_t maxLenBufRx, +! spi_first_t isFirst, +! spi_last_t isLast) { +! +! #ifdef SPI_IN_INTERRUPT_MODE +! // disable interrupts +! __disable_interrupt(); +! #endif +! +! // register spi frame to send +! spi_vars.pNextTxByte = bufTx; +! spi_vars.numTxedBytes = 0; +! spi_vars.txBytesLeft = lenbufTx; +! spi_vars.returnType = returnType; +! spi_vars.pNextRxByte = bufRx; +! spi_vars.maxRxBytes = maxLenBufRx; +! spi_vars.isFirst = isFirst; +! spi_vars.isLast = isLast; +! +! // SPI is now busy +! spi_vars.busy = 1; +! +! // lower CS signal to have slave listening +! if (spi_vars.isFirst==SPI_FIRST) { +! P4OUT &= ~0x04; +! } +! +! #ifdef SPI_IN_INTERRUPT_MODE +! // implementation 1. use a callback function when transaction finishes +! +! // write first byte to TX buffer +! U0TXBUF = *spi_vars.pNextTxByte; +! +! // re-enable interrupts +! __enable_interrupt(); +! #else +! // implementation 2. busy wait for each byte to be sent +! +! // send all bytes +! while (spi_vars.txBytesLeft>0) { +! // write next byte to TX buffer +! U0TXBUF = *spi_vars.pNextTxByte; +! // busy wait on the interrupt flag +! uint32_t c = 0; +! while ((IFG1 & URXIFG0)==0) +! if (c++ == 1000) { +! puts("spi_txrx timeout"); +! break; +! } +! // clear the interrupt flag +! IFG1 &= ~URXIFG0; +! // save the byte just received in the RX buffer +! switch (spi_vars.returnType) { +! case SPI_FIRSTBYTE: +! if (spi_vars.numTxedBytes==0) { +! *spi_vars.pNextRxByte = U0RXBUF; +! } +! break; +! case SPI_BUFFER: +! *spi_vars.pNextRxByte = U0RXBUF; +! spi_vars.pNextRxByte++; +! break; +! case SPI_LASTBYTE: +! *spi_vars.pNextRxByte = U0RXBUF; +! break; +! } +! // one byte less to go +! spi_vars.pNextTxByte++; +! spi_vars.numTxedBytes++; +! spi_vars.txBytesLeft--; +! } +! +! // put CS signal high to signal end of transmission to slave +! if (spi_vars.isLast==SPI_LAST) { +! P4OUT |= 0x04; +! } +! +! // SPI is not busy anymore +! spi_vars.busy = 0; +! #endif +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! kick_scheduler_t spi_isr(void) { +! #ifdef SPI_IN_INTERRUPT_MODE +! // save the byte just received in the RX buffer +! switch (spi_vars.returnType) { +! case SPI_FIRSTBYTE: +! if (spi_vars.numTxedBytes==0) { +! *spi_vars.pNextRxByte = U0RXBUF; +! } +! break; +! case SPI_BUFFER: +! *spi_vars.pNextRxByte = U0RXBUF; +! spi_vars.pNextRxByte++; +! break; +! case SPI_LASTBYTE: +! *spi_vars.pNextRxByte = U0RXBUF; +! break; +! } +! +! // one byte less to go +! spi_vars.pNextTxByte++; +! spi_vars.numTxedBytes++; +! spi_vars.txBytesLeft--; +! +! if (spi_vars.txBytesLeft>0) { +! // write next byte to TX buffer +! U0TXBUF = *spi_vars.pNextTxByte; +! } else { +! // put CS signal high to signal end of transmission to slave +! if (spi_vars.isLast==SPI_LAST) { +! P4OUT |= 0x04; +! } +! // SPI is not busy anymore +! spi_vars.busy = 0; +! +! // SPI is done! +! if (spi_vars.spi_cb!=NULL) { +! // call the callback +! spi_vars.spi_cb(); +! // kick the OS +! return KICK_SCHEDULER; +! } +! } +! return DO_NOT_KICK_SCHEDULER; +! #else +! // this should never happpen! +! +! // we can not print from within the BSP. Instead: +! // blink the error LED +! leds_error_blink(); +! // reset the board +! board_reset(); +! +! return DO_NOT_KICK_SCHEDULER; // we will not get here, statement to please compiler +! #endif +! } +diff -crB openwsn/spi.h ../../../sys/net/openwsn/spi.h +*** openwsn/spi.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/spi.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,67 **** +! /** +! \brief Cross-platform declaration "spi" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __SPI_H +! #define __SPI_H +! +! #include "stdint.h" +! #include "board.h" +! +! //=========================== define ========================================== +! +! /** +! The SPI module functions in two modes: +! - in "blocking" mode, all calls return only when the module is done. the CPU +! is not available while the module is busy. This is the preferred method is +! low-RAM system which can not run an RTOS +! - in "interrupt" mode, calls are returned after the module has started a +! transaction. When the transaction is done, the module uses a callback +! function to signal this to the caller. This frees up CPU time, allowing for +! other operations to happen concurrently. This is the preferred method when an +! RTOS is present. +! */ +! //#define SPI_IN_INTERRUPT_MODE +! +! //=========================== typedef ========================================= +! +! typedef enum { +! SPI_FIRSTBYTE = 0, +! SPI_BUFFER = 1, +! SPI_LASTBYTE = 2, +! } spi_return_t; +! +! typedef enum { +! SPI_NOTFIRST = 0, +! SPI_FIRST = 1, +! } spi_first_t; +! +! typedef enum { +! SPI_NOTLAST = 0, +! SPI_LAST = 1, +! } spi_last_t; +! +! typedef void (*spi_cbt)(void); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void spi_init(); +! #ifdef SPI_IN_INTERRUPT_MODE +! void spi_setCb(spi_cbt cb); +! #endif +! void spi_txrx(uint8_t* bufTx, +! uint8_t lenbufTx, +! spi_return_t returnType, +! uint8_t* bufRx, +! uint8_t maxLenBufRx, +! spi_first_t isFirst, +! spi_last_t isLast); +! +! // interrupt handlers +! kick_scheduler_t spi_isr(); +! +! #endif +--- 1,67 ---- +! /** +! \brief Cross-platform declaration "spi" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __SPI_H +! #define __SPI_H +! +! #include "stdint.h" +! #include "board_ow.h" +! +! //=========================== define ========================================== +! +! /** +! The SPI module functions in two modes: +! - in "blocking" mode, all calls return only when the module is done. the CPU +! is not available while the module is busy. This is the preferred method is +! low-RAM system which can not run an RTOS +! - in "interrupt" mode, calls are returned after the module has started a +! transaction. When the transaction is done, the module uses a callback +! function to signal this to the caller. This frees up CPU time, allowing for +! other operations to happen concurrently. This is the preferred method when an +! RTOS is present. +! */ +! //#define SPI_IN_INTERRUPT_MODE +! +! //=========================== typedef ========================================= +! +! typedef enum { +! SPI_FIRSTBYTE = 0, +! SPI_BUFFER = 1, +! SPI_LASTBYTE = 2, +! } spi_return_t; +! +! typedef enum { +! SPI_NOTFIRST = 0, +! SPI_FIRST = 1, +! } spi_first_t; +! +! typedef enum { +! SPI_NOTLAST = 0, +! SPI_LAST = 1, +! } spi_last_t; +! +! typedef void (*spi_cbt)(void); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void spi_init(void); +! #ifdef SPI_IN_INTERRUPT_MODE +! void spi_setCb(spi_cbt cb); +! #endif +! void spi_txrx(uint8_t* bufTx, +! uint8_t lenbufTx, +! spi_return_t returnType, +! uint8_t* bufRx, +! uint8_t maxLenBufRx, +! spi_first_t isFirst, +! spi_last_t isLast); +! +! // interrupt handlers +! kick_scheduler_t spi_isr(void); +! +! #endif +diff -crB openwsn/uart.c ../../../sys/net/openwsn/uart.c +*** openwsn/uart.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/uart.c Wed Jan 15 13:48:27 2014 +*************** +*** 1,94 **** +! /** +! \brief TelosB-specific definition of the "uart" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "uart.h" +! #include "board.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! uart_tx_cbt txCb; +! uart_rx_cbt rxCb; +! } uart_vars_t; +! +! uart_vars_t uart_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void uart_init() { +! P3SEL |= 0xc0; // P3.6,7 = UART1TX/RX +! +! UCTL1 = SWRST; // hold UART1 module in reset +! UCTL1 |= CHAR; // 8-bit character +! +! /* +! // 9600 baud, clocked from 32kHz ACLK +! UTCTL1 |= SSEL0; // clocking from ACLK +! UBR01 = 0x03; // 32768/9600 = 3.41 +! UBR11 = 0x00; // +! UMCTL1 = 0x4A; // modulation +! */ +! +! // 115200 baud, clocked from 4.8MHz SMCLK +! UTCTL1 |= SSEL1; // clocking from SMCLK +! UBR01 = 41; // 4.8MHz/115200 - 41.66 +! UBR11 = 0x00; // +! UMCTL1 = 0x4A; // modulation +! +! +! ME2 |= UTXE1 + URXE1; // enable UART1 TX/RX +! UCTL1 &= ~SWRST; // clear UART1 reset bit +! } +! +! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { +! uart_vars.txCb = txCb; +! uart_vars.rxCb = rxCb; +! } +! +! void uart_enableInterrupts(){ +! IE2 |= (URXIE1 | UTXIE1); +! } +! +! void uart_disableInterrupts(){ +! IE2 &= ~(URXIE1 | UTXIE1); +! } +! +! void uart_clearRxInterrupts(){ +! IFG2 &= ~URXIFG1; +! } +! +! void uart_clearTxInterrupts(){ +! IFG2 &= ~UTXIFG1; +! } +! +! void uart_writeByte(uint8_t byteToWrite){ +! U1TXBUF = byteToWrite; +! } +! +! uint8_t uart_readByte(){ +! return U1RXBUF; +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! kick_scheduler_t uart_tx_isr() { +! uart_clearTxInterrupts(); // TODO: do not clear, but disable when done +! uart_vars.txCb(); +! return DO_NOT_KICK_SCHEDULER; +! } +! +! kick_scheduler_t uart_rx_isr() { +! uart_clearRxInterrupts(); // TODO: do not clear, but disable when done +! uart_vars.rxCb(); +! return DO_NOT_KICK_SCHEDULER; + } +\ No newline at end of file +--- 1,94 ---- +! /** +! \brief TelosB-specific definition of the "uart" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "msp430f1611.h" +! #include "uart.h" +! #include "board_ow.h" +! +! //=========================== defines ========================================= +! +! //=========================== variables ======================================= +! +! typedef struct { +! uart_tx_cbt txCb; +! uart_rx_cbt rxCb; +! } uart_vars_t; +! +! uart_vars_t uart_vars; +! +! //=========================== prototypes ====================================== +! +! //=========================== public ========================================== +! +! void uart_init_ow(void) { +! P3SEL |= 0xc0; // P3.6,7 = UART1TX/RX +! +! UCTL1 = SWRST; // hold UART1 module in reset +! UCTL1 |= CHAR; // 8-bit character +! +! /* +! // 9600 baud, clocked from 32kHz ACLK +! UTCTL1 |= SSEL0; // clocking from ACLK +! UBR01 = 0x03; // 32768/9600 = 3.41 +! UBR11 = 0x00; // +! UMCTL1 = 0x4A; // modulation +! */ +! +! // 115200 baud, clocked from 4.8MHz SMCLK +! UTCTL1 |= SSEL1; // clocking from SMCLK +! UBR01 = 41; // 4.8MHz/115200 - 41.66 +! UBR11 = 0x00; // +! UMCTL1 = 0x4A; // modulation +! +! +! ME2 |= UTXE1 + URXE1; // enable UART1 TX/RX +! UCTL1 &= ~SWRST; // clear UART1 reset bit +! } +! +! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { +! uart_vars.txCb = txCb; +! uart_vars.rxCb = rxCb; +! } +! +! void uart_enableInterrupts(void){ +! IE2 |= (URXIE1 | UTXIE1); +! } +! +! void uart_disableInterrupts(void){ +! IE2 &= ~(URXIE1 | UTXIE1); +! } +! +! void uart_clearRxInterrupts(void){ +! IFG2 &= ~URXIFG1; +! } +! +! void uart_clearTxInterrupts(void){ +! IFG2 &= ~UTXIFG1; +! } +! +! void uart_writeByte(uint8_t byteToWrite){ +! U1TXBUF = byteToWrite; +! } +! +! uint8_t uart_readByte_ow(void){ +! return U1RXBUF; +! } +! +! //=========================== private ========================================= +! +! //=========================== interrupt handlers ============================== +! +! kick_scheduler_t uart_tx_isr(void) { +! uart_clearTxInterrupts(); // TODO: do not clear, but disable when done +! uart_vars.txCb(); +! return DO_NOT_KICK_SCHEDULER; +! } +! +! kick_scheduler_t uart_rx_isr(void) { +! uart_clearRxInterrupts(); // TODO: do not clear, but disable when done +! uart_vars.rxCb(); +! return DO_NOT_KICK_SCHEDULER; + } +\ No newline at end of file +diff -crB openwsn/uart.h ../../../sys/net/openwsn/uart.h +*** openwsn/uart.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/uart.h Wed Jan 15 13:48:27 2014 +*************** +*** 1,42 **** +! /** +! \brief Cross-platform declaration "uart" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #ifndef __UART_H +! #define __UART_H +! +! #include "stdint.h" +! #include "board.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef enum { +! UART_EVENT_THRES, +! UART_EVENT_OVERFLOW, +! } uart_event_t; +! +! typedef void (*uart_tx_cbt)(); +! typedef void (*uart_rx_cbt)(); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void uart_init(); +! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb); +! void uart_enableInterrupts(); +! void uart_disableInterrupts(); +! void uart_clearRxInterrupts(); +! void uart_clearTxInterrupts(); +! void uart_writeByte(uint8_t byteToWrite); +! uint8_t uart_readByte(); +! +! // interrupt handlers +! kick_scheduler_t uart_tx_isr(); +! kick_scheduler_t uart_rx_isr(); +! +! #endif +\ No newline at end of file +--- 1,52 ---- +! #ifndef __UART_H +! #define __UART_H +! +! /** +! \addtogroup BSP +! \{ +! \addtogroup uart +! \{ +! +! \brief Cross-platform declaration "uart" bsp module. +! +! \author Thomas Watteyne , February 2012. +! */ +! +! #include "stdint.h" +! #include "board_ow.h" +! +! //=========================== define ========================================== +! +! //=========================== typedef ========================================= +! +! typedef enum { +! UART_EVENT_THRES, +! UART_EVENT_OVERFLOW, +! } uart_event_t; +! +! typedef void (*uart_tx_cbt)(void); +! typedef void (*uart_rx_cbt)(void); +! +! //=========================== variables ======================================= +! +! //=========================== prototypes ====================================== +! +! void uart_init_ow(void); +! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb); +! void uart_enableInterrupts(void); +! void uart_disableInterrupts(void); +! void uart_clearRxInterrupts(void); +! void uart_clearTxInterrupts(void); +! void uart_writeByte(uint8_t byteToWrite); +! uint8_t uart_readByte_ow(void); +! +! // interrupt handlers +! kick_scheduler_t uart_tx_isr(void); +! kick_scheduler_t uart_rx_isr(void); +! +! /** +! \} +! \} +! */ +! +! #endif diff --git a/pkg/openwsn/structure_changes.sh b/pkg/openwsn/structure_changes.sh new file mode 100755 index 000000000000..4647aa9c7a0d --- /dev/null +++ b/pkg/openwsn/structure_changes.sh @@ -0,0 +1,67 @@ +#!/usr/bin/sh + +# move openwsn stack directory up +mv openwsn-fw-RB-1.4/firmware/openos/openwsn/ ./ + +# and all needed hw dependent files too +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/spi.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/uart.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/leds.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board openwsn/board_ow.c +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board.c openwsn/board_ow.c +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board_info.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/radiotimer.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/eui64.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/debugpins.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/board.h openwsn/board_ow.h +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/debugpins.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/eui64.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/leds.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/radio.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/radiotimer.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/uart.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/chips/spi.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/chips/cc2420/radio.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/chips/cc2420/cc2420.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/drivers/common/openhdlc.* openwsn +mv openwsn-fw-RB-1.4/firmware/openos/drivers/common/opentimers.* openwsn +mv openwsn-fw-RB-1.4/firmware/openos/drivers/common/openserial.{c,h} openwsn +mv openwsn-fw-RB-1.4/firmware/openos/kernel/openos/scheduler.{c,h} openwsn + +# remove all *dox files +for i in `find ./openwsn -name "*.dox"`; do +rm -f $i +done + +rm -f openwsn/SConscript +rm -rf openwsn/02.5-MPLS + +# create empty Makefiles +touch openwsn/Makefile + +for i in `find ./openwsn -type d`; do +touch $i/Makefile +done + +# meta Makefile +cp ../Makefile.in ./ +mv ./Makefile.in ./Makefile + +# oops too many Makefiles +rm -f openwsn/07-App/rxl1/Makefile \ + openwsn/07-App/rt/Makefile \ + openwsn/07-App/rrube/Makefile \ + openwsn/07-App/rreg/Makefile \ + openwsn/07-App/rleds/Makefile \ + openwsn/07-App/rheli/Makefile \ + openwsn/07-App/rex/Makefile \ + openwsn/07-App/layerdebug/Makefile \ + openwsn/07-App/imu/Makefile \ + openwsn/07-App/heli/Makefile + +mkdir openwsn/07-App/r6tus +touch openwsn/07-App/r6tus/r6tus.c +touch openwsn/07-App/r6tus/r6tus.h + +# clean not need files +rm -rf openwsn-fw-RB-1.4 From a66846ef22490e72aae16a2a421dc020d937b4c7 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Wed, 15 Jan 2014 16:12:11 +0100 Subject: [PATCH 2/8] fixes to fit the new silence flag --- pkg/openwsn/Makefile.in | 2 +- pkg/openwsn/patch.txt | 160 ++++++++++++++++++++-------------------- 2 files changed, 81 insertions(+), 81 deletions(-) diff --git a/pkg/openwsn/Makefile.in b/pkg/openwsn/Makefile.in index 3c983301a005..2422b2c7c1d5 100644 --- a/pkg/openwsn/Makefile.in +++ b/pkg/openwsn/Makefile.in @@ -1,7 +1,7 @@ DIRS = DIRS += openwsn -all: $(BINDIR)$(MODULE) +all:: @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; # remove compilation products diff --git a/pkg/openwsn/patch.txt b/pkg/openwsn/patch.txt index f0a98980326b..a6b319c16872 100644 --- a/pkg/openwsn/patch.txt +++ b/pkg/openwsn/patch.txt @@ -5136,7 +5136,7 @@ diff -crB openwsn/02a-MAClow/Makefile ../../../sys/net/openwsn/02a-MAClow/Makefi *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -5152,15 +5152,15 @@ diff -crB openwsn/02a-MAClow/Makefile ../../../sys/net/openwsn/02a-MAClow/Makefi + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -6207,7 +6207,7 @@ diff -crB openwsn/02b-MAChigh/Makefile ../../../sys/net/openwsn/02b-MAChigh/Make *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -6223,15 +6223,15 @@ diff -crB openwsn/02b-MAChigh/Makefile ../../../sys/net/openwsn/02b-MAChigh/Make + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -10215,7 +10215,7 @@ diff -crB openwsn/03a-IPHC/Makefile ../../../sys/net/openwsn/03a-IPHC/Makefile *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -10231,15 +10231,15 @@ diff -crB openwsn/03a-IPHC/Makefile ../../../sys/net/openwsn/03a-IPHC/Makefile + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -12101,7 +12101,7 @@ diff -crB openwsn/03b-IPv6/Makefile ../../../sys/net/openwsn/03b-IPv6/Makefile *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -12117,15 +12117,15 @@ diff -crB openwsn/03b-IPv6/Makefile ../../../sys/net/openwsn/03b-IPv6/Makefile + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -15238,7 +15238,7 @@ diff -crB openwsn/04-TRAN/Makefile ../../../sys/net/openwsn/04-TRAN/Makefile *** 0 **** --- 1,42 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -15264,15 +15264,15 @@ diff -crB openwsn/04-TRAN/Makefile ../../../sys/net/openwsn/04-TRAN/Makefile + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -18632,7 +18632,7 @@ diff -crB openwsn/07-App/Makefile ../../../sys/net/openwsn/07-App/Makefile *** 0 **** --- 1,49 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -18666,7 +18666,7 @@ diff -crB openwsn/07-App/Makefile ../../../sys/net/openwsn/07-App/Makefile + @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) @@ -18674,8 +18674,8 @@ diff -crB openwsn/07-App/Makefile ../../../sys/net/openwsn/07-App/Makefile + # compile and generate dependency info + $(BINDIR)%.o: %.c + mkdir -p $(BINDIR) -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + clean:: @@ -20436,7 +20436,7 @@ diff -crB openwsn/07-App/ohlone/Makefile ../../../sys/net/openwsn/07-App/ohlone/ *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -20452,15 +20452,15 @@ diff -crB openwsn/07-App/ohlone/Makefile ../../../sys/net/openwsn/07-App/ohlone/ + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -21950,7 +21950,7 @@ diff -crB openwsn/07-App/rinfo/Makefile ../../../sys/net/openwsn/07-App/rinfo/Ma *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -21966,15 +21966,15 @@ diff -crB openwsn/07-App/rinfo/Makefile ../../../sys/net/openwsn/07-App/rinfo/Ma + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -23860,7 +23860,7 @@ diff -crB openwsn/07-App/rwellknown/Makefile ../../../sys/net/openwsn/07-App/rwe *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -23876,15 +23876,15 @@ diff -crB openwsn/07-App/rwellknown/Makefile ../../../sys/net/openwsn/07-App/rwe + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -24535,7 +24535,7 @@ diff -crB openwsn/07-App/tcpecho/Makefile ../../../sys/net/openwsn/07-App/tcpech *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -24551,15 +24551,15 @@ diff -crB openwsn/07-App/tcpecho/Makefile ../../../sys/net/openwsn/07-App/tcpech + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -24755,7 +24755,7 @@ diff -crB openwsn/07-App/tcpinject/Makefile ../../../sys/net/openwsn/07-App/tcpi *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -24771,15 +24771,15 @@ diff -crB openwsn/07-App/tcpinject/Makefile ../../../sys/net/openwsn/07-App/tcpi + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -25061,7 +25061,7 @@ diff -crB openwsn/07-App/tcpprint/Makefile ../../../sys/net/openwsn/07-App/tcppr *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -25077,15 +25077,15 @@ diff -crB openwsn/07-App/tcpprint/Makefile ../../../sys/net/openwsn/07-App/tcppr + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -25249,7 +25249,7 @@ diff -crB openwsn/07-App/udpecho/Makefile ../../../sys/net/openwsn/07-App/udpech *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -25265,15 +25265,15 @@ diff -crB openwsn/07-App/udpecho/Makefile ../../../sys/net/openwsn/07-App/udpech + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -25545,7 +25545,7 @@ diff -crB openwsn/07-App/udpinject/Makefile ../../../sys/net/openwsn/07-App/udpi *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -25561,15 +25561,15 @@ diff -crB openwsn/07-App/udpinject/Makefile ../../../sys/net/openwsn/07-App/udpi + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -25807,7 +25807,7 @@ diff -crB openwsn/07-App/udplatency/Makefile ../../../sys/net/openwsn/07-App/udp *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -25823,15 +25823,15 @@ diff -crB openwsn/07-App/udplatency/Makefile ../../../sys/net/openwsn/07-App/udp + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -26184,7 +26184,7 @@ diff -crB openwsn/07-App/udpprint/Makefile ../../../sys/net/openwsn/07-App/udppr *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -26200,15 +26200,15 @@ diff -crB openwsn/07-App/udpprint/Makefile ../../../sys/net/openwsn/07-App/udppr + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -26356,7 +26356,7 @@ diff -crB openwsn/07-App/udprand/Makefile ../../../sys/net/openwsn/07-App/udpran *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -26372,15 +26372,15 @@ diff -crB openwsn/07-App/udprand/Makefile ../../../sys/net/openwsn/07-App/udpran + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -26649,7 +26649,7 @@ diff -crB openwsn/07-App/udpstorm/Makefile ../../../sys/net/openwsn/07-App/udpst *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -26665,15 +26665,15 @@ diff -crB openwsn/07-App/udpstorm/Makefile ../../../sys/net/openwsn/07-App/udpst + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products @@ -27073,7 +27073,7 @@ diff -crB openwsn/Makefile ../../../sys/net/openwsn/Makefile *** 0 **** --- 1,57 ---- + export MODULE:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -27114,7 +27114,7 @@ diff -crB openwsn/Makefile ../../../sys/net/openwsn/Makefile + @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; + + $(BINDIR)$(MODULE): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) @@ -27122,8 +27122,8 @@ diff -crB openwsn/Makefile ../../../sys/net/openwsn/Makefile + # compile and generate dependency info + $(BINDIR)%.o: %.c + mkdir -p $(BINDIR) -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)"|cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + @@ -28431,7 +28431,7 @@ diff -crB openwsn/cross-layers/Makefile ../../../sys/net/openwsn/cross-layers/Ma *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a -+ BINDIR = $(RIOTBASE)/bin/ ++ #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) @@ -28447,15 +28447,15 @@ diff -crB openwsn/cross-layers/Makefile ../../../sys/net/openwsn/cross-layers/Ma + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) -+ $(AR) rcs $(BINDIR)$(MODULE) $(OBJ) ++ $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o -+ $(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -c $*.c -o $(BINDIR)$*.o ++ $(AD)$(CC) $(CFLAGS) $(INCLUDES) $(BOARDINCLUDE) $(PROJECTINCLUDE) $(CPUINCLUDE) -MM $*.c > $(BINDIR)$*.d + @printf "$(BINDIR)" | cat - $(BINDIR)$*.d > /tmp/riot_out && mv /tmp/riot_out $(BINDIR)$*.d + + # remove compilation products From 5c8838ce3f5cfe6a308e0df1bae8ee9e5929d712 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Wed, 15 Jan 2014 16:16:07 +0100 Subject: [PATCH 3/8] make script more verbose and deal with CRLF line endings --- pkg/openwsn/structure_changes.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/pkg/openwsn/structure_changes.sh b/pkg/openwsn/structure_changes.sh index 4647aa9c7a0d..3901b501a9bd 100755 --- a/pkg/openwsn/structure_changes.sh +++ b/pkg/openwsn/structure_changes.sh @@ -1,5 +1,6 @@ -#!/usr/bin/sh +#!/usr/bin/zsh +printf "Moving openwsn stack ..." # move openwsn stack directory up mv openwsn-fw-RB-1.4/firmware/openos/openwsn/ ./ @@ -7,7 +8,6 @@ mv openwsn-fw-RB-1.4/firmware/openos/openwsn/ ./ mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/spi.c openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/uart.c openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/leds.c openwsn -mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board openwsn/board_ow.c mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board.c openwsn/board_ow.c mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board_info.h openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/radiotimer.c openwsn @@ -27,7 +27,8 @@ mv openwsn-fw-RB-1.4/firmware/openos/drivers/common/openhdlc.* openwsn mv openwsn-fw-RB-1.4/firmware/openos/drivers/common/opentimers.* openwsn mv openwsn-fw-RB-1.4/firmware/openos/drivers/common/openserial.{c,h} openwsn mv openwsn-fw-RB-1.4/firmware/openos/kernel/openos/scheduler.{c,h} openwsn - +printf "[OK]\n" +printf "Removing files not needed ... " # remove all *dox files for i in `find ./openwsn -name "*.dox"`; do rm -f $i @@ -35,7 +36,9 @@ done rm -f openwsn/SConscript rm -rf openwsn/02.5-MPLS +printf "[OK]\n" +printf "Initialize Makefile structure ..." # create empty Makefiles touch openwsn/Makefile @@ -58,10 +61,20 @@ rm -f openwsn/07-App/rxl1/Makefile \ openwsn/07-App/layerdebug/Makefile \ openwsn/07-App/imu/Makefile \ openwsn/07-App/heli/Makefile +printf "[OK]\n" mkdir openwsn/07-App/r6tus touch openwsn/07-App/r6tus/r6tus.c touch openwsn/07-App/r6tus/r6tus.h +printf "Clean up ..." # clean not need files rm -rf openwsn-fw-RB-1.4 +printf "[OK]\n" + +printf "Remove CRLF line endings ... " +# deal with crlf line endings +for i in `find ./openwsn -type f`; do +perl -pi -e 's/\r\n/\n/g' $i +done +printf "[OK]\n" From 923b6c09afce1aaa3b24945a146e556f22f2fef6 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Thu, 16 Jan 2014 21:31:44 +0100 Subject: [PATCH 4/8] added a README with compatibility information --- pkg/openwsn/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 pkg/openwsn/README.md diff --git a/pkg/openwsn/README.md b/pkg/openwsn/README.md new file mode 100644 index 000000000000..15ef36f40523 --- /dev/null +++ b/pkg/openwsn/README.md @@ -0,0 +1,8 @@ +# Compatibility + +This port of the openwsn stack is compatible with the TelosB board only for now. +The hardware dependency will be reduced in the future and thous running on more +hardware platforms. + +A test can be found in the [projects repository](https://github.com/RIOT-OS/projects/) +named ```test_openwsn_pkg``` with an example ```Makefile```. \ No newline at end of file From f25e9f1f795564032cacc1c6229dccd85662f031 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Fri, 17 Jan 2014 17:50:23 +0100 Subject: [PATCH 5/8] fixing bug: don't reapply patch --- pkg/openwsn/Makefile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pkg/openwsn/Makefile b/pkg/openwsn/Makefile index 738e8069d2bc..3c864cfadf11 100644 --- a/pkg/openwsn/Makefile +++ b/pkg/openwsn/Makefile @@ -26,19 +26,16 @@ patch: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/ # Here you apply your patch. cd $< && sh ../structure_changes.sh - cd $< && patch -p0 -i ../patch.txt + cd $< && patch -p0 -N -i ../patch.txt $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) + rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) $(UNPACK) $< -d $(PKG_NAME)-$(PKG_VERSION) $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT): + # rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) # Get PKG_VERSION of package from PKG_URL @$(FETCH) -O $@ $(PKG_URL)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) || true -clean:: - # Reset package to checkout state. - rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) && \ - make $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile - clean:: rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) From d41b92094a223721659deb39741f574d390bea93 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Mon, 20 Jan 2014 12:34:07 +0100 Subject: [PATCH 6/8] fixes downloading the archive with each ```make -B``` --- pkg/openwsn/Makefile | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/pkg/openwsn/Makefile b/pkg/openwsn/Makefile index 3c864cfadf11..d11a230bb880 100644 --- a/pkg/openwsn/Makefile +++ b/pkg/openwsn/Makefile @@ -1,5 +1,5 @@ PKG_NAME=RB -PKG_URL=https://github.com/openwsn-berkeley/openwsn-fw/archive +PKG_URL=https://codeload.github.com/openwsn-berkeley/openwsn-fw PKG_VERSION=1.4 PKG_EXT=zip @@ -7,35 +7,34 @@ FETCH=$(shell which wget &> /dev/null && echo "wget" || echo "curl") #UNPACK=tar -xvf UNPACK=unzip +ifeq ($(FETCH),curl ) + FETCH_FLAGS += -z $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) -o +else + FETCH_FLAGS += -nc -O +endif + ifneq ($(RIOTBOARD),) #include $(RIOTBOARD)/Makefile.base include $(RIOTBOARD)/$(BOARD)/Makefile.include endif -.PHONY: all clean patch reset +.PHONY: all clean -all: patch +all: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/ make -C $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) -patch: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile - # Dependancy might be changed accordingly though we think the Makefile - # will be the first thing you want to change - # - # Here might not happen anything besides dependancy checks - -$(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/Makefile: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/ - # Here you apply your patch. - cd $< && sh ../structure_changes.sh - cd $< && patch -p0 -N -i ../patch.txt - $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION)/: $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) - rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) - $(UNPACK) $< -d $(PKG_NAME)-$(PKG_VERSION) + $(AD)rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) + $(AD)$(UNPACK) $< -d $(PKG_NAME)-$(PKG_VERSION) + $(AD)cd $@ && sh ../structure_changes.sh + $(AD)cd $@ && patch -p0 -N -i ../patch.txt $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT): - # rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) # Get PKG_VERSION of package from PKG_URL - @$(FETCH) -O $@ $(PKG_URL)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) || true + $(AD)$(FETCH) $(FETCH_FLAGS) $@ $(PKG_URL)/$(PKG_EXT)/$(PKG_NAME)-$(PKG_VERSION) || true clean:: - rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) + rm -rf $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION) + +distclean:: + rm -f $(CURDIR)/$(PKG_NAME)-$(PKG_VERSION).$(PKG_EXT) From 10cf348a6e868b1f1b2022ce39518bd82770299e Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Mon, 20 Jan 2014 12:35:19 +0100 Subject: [PATCH 7/8] fixes naming conflict with uart.(c|h) --- pkg/openwsn/patch.txt | 18 +++++++++--------- pkg/openwsn/structure_changes.sh | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/openwsn/patch.txt b/pkg/openwsn/patch.txt index a6b319c16872..341755b1e91b 100644 --- a/pkg/openwsn/patch.txt +++ b/pkg/openwsn/patch.txt @@ -27457,7 +27457,7 @@ diff -crB openwsn/board_ow.c ../../../sys/net/openwsn/board_ow.c ! #include "board_ow.h" ! ! #include "leds.h" -! #include "uart.h" +! #include "uart_ow.h" ! #include "spi.h" ! //#include "bsp_timer.h" ! #include "radio.h" @@ -32996,7 +32996,7 @@ diff -crB openwsn/openserial.c ../../../sys/net/openwsn/openserial.c ! #include "openbridge.h" ! #include "leds.h" ! #include "schedule.h" -! #include "uart.h" +! #include "uart_ow.h" ! #include "opentimers.h" ! #include "openhdlc.h" ! @@ -38113,9 +38113,9 @@ diff -crB openwsn/spi.h ../../../sys/net/openwsn/spi.h ! kick_scheduler_t spi_isr(void); ! ! #endif -diff -crB openwsn/uart.c ../../../sys/net/openwsn/uart.c -*** openwsn/uart.c Thu Mar 21 21:36:59 2013 ---- ../../../sys/net/openwsn/uart.c Wed Jan 15 13:48:27 2014 +diff -crB openwsn/uart_ow.c ../../../sys/net/openwsn/uart_ow.c +*** openwsn/uart_ow.c Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/uart_ow.c Wed Jan 15 13:48:27 2014 *************** *** 1,94 **** ! /** @@ -38221,7 +38221,7 @@ diff -crB openwsn/uart.c ../../../sys/net/openwsn/uart.c ! */ ! ! #include "msp430f1611.h" -! #include "uart.h" +! #include "uart_ow.h" ! #include "board_ow.h" ! ! //=========================== defines ========================================= @@ -38309,9 +38309,9 @@ diff -crB openwsn/uart.c ../../../sys/net/openwsn/uart.c ! return DO_NOT_KICK_SCHEDULER; } \ No newline at end of file -diff -crB openwsn/uart.h ../../../sys/net/openwsn/uart.h -*** openwsn/uart.h Thu Mar 21 21:36:59 2013 ---- ../../../sys/net/openwsn/uart.h Wed Jan 15 13:48:27 2014 +diff -crB openwsn/uart_ow.h ../../../sys/net/openwsn/uart_ow.h +*** openwsn/uart_ow.h Thu Mar 21 21:36:59 2013 +--- ../../../sys/net/openwsn/uart_ow.h Wed Jan 15 13:48:27 2014 *************** *** 1,42 **** ! /** diff --git a/pkg/openwsn/structure_changes.sh b/pkg/openwsn/structure_changes.sh index 3901b501a9bd..c2ed48c123a7 100755 --- a/pkg/openwsn/structure_changes.sh +++ b/pkg/openwsn/structure_changes.sh @@ -6,7 +6,7 @@ mv openwsn-fw-RB-1.4/firmware/openos/openwsn/ ./ # and all needed hw dependent files too mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/spi.c openwsn -mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/uart.c openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/uart.c openwsn/uart_ow.c mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/leds.c openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board.c openwsn/board_ow.c mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/telosb/board_info.h openwsn @@ -19,7 +19,7 @@ mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/eui64.h openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/leds.h openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/radio.h openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/radiotimer.h openwsn -mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/uart.h openwsn +mv openwsn-fw-RB-1.4/firmware/openos/bsp/boards/uart.h openwsn/uart_ow.h mv openwsn-fw-RB-1.4/firmware/openos/bsp/chips/spi.h openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/chips/cc2420/radio.c openwsn mv openwsn-fw-RB-1.4/firmware/openos/bsp/chips/cc2420/cc2420.h openwsn From b290ea005952323276062ab928ca8e6b10324c05 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Mon, 20 Jan 2014 13:19:07 +0100 Subject: [PATCH 8/8] fix for those fancy case sensitiv filesystems --- pkg/openwsn/patch.txt | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/pkg/openwsn/patch.txt b/pkg/openwsn/patch.txt index 341755b1e91b..f8130ea73a17 100644 --- a/pkg/openwsn/patch.txt +++ b/pkg/openwsn/patch.txt @@ -15249,16 +15249,16 @@ diff -crB openwsn/04-TRAN/Makefile ../../../sys/net/openwsn/04-TRAN/Makefile + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN -+ INCLUDES += -I$(CURDIR)/07-APP/ohlone -+ INCLUDES += -I$(CURDIR)/07-APP/tcpecho -+ INCLUDES += -I$(CURDIR)/07-APP/tcpinject -+ INCLUDES += -I$(CURDIR)/07-APP/tcpprint -+ INCLUDES += -I$(CURDIR)/07-APP/udpecho -+ INCLUDES += -I$(CURDIR)/07-APP/udpinject -+ INCLUDES += -I$(CURDIR)/07-APP/udplatency -+ INCLUDES += -I$(CURDIR)/07-APP/udpprint -+ INCLUDES += -I$(CURDIR)/07-APP/udprand -+ INCLUDES += -I$(CURDIR)/07-APP/udpstorm ++ INCLUDES += -I$(CURDIR)/07-App/ohlone ++ INCLUDES += -I$(CURDIR)/07-App/tcpecho ++ INCLUDES += -I$(CURDIR)/07-App/tcpinject ++ INCLUDES += -I$(CURDIR)/07-App/tcpprint ++ INCLUDES += -I$(CURDIR)/07-App/udpecho ++ INCLUDES += -I$(CURDIR)/07-App/udpinject ++ INCLUDES += -I$(CURDIR)/07-App/udplatency ++ INCLUDES += -I$(CURDIR)/07-App/udpprint ++ INCLUDES += -I$(CURDIR)/07-App/udprand ++ INCLUDES += -I$(CURDIR)/07-App/udpstorm + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBMOD) @@ -18643,10 +18643,10 @@ diff -crB openwsn/07-App/Makefile ../../../sys/net/openwsn/07-App/Makefile + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN -+ INCLUDES += -I$(CURDIR)/07-APP/ohlone -+ INCLUDES += -I$(CURDIR)/07-APP/tcpecho -+ INCLUDES += -I$(CURDIR)/07-APP/tcpinject -+ INCLUDES += -I$(CURDIR)/07-APP/tcpprint ++ INCLUDES += -I$(CURDIR)/07-App/ohlone ++ INCLUDES += -I$(CURDIR)/07-App/tcpecho ++ INCLUDES += -I$(CURDIR)/07-App/tcpinject ++ INCLUDES += -I$(CURDIR)/07-App/tcpprint + INCLUDES += -I$(CURDIR)/cross-layers + + DIRS += rinfo @@ -27087,18 +27087,18 @@ diff -crB openwsn/Makefile ../../../sys/net/openwsn/Makefile + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers -+ INCLUDES += -I$(CURDIR)/07-APP/rinfo -+ INCLUDES += -I$(CURDIR)/07-APP/rwellknown -+ INCLUDES += -I$(CURDIR)/07-APP/ohlone -+ INCLUDES += -I$(CURDIR)/07-APP/tcpecho -+ INCLUDES += -I$(CURDIR)/07-APP/tcpinject -+ INCLUDES += -I$(CURDIR)/07-APP/tcpprint -+ INCLUDES += -I$(CURDIR)/07-APP/udpecho -+ INCLUDES += -I$(CURDIR)/07-APP/udpinject -+ INCLUDES += -I$(CURDIR)/07-APP/udplatency -+ INCLUDES += -I$(CURDIR)/07-APP/udpprint -+ INCLUDES += -I$(CURDIR)/07-APP/udprand -+ INCLUDES += -I$(CURDIR)/07-APP/udpstorm ++ INCLUDES += -I$(CURDIR)/07-App/rinfo ++ INCLUDES += -I$(CURDIR)/07-App/rwellknown ++ INCLUDES += -I$(CURDIR)/07-App/ohlone ++ INCLUDES += -I$(CURDIR)/07-App/tcpecho ++ INCLUDES += -I$(CURDIR)/07-App/tcpinject ++ INCLUDES += -I$(CURDIR)/07-App/tcpprint ++ INCLUDES += -I$(CURDIR)/07-App/udpecho ++ INCLUDES += -I$(CURDIR)/07-App/udpinject ++ INCLUDES += -I$(CURDIR)/07-App/udplatency ++ INCLUDES += -I$(CURDIR)/07-App/udpprint ++ INCLUDES += -I$(CURDIR)/07-App/udprand ++ INCLUDES += -I$(CURDIR)/07-App/udpstorm + + + DIRS =