1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/openwsn/patch.txt

38413 lines
1.3 MiB
Plaintext
Raw Normal View History

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<6E>
! \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->length<LENGTH_CRC || ieee154e_vars.dataReceived->length>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;i<NUMSERIALRX-1;i++){
! incrementAsnOffset();
! }
! break;
! case CELLTYPE_MORESERIALRX:
! // do nothing (not even endSlot())
! break;
! default:
! // stop using serial
! openserial_stop();
! // log the error
! openserial_printCritical(COMPONENT_IEEE802154E,ERR_WRONG_CELLTYPE,
! (errorparameter_t)cellType,
! (errorparameter_t)ieee154e_vars.slotOffset);
! // abort
! endSlot();
! break;
! }
! }
!
! port_INLINE void activity_ti2() {
! // change state
! changeState(S_TXDATAPREPARE);
!
! // 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.dataToSend->payload,
! 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->length<LENGTH_CRC || ieee154e_vars.ackReceived->length>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->length<LENGTH_CRC || ieee154e_vars.dataReceived->length>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<timeReceived || currentPeriod-currentValue<RESYNCHRONIZATIONGUARD) {
! newPeriod += TsSlotDuration;
! incrementAsnOffset();
! }
! newPeriod = (PORT_TIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)newPeriod+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)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 (timeCorrection<ieee154e_stats.minCorrection) {
! ieee154e_stats.minCorrection = timeCorrection;
! }
! // update maxConnection
! if(timeCorrection>ieee154e_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->length<LENGTH_CRC || ieee154e_vars.dataReceived->length>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;j<sfInfo.numlinks;j++){
! //for each link 5Bytes
! //TimeSlot 2B
! linkInfo.tsNum = *((uint8_t*)(pkt->payload)+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;i<NUMSERIALRX-1;i++){
! incrementAsnOffset();
! }
! break;
! case CELLTYPE_MORESERIALRX:
! // do nothing (not even endSlot())
! break;
! default:
! // stop using serial
! openserial_stop();
! // log the error
! openserial_printCritical(COMPONENT_IEEE802154E,ERR_WRONG_CELLTYPE,
! (errorparameter_t)cellType,
! (errorparameter_t)ieee154e_vars.slotOffset);
! // abort
! endSlot();
! break;
! }
! }
!
! port_INLINE void activity_ti2(void) {
! // change state
! changeState(S_TXDATAPREPARE);
!
! // 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.dataToSend->payload,
! 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->length<LENGTH_CRC || ieee154e_vars.ackReceived->length>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->length<LENGTH_CRC || ieee154e_vars.dataReceived->length>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<timeReceived || currentPeriod-currentValue<RESYNCHRONIZATIONGUARD) {
! newPeriod += TsSlotDuration;
! incrementAsnOffset();
! }
! newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)newPeriod+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)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 (timeCorrection<ieee154e_stats.minCorrection) {
! ieee154e_stats.minCorrection = timeCorrection;
! }
! // update maxConnection
! if(timeCorrection>ieee154e_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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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;i<MAXNUMNEIGHBORS;i++) {
! if (neighbors_vars.neighbors[i].used==TRUE) {
! returnVal++;
! }
! }
! return returnVal;
! }
!
! /**
! \brief Retrieve my preferred parent's EUI64 address.
!
! \param [out] addressToWrite Where to write the preferred parent's address to.
! */
! bool neighbors_getPreferredParentEui64(open_addr_t* addressToWrite) {
! uint8_t i;
! bool foundPreferred;
! uint8_t numNeighbors;
! dagrank_t minRankVal;
! uint8_t minRankIdx;
!
! addressToWrite->type = ADDR_NONE;
!
! foundPreferred = FALSE;
! numNeighbors = 0;
! minRankVal = MAXDAGRANK;
! minRankIdx = MAXNUMNEIGHBORS+1;
!
! //===== step 1. Try to find preferred parent
! for (i=0; i<MAXNUMNEIGHBORS; i++) {
! if (neighbors_vars.neighbors[i].used==TRUE){
! if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) {
! memcpy(addressToWrite,&(neighbors_vars.neighbors[i].addr_64b),sizeof(open_addr_t));
! addressToWrite->type=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;i<MAXNUMNEIGHBORS;i++) {
! if (neighbors_vars.neighbors[i].used==1) {
! timeSinceHeard = ieee154e_asnDiff(&neighbors_vars.neighbors[i].asn);
! if (timeSinceHeard>KATIMEOUT) {
! // 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<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(&temp_addr_64b,i) && neighbors_vars.neighbors[i].stableNeighbor==TRUE) {
! returnVal = TRUE;
! break;
! }
! }
!
! return returnVal;
! }
!
! /**
! \brief Indicate whether some neighbor is a preferred neighbor.
!
! \param address [in] The EUI64 address of the neighbor.
!
! \returns TRUE if that neighbor is preferred, FALSE otherwise.
! */
! bool neighbors_isPreferredParent(open_addr_t* address) {
! uint8_t i;
! bool returnVal;
!
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
!
! // by default, not preferred
! returnVal = FALSE;
!
! // iterate through neighbor table
! for (i=0;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(address,i) && neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) {
! returnVal = TRUE;
! break;
! }
! }
!
! ENABLE_INTERRUPTS();
! return returnVal;
! }
!
! /**
! \brief Indicate whether some neighbor has a lower DAG rank that me.
!
! \param index [in] The index of that neighbor in the neighbor table.
!
! \returns TRUE if that neighbor has a lower DAG rank than me, FALSE otherwise.
! */
! bool neighbors_isNeighborWithLowerDAGrank(uint8_t index) {
! bool returnVal;
!
! if (neighbors_vars.neighbors[index].used==TRUE &&
! neighbors_vars.neighbors[index].DAGrank < neighbors_getMyDAGrank()) {
! returnVal = TRUE;
! } else {
! returnVal = FALSE;
! }
!
! return returnVal;
! }
!
!
! /**
! \brief Indicate whether some neighbor has a lower DAG rank that me.
!
! \param index [in] The index of that neighbor in the neighbor table.
!
! \returns TRUE if that neighbor has a lower DAG rank than me, FALSE otherwise.
! */
! bool neighbors_isNeighborWithHigherDAGrank(uint8_t index) {
! bool returnVal;
!
! if (neighbors_vars.neighbors[index].used==TRUE &&
! neighbors_vars.neighbors[index].DAGrank >= 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;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(l2_src,i)) {
!
! // this is not a new neighbor
! newNeighbor = FALSE;
!
! // update numRx, rssi, asn
! neighbors_vars.neighbors[i].numRx++;
! neighbors_vars.neighbors[i].rssi=rssi;
! memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t));
!
! // update stableNeighbor, switchStabilityCounter
! if (neighbors_vars.neighbors[i].stableNeighbor==FALSE) {
! if (neighbors_vars.neighbors[i].rssi>BADNEIGHBORMAXRSSI) {
! 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<GOODNEIGHBORMINRSSI) {
! neighbors_vars.neighbors[i].switchStabilityCounter++;
! if (neighbors_vars.neighbors[i].switchStabilityCounter>=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<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(l2_dest,i)) {
! // handle roll-over case
!
! if (neighbors_vars.neighbors[i].numTx>(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;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(&(msg->l2_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;i<MAXNUMNEIGHBORS;i++) {
! if (neighbors_vars.neighbors[i].used==TRUE) {
! // reset parent preference
! neighbors_vars.neighbors[i].parentPreference=0;
! // calculate link cost to this neighbor
! if (neighbors_vars.neighbors[i].numTxACK==0) {
! linkCost = DEFAULTLINKCOST;
! } else {
! linkCost = (uint8_t)((((float)neighbors_vars.neighbors[i].numTx)/((float)neighbors_vars.neighbors[i].numTxACK))*10.0);
! }
! tentativeDAGrank = neighbors_vars.neighbors[i].DAGrank+linkCost;
! if ( tentativeDAGrank<neighbors_vars.myDAGrank &&
! tentativeDAGrank<MAXDAGRANK) {
! // found better parent, lower my DAGrank
! neighbors_vars.myDAGrank = tentativeDAGrank;
! prefParentFound = TRUE;
! prefParentIdx = i;
! }
! }
! }
!
! // update preferred parent
! if (prefParentFound) {
! neighbors_vars.neighbors[prefParentIdx].parentPreference = MAXPREFERENCE;
! neighbors_vars.neighbors[prefParentIdx].stableNeighbor = TRUE;
! neighbors_vars.neighbors[prefParentIdx].switchStabilityCounter = 0;
! }
! }
!
! //===== debug
!
! /**
! \brief Triggers 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_neighbors() {
! debugNeighborEntry_t temp;
! neighbors_vars.debugRow=(neighbors_vars.debugRow+1)%MAXNUMNEIGHBORS;
! temp.row=neighbors_vars.debugRow;
! temp.neighborEntry=neighbors_vars.neighbors[neighbors_vars.debugRow];
! openserial_printStatus(STATUS_NEIGHBORS,(uint8_t*)&temp,sizeof(debugNeighborEntry_t));
! return TRUE;
! }
!
! void debugNetPrint_neighbors(netDebugNeigborEntry_t* out){
! uint8_t idxIn;
! uint8_t idxOut;
!
! idxOut=0;
! for (idxIn=0;idxIn<MAXNUMNEIGHBORS;idxIn++) {
! if(neighbors_vars.neighbors[idxIn].used) {
! out[idxOut].last_addr_byte = neighbors_vars.neighbors[idxIn].addr_64b.addr_64b[7];//last byte of the address; poipoi could be [0]; endianness
! out[idxOut].rssi = neighbors_vars.neighbors[idxIn].rssi;
! out[idxOut].parentPreference = neighbors_vars.neighbors[idxIn].parentPreference;
! out[idxOut].DAGrank = neighbors_vars.neighbors[idxIn].DAGrank;
! memcpy(
! &out[idxOut].asn,
! &neighbors_vars.neighbors[idxIn].asn.bytes0and1,
! sizeof(neighbors_vars.neighbors[idxIn].asn.bytes0and1)
! );
! idxOut++;
! }
! }
! }
!
! //=========================== private =========================================
!
! void registerNewNeighbor(open_addr_t* address,
! int8_t rssi,
! asn_t* asnTimestamp) {
! uint8_t i,j;
! bool iHaveAPreferedParent;
! // filter errors
! if (address->type!=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(i<MAXNUMNEIGHBORS) {
! if (neighbors_vars.neighbors[i].used==FALSE) {
! // add this neighbor
! neighbors_vars.neighbors[i].used = TRUE;
! neighbors_vars.neighbors[i].parentPreference = 0;
! // neighbors_vars.neighbors[i].stableNeighbor = FALSE;
! // Note: all new neighbors are consider stable
! neighbors_vars.neighbors[i].stableNeighbor = TRUE;
! neighbors_vars.neighbors[i].switchStabilityCounter = 0;
! memcpy(&neighbors_vars.neighbors[i].addr_64b,address,sizeof(open_addr_t));
! neighbors_vars.neighbors[i].DAGrank = DEFAULTDAGRANK;
! neighbors_vars.neighbors[i].rssi = rssi;
! neighbors_vars.neighbors[i].numRx = 1;
! neighbors_vars.neighbors[i].numTx = 0;
! neighbors_vars.neighbors[i].numTxACK = 0;
! memcpy(&neighbors_vars.neighbors[i].asn,asnTimestamp,sizeof(asn_t));
! // do I already have a preferred parent ?
! iHaveAPreferedParent = FALSE;
! for (j=0;j<MAXNUMNEIGHBORS;j++) {
! if (neighbors_vars.neighbors[j].parentPreference==MAXPREFERENCE) {
! iHaveAPreferedParent = TRUE;
! }
! }
! // if I have none, and I'm not DAGroot, the new neighbor is my preferred
! if (iHaveAPreferedParent==FALSE && idmanager_getIsDAGroot()==FALSE) {
! neighbors_vars.neighbors[i].parentPreference = MAXPREFERENCE;
! }
! break;
! }
! i++;
! }
! if (i==MAXNUMNEIGHBORS) {
! openserial_printError(COMPONENT_NEIGHBORS,ERR_NEIGHBORS_FULL,
! (errorparameter_t)MAXNUMNEIGHBORS,
! (errorparameter_t)0);
! return;
! }
! }
!
! }
!
! bool isNeighbor(open_addr_t* neighbor) {
! uint8_t i=0;
! for (i=0;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(neighbor,i)) {
! return TRUE;
! }
! }
! return FALSE;
! }
!
! void removeNeighbor(uint8_t neighborIndex) {
! neighbors_vars.neighbors[neighborIndex].used = FALSE;
! neighbors_vars.neighbors[neighborIndex].parentPreference = 0;
! neighbors_vars.neighbors[neighborIndex].stableNeighbor = FALSE;
! neighbors_vars.neighbors[neighborIndex].switchStabilityCounter = 0;
! //neighbors_vars.neighbors[neighborIndex].addr_16b.type = ADDR_NONE; // to save RAM
! neighbors_vars.neighbors[neighborIndex].addr_64b.type = ADDR_NONE;
! //neighbors_vars.neighbors[neighborIndex].addr_128b.type = ADDR_NONE; // to save RAM
! neighbors_vars.neighbors[neighborIndex].DAGrank = DEFAULTDAGRANK;
! neighbors_vars.neighbors[neighborIndex].rssi = 0;
! neighbors_vars.neighbors[neighborIndex].numRx = 0;
! neighbors_vars.neighbors[neighborIndex].numTx = 0;
! neighbors_vars.neighbors[neighborIndex].numTxACK = 0;
! neighbors_vars.neighbors[neighborIndex].asn.bytes0and1 = 0;
! neighbors_vars.neighbors[neighborIndex].asn.bytes2and3 = 0;
! neighbors_vars.neighbors[neighborIndex].asn.byte4 = 0;
! }
!
! //=========================== helpers =========================================
!
! bool isThisRowMatching(open_addr_t* address, uint8_t rowNumber) {
! switch (address->type) {
! 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;i<MAXNUMNEIGHBORS;i++) {
! if (neighbors_vars.neighbors[i].used==TRUE) {
! returnVal++;
! }
! }
! return returnVal;
! }
!
! /**
! \brief Retrieve my preferred parent's EUI64 address.
!
! \param[out] addressToWrite Where to write the preferred parent's address to.
! */
! bool neighbors_getPreferredParentEui64(open_addr_t* addressToWrite) {
! uint8_t i;
! bool foundPreferred;
! uint8_t numNeighbors;
! dagrank_t minRankVal;
! uint8_t minRankIdx;
!
! addressToWrite->type = ADDR_NONE;
!
! foundPreferred = FALSE;
! numNeighbors = 0;
! minRankVal = MAXDAGRANK;
! minRankIdx = MAXNUMNEIGHBORS+1;
!
! //===== step 1. Try to find preferred parent
! for (i=0; i<MAXNUMNEIGHBORS; i++) {
! if (neighbors_vars.neighbors[i].used==TRUE){
! if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) {
! memcpy(addressToWrite,&(neighbors_vars.neighbors[i].addr_64b),sizeof(open_addr_t));
! addressToWrite->type=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;i<MAXNUMNEIGHBORS;i++) {
! if (neighbors_vars.neighbors[i].used==1) {
! timeSinceHeard = ieee154e_asnDiff(&neighbors_vars.neighbors[i].asn);
! if (timeSinceHeard>KATIMEOUT) {
! // 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<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(&temp_addr_64b,i) && neighbors_vars.neighbors[i].stableNeighbor==TRUE) {
! returnVal = TRUE;
! break;
! }
! }
!
! return returnVal;
! }
!
! /**
! \brief Indicate whether some neighbor is a preferred neighbor.
!
! \param[in] address The EUI64 address of the neighbor.
!
! \returns TRUE if that neighbor is preferred, FALSE otherwise.
! */
! bool neighbors_isPreferredParent(open_addr_t* address) {
! uint8_t i;
! bool returnVal;
!
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
!
! // by default, not preferred
! returnVal = FALSE;
!
! // iterate through neighbor table
! for (i=0;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(address,i) && neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) {
! returnVal = TRUE;
! break;
! }
! }
!
! ENABLE_INTERRUPTS();
! return returnVal;
! }
!
! /**
! \brief Indicate whether some neighbor has a lower DAG rank that me.
!
! \param[in] index The index of that neighbor in the neighbor table.
!
! \returns TRUE if that neighbor has a lower DAG rank than me, FALSE otherwise.
! */
! bool neighbors_isNeighborWithLowerDAGrank(uint8_t index) {
! bool returnVal;
!
! if (neighbors_vars.neighbors[index].used==TRUE &&
! neighbors_vars.neighbors[index].DAGrank < neighbors_getMyDAGrank()) {
! returnVal = TRUE;
! } else {
! returnVal = FALSE;
! }
!
! return returnVal;
! }
!
!
! /**
! \brief Indicate whether some neighbor has a lower DAG rank that me.
!
! \param[in] index The index of that neighbor in the neighbor table.
!
! \returns TRUE if that neighbor has a lower DAG rank than me, FALSE otherwise.
! */
! bool neighbors_isNeighborWithHigherDAGrank(uint8_t index) {
! bool returnVal;
!
! if (neighbors_vars.neighbors[index].used==TRUE &&
! neighbors_vars.neighbors[index].DAGrank >= 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;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(l2_src,i)) {
!
! // this is not a new neighbor
! newNeighbor = FALSE;
!
! // update numRx, rssi, asn
! neighbors_vars.neighbors[i].numRx++;
! neighbors_vars.neighbors[i].rssi=rssi;
! memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t));
! //update jp
! if (joinPrioPresent==TRUE){
! neighbors_vars.neighbors[i].joinPrio=joinPrio;
! }
!
! // update stableNeighbor, switchStabilityCounter
! if (neighbors_vars.neighbors[i].stableNeighbor==FALSE) {
! if (neighbors_vars.neighbors[i].rssi>BADNEIGHBORMAXRSSI) {
! 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<GOODNEIGHBORMINRSSI) {
! neighbors_vars.neighbors[i].switchStabilityCounter++;
! if (neighbors_vars.neighbors[i].switchStabilityCounter>=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<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(l2_dest,i)) {
! // handle roll-over case
!
! if (neighbors_vars.neighbors[i].numTx>(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;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(&(msg->l2_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;i<MAXNUMNEIGHBORS;i++) {
! if (neighbors_vars.neighbors[i].used==TRUE) {
! // reset parent preference
! neighbors_vars.neighbors[i].parentPreference=0;
! // calculate link cost to this neighbor
! if (neighbors_vars.neighbors[i].numTxACK==0) {
! rankIncrease = DEFAULTLINKCOST*2*MINHOPRANKINCREASE;
! } else {
! //6TiSCH minimal draft using OF0 for rank computation
! rankIncrease = (uint16_t)((((float)neighbors_vars.neighbors[i].numTx)/((float)neighbors_vars.neighbors[i].numTxACK))*2*MINHOPRANKINCREASE);
! }
! tentativeDAGrank = neighbors_vars.neighbors[i].DAGrank+rankIncrease;
! if ( tentativeDAGrank<neighbors_vars.myDAGrank &&
! tentativeDAGrank<MAXDAGRANK) {
! // found better parent, lower my DAGrank
! neighbors_vars.myDAGrank = tentativeDAGrank;
! prefParentFound = TRUE;
! prefParentIdx = i;
! }
! }
! }
!
! // update preferred parent
! if (prefParentFound) {
! neighbors_vars.neighbors[prefParentIdx].parentPreference = MAXPREFERENCE;
! neighbors_vars.neighbors[prefParentIdx].stableNeighbor = TRUE;
! neighbors_vars.neighbors[prefParentIdx].switchStabilityCounter = 0;
! }
! }
!
! //===== debug
!
! /**
! \brief Triggers 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_neighbors(void) {
! debugNeighborEntry_t temp;
! neighbors_vars.debugRow=(neighbors_vars.debugRow+1)%MAXNUMNEIGHBORS;
! temp.row=neighbors_vars.debugRow;
! temp.neighborEntry=neighbors_vars.neighbors[neighbors_vars.debugRow];
! openserial_printStatus(STATUS_NEIGHBORS,(uint8_t*)&temp,sizeof(debugNeighborEntry_t));
! return TRUE;
! }
!
! void debugNetPrint_neighbors(netDebugNeigborEntry_t* out){
! uint8_t idxIn;
! uint8_t idxOut;
!
! idxOut=0;
! for (idxIn=0;idxIn<MAXNUMNEIGHBORS;idxIn++) {
! if(neighbors_vars.neighbors[idxIn].used) {
! out[idxOut].last_addr_byte = neighbors_vars.neighbors[idxIn].addr_64b.addr_64b[7];//last byte of the address; poipoi could be [0]; endianness
! out[idxOut].rssi = neighbors_vars.neighbors[idxIn].rssi;
! out[idxOut].parentPreference = neighbors_vars.neighbors[idxIn].parentPreference;
! out[idxOut].DAGrank = neighbors_vars.neighbors[idxIn].DAGrank;
! memcpy(
! &out[idxOut].asn,
! &neighbors_vars.neighbors[idxIn].asn.bytes0and1,
! sizeof(neighbors_vars.neighbors[idxIn].asn.bytes0and1)
! );
! idxOut++;
! }
! }
! }
!
! //=========================== private =========================================
!
! void registerNewNeighbor(open_addr_t* address,
! int8_t rssi,
! asn_t* asnTimestamp,
! bool joinPrioPresent,
! uint8_t joinPrio) {
! uint8_t i,j;
! bool iHaveAPreferedParent;
! // filter errors
! if (address->type!=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(i<MAXNUMNEIGHBORS) {
! if (neighbors_vars.neighbors[i].used==FALSE) {
! // add this neighbor
! neighbors_vars.neighbors[i].used = TRUE;
! neighbors_vars.neighbors[i].parentPreference = 0;
! // neighbors_vars.neighbors[i].stableNeighbor = FALSE;
! // Note: all new neighbors are consider stable
! neighbors_vars.neighbors[i].stableNeighbor = TRUE;
! neighbors_vars.neighbors[i].switchStabilityCounter = 0;
! memcpy(&neighbors_vars.neighbors[i].addr_64b,address,sizeof(open_addr_t));
! neighbors_vars.neighbors[i].DAGrank = DEFAULTDAGRANK;
! neighbors_vars.neighbors[i].rssi = rssi;
! neighbors_vars.neighbors[i].numRx = 1;
! neighbors_vars.neighbors[i].numTx = 0;
! neighbors_vars.neighbors[i].numTxACK = 0;
! memcpy(&neighbors_vars.neighbors[i].asn,asnTimestamp,sizeof(asn_t));
! //update jp
! if (joinPrioPresent==TRUE){
! neighbors_vars.neighbors[i].joinPrio=joinPrio;
! }
!
!
! // do I already have a preferred parent ? -- TODO change to use JP
! iHaveAPreferedParent = FALSE;
! for (j=0;j<MAXNUMNEIGHBORS;j++) {
! if (neighbors_vars.neighbors[j].parentPreference==MAXPREFERENCE) {
! iHaveAPreferedParent = TRUE;
! }
! }
! // if I have none, and I'm not DAGroot, the new neighbor is my preferred
! if (iHaveAPreferedParent==FALSE && idmanager_getIsDAGroot()==FALSE) {
! neighbors_vars.neighbors[i].parentPreference = MAXPREFERENCE;
! }
! break;
! }
! i++;
! }
! if (i==MAXNUMNEIGHBORS) {
! openserial_printError(COMPONENT_NEIGHBORS,ERR_NEIGHBORS_FULL,
! (errorparameter_t)MAXNUMNEIGHBORS,
! (errorparameter_t)0);
! return;
! }
! }
!
! }
!
! bool isNeighbor(open_addr_t* neighbor) {
! uint8_t i=0;
! for (i=0;i<MAXNUMNEIGHBORS;i++) {
! if (isThisRowMatching(neighbor,i)) {
! return TRUE;
! }
! }
! return FALSE;
! }
!
! void removeNeighbor(uint8_t neighborIndex) {
! neighbors_vars.neighbors[neighborIndex].used = FALSE;
! neighbors_vars.neighbors[neighborIndex].parentPreference = 0;
! neighbors_vars.neighbors[neighborIndex].stableNeighbor = FALSE;
! neighbors_vars.neighbors[neighborIndex].switchStabilityCounter = 0;
! //neighbors_vars.neighbors[neighborIndex].addr_16b.type = ADDR_NONE; // to save RAM
! neighbors_vars.neighbors[neighborIndex].addr_64b.type = ADDR_NONE;
! //neighbors_vars.neighbors[neighborIndex].addr_128b.type = ADDR_NONE; // to save RAM
! neighbors_vars.neighbors[neighborIndex].DAGrank = DEFAULTDAGRANK;
! neighbors_vars.neighbors[neighborIndex].rssi = 0;
! neighbors_vars.neighbors[neighborIndex].numRx = 0;
! neighbors_vars.neighbors[neighborIndex].numTx = 0;
! neighbors_vars.neighbors[neighborIndex].numTxACK = 0;
! neighbors_vars.neighbors[neighborIndex].asn.bytes0and1 = 0;
! neighbors_vars.neighbors[neighborIndex].asn.bytes2and3 = 0;
! neighbors_vars.neighbors[neighborIndex].asn.byte4 = 0;
! }
!
! //=========================== helpers =========================================
!
! bool isThisRowMatching(open_addr_t* address, uint8_t rowNumber) {
! switch (address->type) {
! 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)<<IEEE802154E_DESC_LEN_PAYLOAD_IE_SHIFT;
! payload_IE_desc.length_groupid_type |= (IEEE802154E_PAYLOAD_DESC_GROUP_ID_MLME | IEEE802154E_DESC_TYPE_LONG); //
!
! //copy header into the packet
! //little endian
! adv->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<<FLAG_TX_S)|(1<<FLAG_RX_S)|(1<<FLAG_SHARED_S);
! while(slot>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<<FLAG_TX_S)|(1<<FLAG_RX_S)|(1<<FLAG_SHARED_S)|(1<<FLAG_TIMEKEEPING_S);
! packetfunctions_reserveHeaderSize(adv,5);
! len+=5;
! //ts
! adv->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;i<MAXACTIVESLOTS;i++){
! schedule_resetEntry(&schedule_vars.scheduleBuf[i]);
! }
! schedule_vars.backoffExponent = MINBE-1;
! memset(&schedule_dbg, 0,sizeof(schedule_dbg_t));
!
! // set frame length
! schedule_setFrameLength(SUPERFRAME_LENGTH);
!
! // start at slot 0
! running_slotOffset = 0;
!
! // advertisement slot(s)
! memset(&temp_neighbor,0,sizeof(temp_neighbor));
! for (i=0;i<NUMADVSLOTS;i++) {
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_ADV, // type of slot
! FALSE, // shared?
! 0, // channel offset
! &temp_neighbor // neighbor
! );
! running_slotOffset++;
! }
!
! // shared TXRX anycast slot(s)
! memset(&temp_neighbor,0,sizeof(temp_neighbor));
! temp_neighbor.type = ADDR_ANYCAST;
! for (i=0;i<NUMSHAREDTXRX;i++) {
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_TXRX, // type of slot
! TRUE, // shared?
! 0, // channel offset
! &temp_neighbor // neighbor
! );
! running_slotOffset++;
! }
!
! // serial RX slot(s)
! memset(&temp_neighbor,0,sizeof(temp_neighbor));
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_SERIALRX, // type of slot
! FALSE, // shared?
! 0, // channel offset
! &temp_neighbor // neighbor
! );
! running_slotOffset++;
! /*
! for (i=0;i<NUMSERIALRX-1;i++) {
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_MORESERIALRX, // type of slot
! FALSE, // shared?
! 0, // channel offset
! &temp_neighbor // neighbor
! );
! running_slotOffset++;
! }
! */
! }
!
! /**
! \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_schedule() {
! debugScheduleEntry_t temp;
! schedule_vars.debugPrintRow = (schedule_vars.debugPrintRow+1)%MAXACTIVESLOTS;
! temp.row = schedule_vars.debugPrintRow;
! //copy element by element to the struct that will be serialized. we don't want to sent the pointer through the serial port.
! temp.scheduleEntry.channelOffset = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].channelOffset;
! temp.scheduleEntry.numRx = schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numRx;
! temp.scheduleEntry.numTx=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTx;
! temp.scheduleEntry.numTxACK=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTxACK;
! temp.scheduleEntry.lastUsedAsn=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].lastUsedAsn;
! temp.scheduleEntry.neighbor=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].neighbor;
! temp.scheduleEntry.shared=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].shared;
! temp.scheduleEntry.slotOffset=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].slotOffset;
! temp.scheduleEntry.type=schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].type;
!
! openserial_printStatus(STATUS_SCHEDULE,
! (uint8_t*)&temp,
! sizeof(debugScheduleEntry_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_backoff() {
! uint8_t temp[2];
! temp[0] = schedule_vars.backoffExponent;
! temp[1] = schedule_vars.backoff;
! openserial_printStatus(STATUS_BACKOFF,
! (uint8_t*)&temp,
! sizeof(temp));
! return TRUE;
! }
!
! //=== from uRES (writing the schedule)
!
! /**
! \brief Set frame length.
!
! \param newFrameLength The new frame length.
! */
! void schedule_setFrameLength(frameLength_t newFrameLength) {
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! schedule_vars.frameLength = newFrameLength;
! ENABLE_INTERRUPTS();
! }
!
! /**
! \brief Add a new active slot into the schedule.
!
! \param newFrameLength The new frame length.
! */
! void schedule_addActiveSlot(slotOffset_t slotOffset,
! cellType_t type,
! bool shared,
! uint8_t channelOffset,
! open_addr_t* neighbor) {
! 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]) {
! 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.backoffExponent<MAXBE) {
! schedule_vars.backoffExponent++;
! }
! // set the backoff to a random value in [0..2^BE]
! schedule_vars.backoff = openrandom_get16b()%(1<<schedule_vars.backoffExponent);
! }
! }
!
! ENABLE_INTERRUPTS();
! }
!
! void schedule_getNetDebugInfo(netDebugScheduleEntry_t* schlist){
! uint8_t i;
!
! for (i=0;i<MAXACTIVESLOTS;i++){
! schlist[i].last_addr_byte=schedule_vars.scheduleBuf[i].neighbor.addr_64b[7];
! schlist[i].slotOffset=(uint8_t)schedule_vars.scheduleBuf[i].slotOffset&0xFF;
! schlist[i].channelOffset=schedule_vars.scheduleBuf[i].channelOffset;
! }
! }
! //=========================== private =========================================
!
! void schedule_resetEntry(scheduleEntry_t* pScheduleEntry) {
! pScheduleEntry->type = 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;i<MAXACTIVESLOTS;i++) {
! schedule_resetEntry(&schedule_vars.scheduleBuf[i]);
! }
! schedule_vars.backoffExponent = MINBE-1;
! memset(&schedule_dbg, 0,sizeof(schedule_dbg_t));
!
! // set frame length
! schedule_setFrameLength(SUPERFRAME_LENGTH);
!
! // start at slot 0
! running_slotOffset = 0;
!
! // advertisement slot(s)
! memset(&temp_neighbor,0,sizeof(temp_neighbor));
! for (i=0;i<NUMADVSLOTS;i++) {
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_ADV, // type of slot
! FALSE, // shared?
! 0, // channel offset
! &temp_neighbor, // neighbor
! FALSE //no update but insert
! );
! running_slotOffset++;
! }
!
! // shared TXRX anycast slot(s)
! memset(&temp_neighbor,0,sizeof(temp_neighbor));
! temp_neighbor.type = ADDR_ANYCAST;
! for (i=0;i<NUMSHAREDTXRX;i++) {
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_TXRX, // type of slot
! TRUE, // shared?
! 0, // channel offset
! &temp_neighbor, // neighbor
! FALSE //no update but insert
! );
! running_slotOffset++;
! }
!
! // serial RX slot(s)
! memset(&temp_neighbor,0,sizeof(temp_neighbor));
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_SERIALRX, // type of slot
! FALSE, // shared?
! 0, // channel offset
! &temp_neighbor, // neighbor
! FALSE //no update but insert
! );
! running_slotOffset++;
! /*
! for (i=0;i<NUMSERIALRX-1;i++) {
! schedule_addActiveSlot(
! running_slotOffset, // slot offset
! CELLTYPE_MORESERIALRX, // type of slot
! FALSE, // shared?
! 0, // channel offset
! &temp_neighbor // neighbor
! );
! running_slotOffset++;
! }
! */
! }
!
! /**
! \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_schedule(void) {
! debugScheduleEntry_t temp;
!
! schedule_vars.debugPrintRow = (schedule_vars.debugPrintRow+1)%MAXACTIVESLOTS;
!
! temp.row = schedule_vars.debugPrintRow;
! temp.slotOffset = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].slotOffset;
! temp.type = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].type;
! temp.shared = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].shared;
! temp.channelOffset = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].channelOffset;
! memcpy(
! &temp.neighbor,
! &schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].neighbor,
! sizeof(open_addr_t)
! );
! temp.numRx = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numRx;
! temp.numTx = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTx;
! temp.numTxACK = \
! schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].numTxACK;
! memcpy(
! &temp.lastUsedAsn,
! &schedule_vars.scheduleBuf[schedule_vars.debugPrintRow].lastUsedAsn,
! sizeof(asn_t)
! );
!
! openserial_printStatus(STATUS_SCHEDULE,
! (uint8_t*)&temp,
! sizeof(debugScheduleEntry_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_backoff(void) {
! uint8_t temp[2];
! temp[0] = schedule_vars.backoffExponent;
! temp[1] = schedule_vars.backoff;
! openserial_printStatus(STATUS_BACKOFF,
! (uint8_t*)&temp,
! sizeof(temp));
! return TRUE;
! }
!
! //=== from uRES (writing the schedule)
!
! /**
! \brief Set frame length.
!
! \param newFrameLength The new frame length.
! */
! void schedule_setFrameLength(frameLength_t newFrameLength) {
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! schedule_vars.frameLength = newFrameLength;
! ENABLE_INTERRUPTS();
! }
!
! /**
! \brief get the information of a spcific slot.
!
! \param slotOffset
! \param neighbor
! \param info
! */
! void schedule_getSlotInfo(
! slotOffset_t slotOffset,
! open_addr_t* neighbor,
! slotinfo_element_t* info
! ){
!
! scheduleEntry_t* slotContainer;
!
! // 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 (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.backoffExponent<MAXBE) {
! schedule_vars.backoffExponent++;
! }
! // set the backoff to a random value in [0..2^BE]
! schedule_vars.backoff = openrandom_get16b()%(1<<schedule_vars.backoffExponent);
! }
! }
!
! ENABLE_INTERRUPTS();
! }
!
! void schedule_getNetDebugInfo(netDebugScheduleEntry_t* schlist){
! uint8_t i;
!
! for (i=0;i<MAXACTIVESLOTS;i++){
! schlist[i].last_addr_byte=schedule_vars.scheduleBuf[i].neighbor.addr_64b[7];
! schlist[i].slotOffset=(uint8_t)schedule_vars.scheduleBuf[i].slotOffset&0xFF;
! schlist[i].channelOffset=schedule_vars.scheduleBuf[i].channelOffset;
! }
! }
! //=========================== private =========================================
!
! void schedule_resetEntry(scheduleEntry_t* pScheduleEntry) {
! pScheduleEntry->type = 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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;nbrIdx<MAXNUMNEIGHBORS;nbrIdx++) {
! if ((neighbors_isNeighborWithLowerDAGrank(nbrIdx))==TRUE) {
! // this neighbor is of lower DAGrank as I am
!
! // write it's address in DAO
! //packetfunctions_reserveHeaderSize(msg,LENGTH_ADDR64b);
! neighbors_getNeighbor(&address,ADDR_64B,nbrIdx);
! packetfunctions_writeAddress(msg,&address,BIG_ENDIAN);
!
!
! // update transit info fields
! //size of the whole option in bytes.
! icmpv6rpl_vars.dao_transit.optionLength = LENGTH_ADDR64b + sizeof(icmpv6rpl_dao_transit_ht);
! icmpv6rpl_vars.dao_transit.PathControl=0; //todo. this is to set the preference of this parent.
! icmpv6rpl_vars.dao_transit.type=OPTION_TRANSIT_INFORMATION_TYPE;
!
! // write transit info in packet
! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_transit_ht));
! memcpy(
! ((icmpv6rpl_dao_transit_ht*)(msg->payload)),
! &(icmpv6rpl_vars.dao_transit),
! sizeof(icmpv6rpl_dao_transit_ht)
! );
!
! // remember I found it
! numTransitParents++;
! }
! }
!
! //target information is required. RFC 6550 page 55.
! /*
! One or more Transit Information options MUST be preceded by one or
! more RPL Target options.
! */
! numTargetParents = 0;
! for (nbrIdx=0;nbrIdx<MAXNUMNEIGHBORS;nbrIdx++) {
! if ((neighbors_isNeighborWithHigherDAGrank(nbrIdx))==TRUE) {
! // this neighbor is of higher DAGrank as I am. so it is my child
!
! // write it's address in DAO RFC6550 page 80 check point 1.
! neighbors_getNeighbor(&address,ADDR_64B,nbrIdx);
! packetfunctions_writeAddress(msg,&address,BIG_ENDIAN);
!
! // update target info fields
! icmpv6rpl_vars.dao_target.optionLength = LENGTH_ADDR64b + sizeof(icmpv6rpl_dao_target_ht);
! icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE;
! icmpv6rpl_vars.dao_target.flags = 0; //must be 0
! icmpv6rpl_vars.dao_target.prefixLength = 0; //no prefix.
!
! // write transit info in packet
! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_target_ht));
! memcpy(
! ((icmpv6rpl_dao_target_ht*)(msg->payload)),
! &(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;nbrIdx<MAXNUMNEIGHBORS;nbrIdx++) {
! if ((neighbors_isNeighborWithHigherDAGrank(nbrIdx))==TRUE) {
! // this neighbor is of higher DAGrank as I am. so it is my child
!
! // write it's address in DAO RFC6550 page 80 check point 1.
! neighbors_getNeighbor(&address,ADDR_64B,nbrIdx);
! packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN);
! prefix=idmanager_getMyID(ADDR_PREFIX);
! packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN);
!
! // update target info fields
! // from rfc6550 p.55 -- Variable, length of the option in octets excluding the Type and Length fields.
! // poipoi xv: assuming that type and length fields refer to the 2 first bytes of the header
! icmpv6rpl_vars.dao_target.optionLength = LENGTH_ADDR128b +sizeof(icmpv6rpl_dao_target_ht) - 2; //no header type and length
! icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE;
! icmpv6rpl_vars.dao_target.flags = 0; //must be 0
! icmpv6rpl_vars.dao_target.prefixLength = 128; //128 leading bits -- full address.
!
! // write transit info in packet
! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_target_ht));
! memcpy(
! ((icmpv6rpl_dao_target_ht*)(msg->payload)),
! &(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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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;i<MAX_COAP_OPTIONS;i++) {
! coap_options[i].type = COAP_OPTION_NONE;
! }
! // fill in the coap_options
! last_option = COAP_OPTION_NONE;
! for (i=0;i<coap_header.OC;i++) {
! 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;
! }
! // 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;i<MAX_COAP_OPTIONS;i++) {
! coap_options[i].type = COAP_OPTION_NONE;
! }
! // fill in the coap_options
! last_option = COAP_OPTION_NONE;
! for (i=0;i<MAX_COAP_OPTIONS;i++) {
! if (msg->payload[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
2014-01-15 16:12:11 +01:00
+ #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 || exit 1; done ;
+
+ $(BINDIR)$(SUBMOD): $(OBJ)
2014-01-15 16:12:11 +01:00
+ $(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
+ mkdir -p $(BINDIR)
2014-01-15 16:12:11 +01:00
+ $(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::
+ @for i in $(DIRS) ; do "$(MAKE)" -C $$i clean || exit 1; 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>",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("<Button-1>",gui_clicked)
! buttonCanvas.bind("<Button-2>",gui_clicked)
! buttonCanvas.bind("<Button-3>",gui_clicked)
! buttonCanvas.create_rectangle(100, 0,200,100,fill="blue")
! buttonCanvas.create_text(150,50,text="up <i>")
! buttonCanvas.create_rectangle( 0,100,100,200,fill="blue")
! buttonCanvas.create_text(50,150,text="left <j>")
! buttonCanvas.create_rectangle(200,100,300,200,fill="blue")
! buttonCanvas.create_text(250,150,text="right <l>")
! buttonCanvas.create_rectangle(100,200,200,300,fill="blue")
! buttonCanvas.create_text(150,250,text="down <k>")
! buttonCanvas.create_oval(120,120,180,180,fill="red")
! buttonCanvas.create_text(150,150,text="stop!\n<space>")
! buttonCanvas.create_oval(220, 20,280, 80,fill="green")
! buttonCanvas.create_text(250, 50,text="takeoff <a>")
! buttonCanvas.create_oval(220,220,280,280,fill="green")
! buttonCanvas.create_text(250,250,text="land <q>")
!
! 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>",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("<Button-1>",gui_clicked)
! buttonCanvas.bind("<Button-2>",gui_clicked)
! buttonCanvas.bind("<Button-3>",gui_clicked)
! buttonCanvas.create_rectangle(100, 0,200,100,fill="blue")
! buttonCanvas.create_text(150,50,text="up <i>")
! buttonCanvas.create_rectangle( 0,100,100,200,fill="blue")
! buttonCanvas.create_text(50,150,text="left <j>")
! buttonCanvas.create_rectangle(200,100,300,200,fill="blue")
! buttonCanvas.create_text(250,150,text="right <l>")
! buttonCanvas.create_rectangle(100,200,200,300,fill="blue")
! buttonCanvas.create_text(150,250,text="down <k>")
! buttonCanvas.create_oval(120,120,180,180,fill="red")
! buttonCanvas.create_text(150,150,text="stop!\n<space>")
! buttonCanvas.create_oval(220, 20,280, 80,fill="green")
! buttonCanvas.create_text(250, 50,text="takeoff <a>")
! buttonCanvas.create_oval(220,220,280,280,fill="green")
! buttonCanvas.create_text(250,250,text="land <q>")
!
! 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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_index<msg->length-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_index<msg->length-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 <mehtank@eecs.berkeley.edu>, 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 <mehtank@eecs.berkeley.edu>, 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 <mehtank@eecs.berkeley.edu>, 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 <mehtank@eecs.berkeley.edu>, 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 <xvilajosana@eecs.berkeley.edu>, 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->numelem<R6TUS_MAXRESPONSES) {
+ for (i=0;i<link_command->numelem;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->numelem<R6TUS_MAXRESPONSES){
+ for(i=0;i<link_command->numelem;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 <xvilajosana@eecs.berkeley.edu>, 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;i<PAYLOADLEN;i++) {
! pkt->payload[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;i<PAYLOADLEN;i++) {
! pkt->payload[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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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[] = "</led>;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[] = "</led>;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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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
2014-01-15 16:12:11 +01:00
+ #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 || exit 1; done ;
+
+ $(BINDIR)$(MODULE): $(OBJ)
2014-01-15 16:12:11 +01:00
+ $(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
+ mkdir -p $(BINDIR)
2014-01-15 16:12:11 +01:00
+ $(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
+ clean::
+ @for i in $(DIRS) ; do "$(MAKE)" -C $$i clean || exit 1; 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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"
2014-01-20 12:35:19 +01:00
! #include "uart_ow.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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <signal.h>
! #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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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
2014-01-15 16:12:11 +01:00
+ #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)
2014-01-15 16:12:11 +01:00
+ $(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
2014-01-15 16:12:11 +01:00
+ $(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
+
+ 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<QUEUELENGTH;i++){
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! }
! }
!
! /**
! \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_queue() {
! debugOpenQueueEntry_t output[QUEUELENGTH];
! uint8_t i;
! for (i=0;i<QUEUELENGTH;i++) {
! output[i].creator = openqueue_vars.queue[i].creator;
! output[i].owner = openqueue_vars.queue[i].owner;
! }
! openserial_printStatus(STATUS_QUEUE,(uint8_t*)&output,QUEUELENGTH*sizeof(debugOpenQueueEntry_t));
! return TRUE;
! }
!
! //======= called by any component
!
! /**
! \brief Request a new (free) packet buffer.
!
! Component throughout the protocol stack can call this function is they want to
! get a new packet buffer to start creating a new packet.
!
! \note Once a packet has been allocated, it is up to the creator of the packet
! to free it using the openqueue_freePacketBuffer() function.
!
! \returns A pointer to the queue entry when it could be allocated, or NULL when
! it could not be allocated (buffer full or not synchronized).
! */
! OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
!
! // refuse to allocate if we're not in sync
! if (ieee154e_isSynch()==FALSE && creator > 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;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_NULL) {
! openqueue_vars.queue[i].creator=creator;
! openqueue_vars.queue[i].owner=COMPONENT_OPENQUEUE;
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
!
! /**
! \brief Free a previously-allocated packet buffer.
!
! \param pkt A pointer to the previsouly-allocated packet buffer.
!
! \returns E_SUCCESS when the freeing was succeful.
! \returns E_FAIL when the module could not find the specified packet buffer.
! */
! error_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (&openqueue_vars.queue[i]==pkt) {
! if (openqueue_vars.queue[i].owner==COMPONENT_NULL) {
! // log the error
! openserial_printCritical(COMPONENT_OPENQUEUE,ERR_FREEING_UNUSED,
! (errorparameter_t)0,
! (errorparameter_t)0);
! }
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! ENABLE_INTERRUPTS();
! return E_SUCCESS;
! }
! }
! // log the error
! openserial_printCritical(COMPONENT_OPENQUEUE,ERR_FREEING_ERROR,
! (errorparameter_t)0,
! (errorparameter_t)0);
! ENABLE_INTERRUPTS();
! return E_FAIL;
! }
!
! /**
! \brief Free all the packet buffers created by a specific module.
!
! \param owner The identifier of the component, taken in COMPONENT_*.
! */
! void openqueue_removeAllCreatedBy(uint8_t creator) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++){
! if (openqueue_vars.queue[i].creator==creator) {
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! }
! }
! ENABLE_INTERRUPTS();
! }
!
! /**
! \brief Free all the packet buffers owned by a specific module.
!
! \param owner The identifier of the component, taken in COMPONENT_*.
! */
! void openqueue_removeAllOwnedBy(uint8_t owner) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++){
! if (openqueue_vars.queue[i].owner==owner) {
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! }
! }
! ENABLE_INTERRUPTS();
! }
!
! //======= called by RES
!
! OpenQueueEntry_t* openqueue_resGetSentPacket() {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_IEEE802154E_TO_RES &&
! openqueue_vars.queue[i].creator!=COMPONENT_IEEE802154E) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! OpenQueueEntry_t* openqueue_resGetReceivedPacket() {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_IEEE802154E_TO_RES &&
! openqueue_vars.queue[i].creator==COMPONENT_IEEE802154E) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! //======= called by IEEE80215E
!
! OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! if (toNeighbor->type==ADDR_64B) {
! // a neighbor is specified, look for a packet unicast to that neigbhbor
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
! packetfunctions_sameAddress(toNeighbor,&openqueue_vars.queue[i].l2_nextORpreviousHop)) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! } else if (toNeighbor->type==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;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
! ( openqueue_vars.queue[i].creator!=COMPONENT_RES ||
! (
! openqueue_vars.queue[i].creator==COMPONENT_RES &&
! packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))==FALSE
! )
! )
! ) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! OpenQueueEntry_t* openqueue_macGetAdvPacket() {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
! openqueue_vars.queue[i].creator==COMPONENT_RES &&
! packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! //=========================== private =========================================
!
! void openqueue_reset_entry(OpenQueueEntry_t* entry) {
! //admin
! entry->creator = 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<QUEUELENGTH;i++){
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! }
! }
!
! /**
! \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_queue(void) {
! debugOpenQueueEntry_t output[QUEUELENGTH];
! uint8_t i;
! for (i=0;i<QUEUELENGTH;i++) {
! output[i].creator = openqueue_vars.queue[i].creator;
! output[i].owner = openqueue_vars.queue[i].owner;
! }
! openserial_printStatus(STATUS_QUEUE,(uint8_t*)&output,QUEUELENGTH*sizeof(debugOpenQueueEntry_t));
! return TRUE;
! }
!
! //======= called by any component
!
! /**
! \brief Request a new (free) packet buffer.
!
! Component throughout the protocol stack can call this function is they want to
! get a new packet buffer to start creating a new packet.
!
! \note Once a packet has been allocated, it is up to the creator of the packet
! to free it using the openqueue_freePacketBuffer() function.
!
! \returns A pointer to the queue entry when it could be allocated, or NULL when
! it could not be allocated (buffer full or not synchronized).
! */
! OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
!
! // refuse to allocate if we're not in sync
! if (ieee154e_isSynch()==FALSE && creator > 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;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_NULL) {
! openqueue_vars.queue[i].creator=creator;
! openqueue_vars.queue[i].owner=COMPONENT_OPENQUEUE;
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
!
! /**
! \brief Free a previously-allocated packet buffer.
!
! \param pkt A pointer to the previsouly-allocated packet buffer.
!
! \returns E_SUCCESS when the freeing was succeful.
! \returns E_FAIL when the module could not find the specified packet buffer.
! */
! owerror_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (&openqueue_vars.queue[i]==pkt) {
! if (openqueue_vars.queue[i].owner==COMPONENT_NULL) {
! // log the error
! openserial_printCritical(COMPONENT_OPENQUEUE,ERR_FREEING_UNUSED,
! (errorparameter_t)0,
! (errorparameter_t)0);
! }
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! ENABLE_INTERRUPTS();
! return E_SUCCESS;
! }
! }
! // log the error
! openserial_printCritical(COMPONENT_OPENQUEUE,ERR_FREEING_ERROR,
! (errorparameter_t)0,
! (errorparameter_t)0);
! ENABLE_INTERRUPTS();
! return E_FAIL;
! }
!
! /**
! \brief Free all the packet buffers created by a specific module.
!
! \param creator The identifier of the component, taken in COMPONENT_*.
! */
! void openqueue_removeAllCreatedBy(uint8_t creator) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++){
! if (openqueue_vars.queue[i].creator==creator) {
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! }
! }
! ENABLE_INTERRUPTS();
! }
!
! /**
! \brief Free all the packet buffers owned by a specific module.
!
! \param owner The identifier of the component, taken in COMPONENT_*.
! */
! void openqueue_removeAllOwnedBy(uint8_t owner) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++){
! if (openqueue_vars.queue[i].owner==owner) {
! openqueue_reset_entry(&(openqueue_vars.queue[i]));
! }
! }
! ENABLE_INTERRUPTS();
! }
!
! //======= called by RES
!
! OpenQueueEntry_t* openqueue_resGetSentPacket(void) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_IEEE802154E_TO_RES &&
! openqueue_vars.queue[i].creator!=COMPONENT_IEEE802154E) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! OpenQueueEntry_t* openqueue_resGetReceivedPacket(void) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_IEEE802154E_TO_RES &&
! openqueue_vars.queue[i].creator==COMPONENT_IEEE802154E) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! //======= called by IEEE80215E
!
! OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! if (toNeighbor->type==ADDR_64B) {
! // a neighbor is specified, look for a packet unicast to that neigbhbor
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
! packetfunctions_sameAddress(toNeighbor,&openqueue_vars.queue[i].l2_nextORpreviousHop)) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! } else if (toNeighbor->type==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;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
! ( openqueue_vars.queue[i].creator!=COMPONENT_RES ||
! (
! openqueue_vars.queue[i].creator==COMPONENT_RES &&
! packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))==FALSE
! )
! )
! ) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! OpenQueueEntry_t* openqueue_macGetAdvPacket(void) {
! uint8_t i;
! INTERRUPT_DECLARATION();
! DISABLE_INTERRUPTS();
! for (i=0;i<QUEUELENGTH;i++) {
! if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
! openqueue_vars.queue[i].creator==COMPONENT_RES &&
! packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))) {
! ENABLE_INTERRUPTS();
! return &openqueue_vars.queue[i];
! }
! }
! ENABLE_INTERRUPTS();
! return NULL;
! }
!
! //=========================== private =========================================
!
! void openqueue_reset_entry(OpenQueueEntry_t* entry) {
! //admin
! entry->creator = 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)<<i;
! random_vars.shift_reg = (random_vars.shift_reg>>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)<<i;
! random_vars.shift_reg = (random_vars.shift_reg>>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;i<address_length;i++) {
! if (address->addr_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;i<address_length;i++) {
! if (littleEndian) {
! writeToAddress->addr_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;i<address_length;i++) {
! msg->payload -= 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;count<msg->length-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;count<msg->length-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;i<address_length;i++) {
! if (address->addr_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;i<address_length;i++) {
! if (littleEndian) {
! writeToAddress->addr_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;i<address_length;i++) {
! msg->payload -= 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;count<msg->length-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;count<msg->length-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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, February 2012.
! */
! #include <stdint.h> // 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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<startTime+delay);
! }
!
! //===== pin
!
! void owpin_init() {
! P2DIR &= ~PIN_1WIRE; // set as input
! P2OUT &= ~PIN_1WIRE; // pull low
! }
!
! void owpin_output_low() {
! P2DIR |= PIN_1WIRE; // set as output
! }
!
! void owpin_output_high() {
! P2DIR &= ~PIN_1WIRE; // set as input
! }
!
! void owpin_prepare_read() {
! P2DIR &= ~PIN_1WIRE; // set as input
! }
!
! uint8_t owpin_read() {
! return (P2IN & PIN_1WIRE);
}
\ No newline at end of file
--- 1,218 ----
! /**
! \brief TelosB-specific definition of the "eui64" bsp module.
!
! \author Thomas Watteyne <watteyne@eecs.berkeley.edu>, 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<startTime+delay);
! }
!
! //===== pin
!
! void owpin_init(void) {
! P2DIR &= ~PIN_1WIRE; // set as input
! P2OUT &= ~PIN_1WIRE; // pull low
! }
!
! void owpin_output_low(void) {
! P2DIR |= PIN_1WIRE; // set as output
! }
!
! void owpin_output_high(void) {
! P2DIR &= ~PIN_1WIRE; // set as input
! }
!
! void owpin_prepare_read(void) {
! P2DIR &= ~PIN_1WIRE; // set as input
! }
!
! uint8_t owpin_read(void) {
! return (P2IN & PIN_1WIRE);
}
\ No newline at end of file
diff -crB openwsn/eui64.h ../../../sys/net/openwsn/eui64.h
*** openwsn/eui64.h Thu Mar 21 21:36:59 2013
--- ../../../sys/net/openwsn/eui64.h Wed Jan 15 13:48:27 2014
***************
*** 1,22 ****
! /**
! \brief Cross-platform declaration "eui64" bsp module.
!
! \author Thomas Watteyne <watteyne@eecs.berkeley.edu>, March 2012.
! */
!
! #ifndef __EUI64_H
! #define __EUI64_H
!
! #include <stdint.h>
!
! //=========================== 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 <watteyne@eecs.berkeley.edu>, March 2012.
! */
!
! #include <stdint.h>
!
! //=========================== 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <tingm417@gmail.com>, October 2012.
! \author Fabien Chraim <chraim@eecs.berkeley.edu>, 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 <tingm417@gmail.com>, October 2012.
! \author Fabien Chraim <chraim@eecs.berkeley.edu>, 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 <tingm417@gmail.com>, October 2012.
! \author Fabien Chraim <chraim@eecs.berkeley.edu>, 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 <tingm417@gmail.com>, October 2012.
! \author Fabien Chraim <chraim@eecs.berkeley.edu>, 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 <chraim@eecs.berkeley.edu>, 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;i<length;i++){
! outputHdlcWrite(buffer[i]);
! }
! outputHdlcClose();
! ENABLE_INTERRUPTS();
!
! return E_SUCCESS;
! }
!
! error_t openserial_printInfoErrorCritical(
! char severity,
! uint8_t calling_component,
! uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2
! ) {
! INTERRUPT_DECLARATION();
!
! DISABLE_INTERRUPTS();
! openserial_vars.outputBufFilled = TRUE;
! outputHdlcOpen();
! outputHdlcWrite(severity);
! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_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;i<length;i++){
! outputHdlcWrite(buffer[i]);
! }
! outputHdlcClose();
! ENABLE_INTERRUPTS();
!
! return E_SUCCESS;
! }
!
! error_t openserial_printInfo(uint8_t calling_component, uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2) {
! return openserial_printInfoErrorCritical(
! SERFRAME_MOTE2PC_INFO,
! calling_component,
! error_code,
! arg1,
! arg2
! );
! }
!
! error_t openserial_printError(uint8_t calling_component, uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2) {
! // blink error LED, this is serious
! leds_error_toggle();
!
! return openserial_printInfoErrorCritical(
! SERFRAME_MOTE2PC_ERROR,
! calling_component,
! error_code,
! arg1,
! arg2
! );
! }
!
! error_t openserial_printCritical(uint8_t calling_component, uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2) {
! // blink error LED, this is serious
! leds_error_blink();
!
! // schedule for the mote to reboot in 10s
! opentimers_start(10000,
! TIMER_ONESHOT,TIME_MS,
! board_reset);
!
! return openserial_printInfoErrorCritical(
! SERFRAME_MOTE2PC_CRITICAL,
! calling_component,
! error_code,
! arg1,
! arg2
! );
! }
!
! uint8_t openserial_getNumDataBytes() {
! uint8_t inputBufFill;
! INTERRUPT_DECLARATION();
!
! DISABLE_INTERRUPTS();
! inputBufFill = openserial_vars.inputBufFill;
! ENABLE_INTERRUPTS();
!
! return inputBufFill-1; // removing the command byte
! }
!
! uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes) {
! uint8_t numBytesWritten;
! uint8_t inputBufFill;
! INTERRUPT_DECLARATION();
!
! DISABLE_INTERRUPTS();
! inputBufFill = openserial_vars.inputBufFill;
! ENABLE_INTERRUPTS();
!
! if (maxNumBytes<inputBufFill-1) {
! openserial_printError(COMPONENT_OPENSERIAL,ERR_GETDATA_ASKS_TOO_FEW_BYTES,
! (errorparameter_t)maxNumBytes,
! (errorparameter_t)inputBufFill-1);
! numBytesWritten = 0;
! } else {
! numBytesWritten = inputBufFill-1;
! memcpy(bufferToWrite,&(openserial_vars.inputBuf[1]),numBytesWritten);
! }
! DISABLE_INTERRUPTS();
! openserial_vars.inputBufFill=0;
! ENABLE_INTERRUPTS();
!
! return numBytesWritten;
! }
!
! void openserial_startInput() {
! INTERRUPT_DECLARATION();
!
! if (openserial_vars.inputBufFill>0) {
! 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.reqFrameIdx<sizeof(openserial_vars.reqFrame)) {
! uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]);
! }
! break;
! case MODE_OUTPUT:
! if (openserial_vars.outputBufIdxW==openserial_vars.outputBufIdxR) {
! openserial_vars.outputBufFilled = FALSE;
! }
! if (openserial_vars.outputBufFilled) {
! uart_writeByte(openserial_vars.outputBuf[openserial_vars.outputBufIdxR++]);
! }
! break;
! case MODE_OFF:
! default:
! break;
! }
! }
!
! // executed in ISR, called from scheduler.c
! void isr_openserial_rx() {
! uint8_t rxbyte;
!
! // stop if I'm not in input mode
! if (openserial_vars.mode!=MODE_INPUT) {
! return;
! }
!
! // read byte just received
! rxbyte = uart_readByte();
!
! if (
! openserial_vars.busyReceiving==FALSE &&
! openserial_vars.lastRxByte==HDLC_FLAG &&
! rxbyte!=HDLC_FLAG
! ) {
! // start of frame
!
! // I'm now receiving
! openserial_vars.busyReceiving = TRUE;
!
! // create the HDLC frame
! inputHdlcOpen();
!
! // add the byte just received
! inputHdlcWrite(rxbyte);
! } else if (
! openserial_vars.busyReceiving==TRUE &&
! rxbyte!=HDLC_FLAG
! ) {
! // middle of frame
!
! // add the byte just received
! inputHdlcWrite(rxbyte);
! if (openserial_vars.inputBufFill+1>SERIAL_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 <chraim@eecs.berkeley.edu>, 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"
2014-01-20 12:35:19 +01:00
! #include "uart_ow.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;i<length;i++){
! // outputHdlcWrite(buffer[i]);
! // }
! // outputHdlcClose();
! // ENABLE_INTERRUPTS();
!
! return E_SUCCESS;
! }
!
! owerror_t openserial_printInfoErrorCritical(
! char severity,
! uint8_t calling_component,
! uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2
! ) {
! // INTERRUPT_DECLARATION();
! //
! // DISABLE_INTERRUPTS();
! // openserial_vars.outputBufFilled = TRUE;
! // outputHdlcOpen();
! // outputHdlcWrite(severity);
! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_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;i<length;i++){
! // outputHdlcWrite(buffer[i]);
! // }
! // outputHdlcClose();
! // ENABLE_INTERRUPTS();
!
! return E_SUCCESS;
! }
!
! owerror_t openserial_printInfo(uint8_t calling_component, uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2) {
! return openserial_printInfoErrorCritical(
! SERFRAME_MOTE2PC_INFO,
! calling_component,
! error_code,
! arg1,
! arg2
! );
! }
!
! owerror_t openserial_printError(uint8_t calling_component, uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2) {
! // blink error LED, this is serious
! leds_error_toggle();
!
! return openserial_printInfoErrorCritical(
! SERFRAME_MOTE2PC_ERROR,
! calling_component,
! error_code,
! arg1,
! arg2
! );
! }
!
! owerror_t openserial_printCritical(uint8_t calling_component, uint8_t error_code,
! errorparameter_t arg1,
! errorparameter_t arg2) {
! // blink error LED, this is serious
! leds_error_blink();
! //
! // // schedule for the mote to reboot in 10s
! // opentimers_start(10000,
! // TIMER_ONESHOT,TIME_MS,
! // board_reset);
!
! return openserial_printInfoErrorCritical(
! SERFRAME_MOTE2PC_CRITICAL,
! calling_component,
! error_code,
! arg1,
! arg2
! );
! }
!
! uint8_t openserial_getNumDataBytes(void) {
! uint8_t inputBufFill;
! // INTERRUPT_DECLARATION();
! //
! // DISABLE_INTERRUPTS();
! // inputBufFill = openserial_vars.inputBufFill;
! // ENABLE_INTERRUPTS();
!
! return inputBufFill-1; // removing the command byte
! }
!
! uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes) {
! uint8_t numBytesWritten;
! // uint8_t inputBufFill;
! // INTERRUPT_DECLARATION();
! //
! // DISABLE_INTERRUPTS();
! // inputBufFill = openserial_vars.inputBufFill;
! // ENABLE_INTERRUPTS();
! //
! // if (maxNumBytes<inputBufFill-1) {
! // openserial_printError(COMPONENT_OPENSERIAL,ERR_GETDATA_ASKS_TOO_FEW_BYTES,
! // (errorparameter_t)maxNumBytes,
! // (errorparameter_t)inputBufFill-1);
! // numBytesWritten = 0;
! // } else {
! // numBytesWritten = inputBufFill-1;
! // memcpy(bufferToWrite,&(openserial_vars.inputBuf[1]),numBytesWritten);
! // }
!
! return numBytesWritten;
! }
!
! void openserial_startInput() {
! // INTERRUPT_DECLARATION();
! //
! // if (openserial_vars.inputBufFill>0) {
! // 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.reqFrameIdx<sizeof(openserial_vars.reqFrame)) {
! // uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]);
! // }
! // break;
! // case MODE_OUTPUT:
! // if (openserial_vars.outputBufIdxW==openserial_vars.outputBufIdxR) {
! // openserial_vars.outputBufFilled = FALSE;
! // }
! // if (openserial_vars.outputBufFilled) {
! // uart_writeByte(openserial_vars.outputBuf[openserial_vars.outputBufIdxR++]);
! // }
! // break;
! // case MODE_OFF:
! // default:
! // break;
! // }
! // }
!
! // executed in ISR, called from scheduler.c
! // void isr_openserial_rx(void) {
! // uint8_t rxbyte;
! // uint8_t inputBufFill;
! //
! // // stop if I'm not in input mode
! // if (openserial_vars.mode!=MODE_INPUT) {
! // return;
! // }
! //
! // // read byte just received
! // rxbyte = uart_readByte();
! // //keep lenght
! // inputBufFill=openserial_vars.inputBufFill;
! //
! // if (
! // openserial_vars.busyReceiving==FALSE &&
! // openserial_vars.lastRxByte==HDLC_FLAG &&
! // rxbyte!=HDLC_FLAG
! // ) {
! // // start of frame
! //
! // // I'm now receiving
! // openserial_vars.busyReceiving = TRUE;
! //
! // // create the HDLC frame
! // inputHdlcOpen();
! //
! // // add the byte just received
! // inputHdlcWrite(rxbyte);
! // } else if (
! // openserial_vars.busyReceiving==TRUE &&
! // rxbyte!=HDLC_FLAG
! // ) {
! // // middle of frame
! //
! // // add the byte just received
! // inputHdlcWrite(rxbyte);
! // if (openserial_vars.inputBufFill+1>SERIAL_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 <chraim@eecs.berkeley.edu>, 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 <chraim@eecs.berkeley.edu>, 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 <xvilajosana@eecs.berkeley.edu>, 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<MAX_NUM_TIMERS;i++) {
! opentimers_vars.timersBuf[i].period_ticks = 0;
! opentimers_vars.timersBuf[i].ticks_remaining = 0;
! opentimers_vars.timersBuf[i].type = TIMER_ONESHOT;
! opentimers_vars.timersBuf[i].isrunning = FALSE;
! opentimers_vars.timersBuf[i].callback = NULL;
! opentimers_vars.timersBuf[i].hasExpired = FALSE;
! }
!
! // set callback for bsp_timers module
! bsp_timer_set_callback(opentimers_timer_callback);
! }
!
! /**
! \brief Start a timer.
!
! The timer works as follows:
! - currentTimeout is the number of ticks before the next timer expires.
! - if a new timer is inserted, we check that it is not earlier than the soonest
! - if it is earliest, replace it
! - if not, insert it in the list
!
! \param duration Number milli-seconds after which the timer will fire.
! \param type The type of timer, indicating whether it's a one-shot or a period timer.
! \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<MAX_NUM_TIMERS && opentimers_vars.timersBuf[id].isrunning==TRUE; id++);
!
! if (id<MAX_NUM_TIMERS) {
! // we found an unused timer
!
! // register the timer
! if (timetype==TIME_MS) {
! opentimers_vars.timersBuf[id].period_ticks = duration*PORT_TICS_PER_MS;
! opentimers_vars.timersBuf[id].wraps_remaining = (duration*PORT_TICS_PER_MS/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else if (timetype==TIME_TICS) {
! opentimers_vars.timersBuf[id].period_ticks = duration;
! opentimers_vars.timersBuf[id].wraps_remaining = (duration/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else {
! while (1); //error
! }
! //if the number of ticks falls below a 16bit value, use it, otherwise set to max 16bit value
! if(opentimers_vars.timersBuf[id].wraps_remaining==0){
! if (timetype==TIME_MS){
! opentimers_vars.timersBuf[id].ticks_remaining = duration*PORT_TICS_PER_MS;
! } else if (timetype==TIME_TICS) {
! opentimers_vars.timersBuf[id].ticks_remaining = duration;
! } else {
! // this should never happpen!
!
! // we can not print from within the drivers. Instead:
! // blink the error LED
! leds_error_blink();
! // reset the board
! board_reset();
! }
! }else{
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
! }
! opentimers_vars.timersBuf[id].type = type;
! opentimers_vars.timersBuf[id].isrunning = TRUE;
! opentimers_vars.timersBuf[id].callback = callback;
! opentimers_vars.timersBuf[id].hasExpired = FALSE;
!
! // re-schedule the running timer, if needed
! if (
! (opentimers_vars.running==FALSE)
! ||
! (opentimers_vars.timersBuf[id].ticks_remaining < opentimers_vars.currentTimeout)
! ) {
! opentimers_vars.currentTimeout = opentimers_vars.timersBuf[id].ticks_remaining;
! if (opentimers_vars.running==FALSE) {
! bsp_timer_reset();
! }
! bsp_timer_scheduleIn(opentimers_vars.timersBuf[id].ticks_remaining);
! }
!
! opentimers_vars.running = TRUE;
!
! } else {
! return TOO_MANY_TIMERS_ERROR;
! }
!
! return id;
! }
!
! /**
! \brief Replace the period of a running timer.
! */
! void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype,uint32_t newDuration) {
! if (timetype==TIME_MS) {
! opentimers_vars.timersBuf[id].period_ticks = newDuration*PORT_TICS_PER_MS;
! opentimers_vars.timersBuf[id].wraps_remaining = (newDuration*PORT_TICS_PER_MS/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else if (timetype==TIME_TICS) {
! opentimers_vars.timersBuf[id].period_ticks = newDuration;
! opentimers_vars.timersBuf[id].wraps_remaining = (newDuration/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else {
! // this should never happpen!
!
! // we can not print from within the drivers. Instead:
! // blink the error LED
! leds_error_blink();
! // reset the board
! board_reset();
! }
! if(opentimers_vars.timersBuf[id].wraps_remaining==0) {
! if (timetype==TIME_MS){
! opentimers_vars.timersBuf[id].ticks_remaining = newDuration*PORT_TICS_PER_MS;
! } else if (timetype==TIME_TICS){
! opentimers_vars.timersBuf[id].ticks_remaining = newDuration;
! }
! } else {
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
! }
! }
!
! /**
! \brief Stop a running timer.
!
! Sets the timer to "not running". the system recovers even if this was the next
! timer to expire.
! */
! void opentimers_stop(opentimer_id_t id) {
! opentimers_vars.timersBuf[id].isrunning=FALSE;
! }
!
! /**
! \brief Restart a stop timer.
!
! Sets the timer to " running".
! */
! void opentimers_restart(opentimer_id_t id) {
! opentimers_vars.timersBuf[id].isrunning=TRUE;
! }
!
!
! //=========================== private =========================================
!
! /**
! \brief Function called when the hardware timer expires.
!
! Executed in interrupt mode.
!
! This function maps the expiration event to possibly multiple timers, calls the
! corresponding callback(s), and restarts the hardware timer with the next timer
! to expire.
! */
! void opentimers_timer_callback() {
!
! opentimer_id_t id;
! PORT_TIMER_WIDTH min_timeout;
! bool found;
!
! // step 1. Identify expired timers
! for(id=0; id<MAX_NUM_TIMERS; id++) {
! if (opentimers_vars.timersBuf[id].isrunning==TRUE) {
!
! if(opentimers_vars.currentTimeout >= 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<MAX_NUM_TIMERS; id++) {
! if (opentimers_vars.timersBuf[id].hasExpired==TRUE){
!
! // call the callback
! opentimers_vars.timersBuf[id].callback();
! opentimers_vars.timersBuf[id].hasExpired = FALSE;
!
! // reload the timer, if applicable
! if (opentimers_vars.timersBuf[id].type==TIMER_PERIODIC) {
! opentimers_vars.timersBuf[id].wraps_remaining = (opentimers_vars.timersBuf[id].period_ticks/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! //if the number of ticks falls below a 16bit value, use it, otherwise set to max 16bit value
! if(opentimers_vars.timersBuf[id].wraps_remaining==0)
! opentimers_vars.timersBuf[id].ticks_remaining = opentimers_vars.timersBuf[id].period_ticks;
! else
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
!
! } else {
! opentimers_vars.timersBuf[id].isrunning = FALSE;
! }
! }
!
! }
!
! // step 3. find the minimum remaining timeout among running timers
! found = FALSE;
! for(id=0;id<MAX_NUM_TIMERS;id++) {
! if (
! opentimers_vars.timersBuf[id].isrunning==TRUE &&
! (
! found==FALSE
! ||
! opentimers_vars.timersBuf[id].ticks_remaining < min_timeout
! )
! ) {
! min_timeout = opentimers_vars.timersBuf[id].ticks_remaining;
! found = TRUE;
! }
! }
!
! // step 4. schedule next timeout
! if (found==TRUE) {
! // at least one timer pending
! opentimers_vars.currentTimeout = min_timeout;
! bsp_timer_scheduleIn(opentimers_vars.currentTimeout);
! } else {
! // no more timers pending
! opentimers_vars.running = FALSE;
! }
! }
!
--- 1,382 ----
! /**
! \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 <xvilajosana@eecs.berkeley.edu>, 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;i<MAX_NUM_TIMERS;i++) {
! opentimers_vars.timersBuf[i].period_ticks = 0;
! opentimers_vars.timersBuf[i].ticks_remaining = 0;
! opentimers_vars.timersBuf[i].type = TIMER_ONESHOT;
! opentimers_vars.timersBuf[i].isrunning = FALSE;
! opentimers_vars.timersBuf[i].callback = NULL;
! opentimers_vars.timersBuf[i].hasExpired = FALSE;
! }
!
! // set callback for bsp_timers module
! // bsp_timer_set_callback(opentimers_timer_callback);
! hwtimer_arch_init(opentimers_int_handler, F_CPU);
! }
!
! /**
! \brief opentimers interrupt handler
!
! This is a wrapper to fit the hwtimer_arch API
! */
! void opentimers_int_handler(int t) {
! (void)t;
! opentimers_timer_callback();
! }
!
! /**
! \brief Start a timer.
!
! The timer works as follows:
! - currentTimeout is the number of ticks before the next timer expires.
! - if a new timer is inserted, we check that it is not earlier than the soonest
! - if it is earliest, replace it
! - if not, insert it in the list
!
! \param duration Number milli-seconds after which the timer will fire.
! \param type Type of timer:
! - #TIMER_PERIODIC for a periodic timer.
! - #TIMER_ONESHOT for a on-shot timer.
! \param timetype Units of the <tt>duration</tt>:
! - #TIME_MS when <tt>duration</tt> is in ms.
! - #TIME_TICS when <tt>duration</tt> 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<MAX_NUM_TIMERS && opentimers_vars.timersBuf[id].isrunning==TRUE; id++);
!
! if (id<MAX_NUM_TIMERS) {
! // we found an unused timer
!
! // register the timer
! if (timetype==TIME_MS) {
! opentimers_vars.timersBuf[id].period_ticks = duration*PORT_TICS_PER_MS;
! opentimers_vars.timersBuf[id].wraps_remaining = (duration*PORT_TICS_PER_MS/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else if (timetype==TIME_TICS) {
! opentimers_vars.timersBuf[id].period_ticks = duration;
! opentimers_vars.timersBuf[id].wraps_remaining = (duration/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else {
! while (1); //error
! }
! //if the number of ticks falls below a 16bit value, use it, otherwise set to max 16bit value
! if(opentimers_vars.timersBuf[id].wraps_remaining==0){
! if (timetype==TIME_MS){
! opentimers_vars.timersBuf[id].ticks_remaining = duration*PORT_TICS_PER_MS;
! } else if (timetype==TIME_TICS) {
! opentimers_vars.timersBuf[id].ticks_remaining = duration;
! } else {
! // this should never happpen!
!
! // we can not print from within the drivers. Instead:
! // blink the error LED
! leds_error_blink();
! // reset the board
! board_reset();
! }
! }else{
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
! }
! opentimers_vars.timersBuf[id].type = type;
! opentimers_vars.timersBuf[id].isrunning = TRUE;
! opentimers_vars.timersBuf[id].callback = callback;
! opentimers_vars.timersBuf[id].hasExpired = FALSE;
!
! // re-schedule the running timer, if needed
! if (
! (opentimers_vars.running==FALSE)
! ||
! (opentimers_vars.timersBuf[id].ticks_remaining < opentimers_vars.currentTimeout)
! ) {
! opentimers_vars.currentTimeout = opentimers_vars.timersBuf[id].ticks_remaining;
! if (opentimers_vars.running==FALSE) {
! //bsp_timer_reset();
! hwtimer_arch_unset(OPENTIMERS_HWTIMER_ID);
! }
! // bsp_timer_scheduleIn(opentimers_vars.timersBuf[id].ticks_remaining);
! hwtimer_arch_set(opentimers_vars.timersBuf[id].ticks_remaining, OPENTIMERS_HWTIMER_ID);
! }
!
! opentimers_vars.running = TRUE;
!
! } else {
! return TOO_MANY_TIMERS_ERROR;
! }
!
! return id;
! }
!
! /**
! \brief Replace the period of a running timer.
! */
! void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype,uint32_t newDuration) {
! if (timetype==TIME_MS) {
! opentimers_vars.timersBuf[id].period_ticks = newDuration*PORT_TICS_PER_MS;
! opentimers_vars.timersBuf[id].wraps_remaining = (newDuration*PORT_TICS_PER_MS/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else if (timetype==TIME_TICS) {
! opentimers_vars.timersBuf[id].period_ticks = newDuration;
! opentimers_vars.timersBuf[id].wraps_remaining = (newDuration/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! } else {
! // this should never happpen!
!
! // we can not print from within the drivers. Instead:
! // blink the error LED
! leds_error_blink();
! // reset the board
! board_reset();
! }
! if(opentimers_vars.timersBuf[id].wraps_remaining==0) {
! if (timetype==TIME_MS){
! opentimers_vars.timersBuf[id].ticks_remaining = newDuration*PORT_TICS_PER_MS;
! } else if (timetype==TIME_TICS){
! opentimers_vars.timersBuf[id].ticks_remaining = newDuration;
! }
! } else {
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
! }
! }
!
! /**
! \brief Stop a running timer.
!
! Sets the timer to "not running". the system recovers even if this was the next
! timer to expire.
! */
! void opentimers_stop(opentimer_id_t id) {
! opentimers_vars.timersBuf[id].isrunning=FALSE;
! }
!
! /**
! \brief Restart a stop timer.
!
! Sets the timer to " running".
! */
! void opentimers_restart(opentimer_id_t id) {
! opentimers_vars.timersBuf[id].isrunning=TRUE;
! }
!
!
! //=========================== private =========================================
!
! /**
! \brief Function called when the hardware timer expires.
!
! Executed in interrupt mode.
!
! This function maps the expiration event to possibly multiple timers, calls the
! corresponding callback(s), and restarts the hardware timer with the next timer
! to expire.
! */
! void opentimers_timer_callback(void) {
!
! opentimer_id_t id;
! PORT_TIMER_WIDTH min_timeout;
! bool found;
!
! // step 1. Identify expired timers
! for(id=0; id<MAX_NUM_TIMERS; id++) {
! if (opentimers_vars.timersBuf[id].isrunning==TRUE) {
!
! if(opentimers_vars.currentTimeout >= 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<MAX_NUM_TIMERS; id++) {
! if (opentimers_vars.timersBuf[id].hasExpired==TRUE){
!
! // call the callback
! opentimers_vars.timersBuf[id].callback();
! opentimers_vars.timersBuf[id].hasExpired = FALSE;
!
! // reload the timer, if applicable
! if (opentimers_vars.timersBuf[id].type==TIMER_PERIODIC) {
! opentimers_vars.timersBuf[id].wraps_remaining = (opentimers_vars.timersBuf[id].period_ticks/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! //if the number of ticks falls below a 16bit value, use it, otherwise set to max 16bit value
! if(opentimers_vars.timersBuf[id].wraps_remaining==0)
! opentimers_vars.timersBuf[id].ticks_remaining = opentimers_vars.timersBuf[id].period_ticks;
! else
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
!
! } else {
! opentimers_vars.timersBuf[id].isrunning = FALSE;
! }
! }
!
! }
!
! // step 3. find the minimum remaining timeout among running timers
! found = FALSE;
! for(id=0;id<MAX_NUM_TIMERS;id++) {
! if (
! opentimers_vars.timersBuf[id].isrunning==TRUE &&
! (
! found==FALSE
! ||
! opentimers_vars.timersBuf[id].ticks_remaining < min_timeout
! )
! ) {
! min_timeout = opentimers_vars.timersBuf[id].ticks_remaining;
! found = TRUE;
! }
! }
!
! // step 4. schedule next timeout
! if (found==TRUE) {
! // at least one timer pending
! opentimers_vars.currentTimeout = min_timeout;
! // bsp_timer_scheduleIn(opentimers_vars.currentTimeout);
! hwtimer_arch_set(opentimers_vars.currentTimeout, OPENTIMERS_HWTIMER_ID);
! } else {
! // no more timers pending
! opentimers_vars.running = FALSE;
! }
! }
!
! void opentimers_sleepTimeCompesation(uint16_t sleepTime)
! {
! opentimer_id_t id;
! PORT_TIMER_WIDTH min_timeout;
! bool found;
!
! //step 1. reCount the ticks_remain after waking up from sleep
! for(id=0; id<MAX_NUM_TIMERS; id++)
! {
! if (opentimers_vars.timersBuf[id].isrunning==TRUE)
! {
! if(opentimers_vars.timersBuf[id].ticks_remaining > 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<MAX_NUM_TIMERS; id++) {
! if (opentimers_vars.timersBuf[id].hasExpired==TRUE){
!
! // call the callback
! opentimers_vars.timersBuf[id].callback();
! opentimers_vars.timersBuf[id].hasExpired = FALSE;
!
! // reload the timer, if applicable
! if (opentimers_vars.timersBuf[id].type==TIMER_PERIODIC) {
! opentimers_vars.timersBuf[id].wraps_remaining = (opentimers_vars.timersBuf[id].period_ticks/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t
! //if the number of ticks falls below a 16bit value, use it, otherwise set to max 16bit value
! if(opentimers_vars.timersBuf[id].wraps_remaining==0)
! opentimers_vars.timersBuf[id].ticks_remaining = opentimers_vars.timersBuf[id].period_ticks;
! else
! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK;
!
! } else {
! opentimers_vars.timersBuf[id].isrunning = FALSE;
! }
! }
!
! }
!
! // step 3. find the minimum remaining timeout among running timers
! found = FALSE;
! for(id=0;id<MAX_NUM_TIMERS;id++) {
! if (
! opentimers_vars.timersBuf[id].isrunning==TRUE &&
! (
! found==FALSE
! ||
! opentimers_vars.timersBuf[id].ticks_remaining < min_timeout
! )
! ) {
! min_timeout = opentimers_vars.timersBuf[id].ticks_remaining;
! found = TRUE;
! }
! }
!
! // step 4. schedule next timeout
! if (found==TRUE) {
! // at least one timer pending
! opentimers_vars.currentTimeout = min_timeout;
! // bsp_timer_scheduleIn(opentimers_vars.currentTimeout);
! hwtimer_arch_set(opentimers_vars.currentTimeout, OPENTIMERS_HWTIMER_ID);
! } else {
! // no more timers pending
! opentimers_vars.running = FALSE;
! }
! }
diff -crB openwsn/opentimers.h ../../../sys/net/openwsn/opentimers.h
*** openwsn/opentimers.h Thu Mar 21 21:36:59 2013
--- ../../../sys/net/openwsn/opentimers.h Wed Jan 15 13:48:27 2014
***************
*** 1,60 ****
! /**
! \brief Declaration of the "opentimers" driver.
!
! \author Xavi Vilajosana <xvilajosana@eecs.berkeley.edu>, 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 <xvilajosana@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, August 2010
! \author Ankur Mehta <mehtank@eecs.berkeley.edu>, September 2010
! */
!
! #ifndef __OPENWSN_H
! #define __OPENWSN_H
!
! //general
! #include <stdint.h> // 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 <watteyne@eecs.berkeley.edu>, August 2010
! \author Ankur Mehta <mehtank@eecs.berkeley.edu>, September 2010
! */
!
! #ifndef __OPENWSN_H
! #define __OPENWSN_H
!
! //general
! #include <stdint.h> // needed for uin8_t, uint16_t
! #include "board_info.h"
!
! #include <stdbool.h>
! #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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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
2014-01-20 12:35:19 +01:00
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 ****
! /**
! \brief TelosB-specific definition of the "uart" bsp module.
!
! \author Thomas Watteyne <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, February 2012.
! */
!
! #include "msp430f1611.h"
2014-01-20 12:35:19 +01:00
! #include "uart_ow.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
2014-01-20 12:35:19 +01:00
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 ****
! /**
! \brief Cross-platform declaration "uart" bsp module.
!
! \author Thomas Watteyne <watteyne@eecs.berkeley.edu>, 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 <watteyne@eecs.berkeley.edu>, 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