diff -crB openwsn/02a-MAClow/IEEE802154.c ../../../sys/net/openwsn/02a-MAClow/IEEE802154.c *** openwsn/02a-MAClow/IEEE802154.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/IEEE802154.c Wed Jan 15 13:48:26 2014 *************** *** 1,220 **** ! #include "openwsn.h" ! #include "IEEE802154.h" ! #include "packetfunctions.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "topology.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! /** ! \brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet. ! ! Note that we are writing the field from the end of the header to the beginning. ! ! \param msg [in,out] The message to append the header to. ! \param frameType [in] Type of IEEE802.15.4 frame. ! \param securityEnabled [in] Is security enabled on this frame? ! \param nextHop [in] Address of the next hop ! */ ! void ieee802154_prependHeader(OpenQueueEntry_t* msg, ! uint8_t frameType, ! bool securityEnabled, ! uint8_t sequenceNumber, ! open_addr_t* nextHop) { ! uint8_t temp_8b; ! ! // previousHop address (always 64-bit) ! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),LITTLE_ENDIAN); ! // nextHop address ! if (packetfunctions_isBroadcastMulticast(nextHop)) { ! //broadcast address is always 16-bit ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = 0xFF; ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = 0xFF; ! } else { ! switch (nextHop->type) { ! case ADDR_16B: ! case ADDR_64B: ! packetfunctions_writeAddress(msg,nextHop,LITTLE_ENDIAN); ! break; ! default: ! openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)nextHop->type, ! (errorparameter_t)1); ! } ! ! } ! // destpan ! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),LITTLE_ENDIAN); ! //dsn ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = sequenceNumber; ! //fcf (2nd byte) ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! temp_8b = 0; ! if (packetfunctions_isBroadcastMulticast(nextHop)) { ! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; ! } else { ! switch (nextHop->type) { ! case ADDR_16B: ! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; ! break; ! case ADDR_64B: ! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_DEST_ADDR_MODE; ! break; ! // no need for a default, since it would have been caught above. ! } ! } ! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_SRC_ADDR_MODE; ! *((uint8_t*)(msg->payload)) = temp_8b; ! //fcf (1st byte) ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! temp_8b = 0; ! temp_8b |= frameType << IEEE154_FCF_FRAME_TYPE; ! temp_8b |= securityEnabled << IEEE154_FCF_SECURITY_ENABLED; ! temp_8b |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING; ! if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) { ! temp_8b |= IEEE154_ACK_NO_ACK_REQ << IEEE154_FCF_ACK_REQ; ! } else { ! temp_8b |= IEEE154_ACK_YES_ACK_REQ << IEEE154_FCF_ACK_REQ; ! } ! temp_8b |= IEEE154_PANID_COMPRESSED << IEEE154_FCF_INTRAPAN; ! *((uint8_t*)(msg->payload)) = temp_8b; ! } ! ! /** ! \brief Retreieve the IEEE802.15.4 MAC header from a (just received) packet. ! ! Note We are writing the fields from the begnning of the header to the end. ! ! \param msg [in,out] The message just received. ! \param ieee802514_header [out] The internal header to write the data to. ! */ ! void ieee802154_retrieveHeader(OpenQueueEntry_t* msg, ! ieee802154_header_iht* ieee802514_header) { ! uint8_t temp_8b; ! ! // by default, let's assume the header is not valid, in case we leave this ! // function because the packet ends up being shorter than the header. ! ieee802514_header->valid=FALSE; ! ! ieee802514_header->headerLength = 0; ! // fcf, byte 1 ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ! ieee802514_header->frameType = (temp_8b >> IEEE154_FCF_FRAME_TYPE ) & 0x07;//3b ! ieee802514_header->securityEnabled = (temp_8b >> IEEE154_FCF_SECURITY_ENABLED) & 0x01;//1b ! ieee802514_header->framePending = (temp_8b >> IEEE154_FCF_FRAME_PENDING ) & 0x01;//1b ! ieee802514_header->ackRequested = (temp_8b >> IEEE154_FCF_ACK_REQ ) & 0x01;//1b ! ieee802514_header->panIDCompression = (temp_8b >> IEEE154_FCF_INTRAPAN ) & 0x01;//1b ! ieee802514_header->headerLength += 1; ! // fcf, byte 2 ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ! switch ( (temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03 ) { ! case IEEE154_ADDR_NONE: ! ieee802514_header->dest.type = ADDR_NONE; ! break; ! case IEEE154_ADDR_SHORT: ! ieee802514_header->dest.type = ADDR_16B; ! break; ! case IEEE154_ADDR_EXT: ! ieee802514_header->dest.type = ADDR_64B; ! break; ! default: ! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, ! (errorparameter_t)1, ! (errorparameter_t)(temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03); ! return; // this is an invalid packet, return ! } ! switch ( (temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03 ) { ! case IEEE154_ADDR_NONE: ! ieee802514_header->src.type = ADDR_NONE; ! break; ! case IEEE154_ADDR_SHORT: ! ieee802514_header->src.type = ADDR_16B; ! break; ! case IEEE154_ADDR_EXT: ! ieee802514_header->src.type = ADDR_64B; ! break; ! default: ! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, ! (errorparameter_t)2, ! (errorparameter_t)(temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03); ! return; // this is an invalid packet, return ! } ! ieee802514_header->headerLength += 1; ! // sequenceNumber ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! ieee802514_header->dsn = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ! ieee802514_header->headerLength += 1; ! // panID ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_PANID, ! &ieee802514_header->panid, ! LITTLE_ENDIAN); ! ieee802514_header->headerLength += 2; ! // dest ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! switch (ieee802514_header->dest.type) { ! case ADDR_NONE: ! break; ! case ADDR_16B: ! packetfunctions_readAddress( ! ((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_16B, ! &ieee802514_header->dest, ! LITTLE_ENDIAN ! ); ! ieee802514_header->headerLength += 2; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! case ADDR_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_64B, ! &ieee802514_header->dest, ! LITTLE_ENDIAN); ! ieee802514_header->headerLength += 8; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! // no need for a default, since case would have been caught above ! } ! //src ! switch (ieee802514_header->src.type) { ! case ADDR_NONE: ! break; ! case ADDR_16B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_16B, ! &ieee802514_header->src, ! LITTLE_ENDIAN); ! ieee802514_header->headerLength += 2; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! case ADDR_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_64B, ! &ieee802514_header->src, ! LITTLE_ENDIAN); ! ieee802514_header->headerLength += 8; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! // no need for a default, since case would have been caught above ! } ! // apply topology filter ! if (topology_isAcceptablePacket(ieee802514_header)==FALSE) { ! // the topology filter does accept this packet, return ! return; ! } ! // if you reach this, the header is valid ! ieee802514_header->valid=TRUE; ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,244 ---- ! #include "openwsn.h" ! #include "IEEE802154.h" ! #include "packetfunctions.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "topology.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! /** ! \brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet. ! ! Note that we are writing the field from the end of the header to the beginning. ! ! \param[in,out] msg The message to append the header to. ! \param[in] frameType Type of IEEE802.15.4 frame. ! \param[in] ielistpresent Is the IE list present¿ ! \param[in] frameVersion IEEE802.15.4 frame version. ! \param[in] securityEnabled Is security enabled on this frame? ! \param[in] sequenceNumber Sequence number of this frame. ! \param[in] nextHop Address of the next hop ! */ ! void ieee802154_prependHeader(OpenQueueEntry_t* msg, ! uint8_t frameType, ! uint8_t ielistpresent, ! uint8_t frameversion, ! bool securityEnabled, ! uint8_t sequenceNumber, ! open_addr_t* nextHop) { ! uint8_t temp_8b; ! ! //General IEs here (those that are carried in all packets) -- None by now. ! ! // previousHop address (always 64-bit) ! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),OW_LITTLE_ENDIAN); ! // nextHop address ! if (packetfunctions_isBroadcastMulticast(nextHop)) { ! //broadcast address is always 16-bit ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = 0xFF; ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = 0xFF; ! } else { ! switch (nextHop->type) { ! case ADDR_16B: ! case ADDR_64B: ! packetfunctions_writeAddress(msg,nextHop,OW_LITTLE_ENDIAN); ! break; ! default: ! openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)nextHop->type, ! (errorparameter_t)1); ! } ! ! } ! // destpan ! packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),OW_LITTLE_ENDIAN); ! //dsn ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = sequenceNumber; ! //fcf (2nd byte) ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! temp_8b = 0; ! if (packetfunctions_isBroadcastMulticast(nextHop)) { ! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; ! } else { ! switch (nextHop->type) { ! case ADDR_16B: ! temp_8b |= IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE; ! break; ! case ADDR_64B: ! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_DEST_ADDR_MODE; ! break; ! // no need for a default, since it would have been caught above. ! } ! } ! temp_8b |= IEEE154_ADDR_EXT << IEEE154_FCF_SRC_ADDR_MODE; ! //poipoi xv IE list present ! temp_8b |= ielistpresent << IEEE154_FCF_IELIST_PRESENT; ! temp_8b |= frameversion << IEEE154_FCF_FRAME_VERSION; ! ! *((uint8_t*)(msg->payload)) = temp_8b; ! //fcf (1st byte) ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! temp_8b = 0; ! temp_8b |= frameType << IEEE154_FCF_FRAME_TYPE; ! temp_8b |= securityEnabled << IEEE154_FCF_SECURITY_ENABLED; ! temp_8b |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING; ! if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) { ! temp_8b |= IEEE154_ACK_NO_ACK_REQ << IEEE154_FCF_ACK_REQ; ! } else { ! temp_8b |= IEEE154_ACK_YES_ACK_REQ << IEEE154_FCF_ACK_REQ; ! } ! temp_8b |= IEEE154_PANID_COMPRESSED << IEEE154_FCF_INTRAPAN; ! *((uint8_t*)(msg->payload)) = temp_8b; ! } ! ! /** ! \brief Retreieve the IEEE802.15.4 MAC header from a (just received) packet. ! ! Note We are writing the fields from the begnning of the header to the end. ! ! \param[in,out] msg The message just received. ! \param[out] ieee802514_header The internal header to write the data to. ! */ ! void ieee802154_retrieveHeader(OpenQueueEntry_t* msg, ! ieee802154_header_iht* ieee802514_header) { ! uint8_t temp_8b; ! ! // by default, let's assume the header is not valid, in case we leave this ! // function because the packet ends up being shorter than the header. ! ieee802514_header->valid=FALSE; ! ! ieee802514_header->headerLength = 0; ! // fcf, byte 1 ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ! ieee802514_header->frameType = (temp_8b >> IEEE154_FCF_FRAME_TYPE ) & 0x07;//3b ! ieee802514_header->securityEnabled = (temp_8b >> IEEE154_FCF_SECURITY_ENABLED) & 0x01;//1b ! ieee802514_header->framePending = (temp_8b >> IEEE154_FCF_FRAME_PENDING ) & 0x01;//1b ! ieee802514_header->ackRequested = (temp_8b >> IEEE154_FCF_ACK_REQ ) & 0x01;//1b ! ieee802514_header->panIDCompression = (temp_8b >> IEEE154_FCF_INTRAPAN ) & 0x01;//1b ! ieee802514_header->headerLength += 1; ! // fcf, byte 2 ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! temp_8b = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ! //poipoi xv IE list present ! ieee802514_header->ieListPresent = (temp_8b >> IEEE154_FCF_IELIST_PRESENT ) & 0x01;//1b ! ieee802514_header->frameVersion = (temp_8b >> IEEE154_FCF_FRAME_VERSION ) & 0x03;//2b ! ! if (ieee802514_header->ieListPresent==TRUE && ieee802514_header->frameVersion!=IEEE154_FRAMEVERSION){ ! return; //invalid packet accordint to p.64 IEEE15.4e ! } ! ! switch ( (temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03 ) { ! case IEEE154_ADDR_NONE: ! ieee802514_header->dest.type = ADDR_NONE; ! break; ! case IEEE154_ADDR_SHORT: ! ieee802514_header->dest.type = ADDR_16B; ! break; ! case IEEE154_ADDR_EXT: ! ieee802514_header->dest.type = ADDR_64B; ! break; ! default: ! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, ! (errorparameter_t)1, ! (errorparameter_t)(temp_8b >> IEEE154_FCF_DEST_ADDR_MODE ) & 0x03); ! return; // this is an invalid packet, return ! } ! switch ( (temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03 ) { ! case IEEE154_ADDR_NONE: ! ieee802514_header->src.type = ADDR_NONE; ! break; ! case IEEE154_ADDR_SHORT: ! ieee802514_header->src.type = ADDR_16B; ! break; ! case IEEE154_ADDR_EXT: ! ieee802514_header->src.type = ADDR_64B; ! break; ! default: ! openserial_printError(COMPONENT_IEEE802154,ERR_IEEE154_UNSUPPORTED, ! (errorparameter_t)2, ! (errorparameter_t)(temp_8b >> IEEE154_FCF_SRC_ADDR_MODE ) & 0x03); ! return; // this is an invalid packet, return ! } ! ieee802514_header->headerLength += 1; ! // sequenceNumber ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! ieee802514_header->dsn = *((uint8_t*)(msg->payload)+ieee802514_header->headerLength); ! ieee802514_header->headerLength += 1; ! // panID ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_PANID, ! &ieee802514_header->panid, ! OW_LITTLE_ENDIAN); ! ieee802514_header->headerLength += 2; ! // dest ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! switch (ieee802514_header->dest.type) { ! case ADDR_NONE: ! break; ! case ADDR_16B: ! packetfunctions_readAddress( ! ((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_16B, ! &ieee802514_header->dest, ! OW_LITTLE_ENDIAN ! ); ! ieee802514_header->headerLength += 2; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! case ADDR_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_64B, ! &ieee802514_header->dest, ! OW_LITTLE_ENDIAN); ! ieee802514_header->headerLength += 8; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! // no need for a default, since case would have been caught above ! } ! //src ! switch (ieee802514_header->src.type) { ! case ADDR_NONE: ! break; ! case ADDR_16B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_16B, ! &ieee802514_header->src, ! OW_LITTLE_ENDIAN); ! ieee802514_header->headerLength += 2; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! case ADDR_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload)+ieee802514_header->headerLength), ! ADDR_64B, ! &ieee802514_header->src, ! OW_LITTLE_ENDIAN); ! ieee802514_header->headerLength += 8; ! if (ieee802514_header->headerLength>msg->length) { return; } // no more to read! ! break; ! // no need for a default, since case would have been caught above ! } ! ! if (ieee802514_header->ieListPresent==TRUE && ieee802514_header->frameVersion!=IEEE154_FRAMEVERSION){ ! return; //invalid packet accordint to p.64 IEEE15.4e ! } ! ! // apply topology filter ! if (topology_isAcceptablePacket(ieee802514_header)==FALSE) { ! // the topology filter does accept this packet, return ! return; ! } ! // if you reach this, the header is valid ! ieee802514_header->valid=TRUE; ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/02a-MAClow/IEEE802154.h ../../../sys/net/openwsn/02a-MAClow/IEEE802154.h *** openwsn/02a-MAClow/IEEE802154.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/IEEE802154.h Wed Jan 15 13:48:26 2014 *************** *** 1,94 **** ! #ifndef __IEEE802154_H ! #define __IEEE802154_H ! ! /** ! \addtogroup helpers ! \{ ! \addtogroup IEEE802154 ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! enum IEEE802154_fcf_enums { ! IEEE154_FCF_FRAME_TYPE = 0, ! IEEE154_FCF_SECURITY_ENABLED = 3, ! IEEE154_FCF_FRAME_PENDING = 4, ! IEEE154_FCF_ACK_REQ = 5, ! IEEE154_FCF_INTRAPAN = 6, ! IEEE154_FCF_DEST_ADDR_MODE = 2, ! IEEE154_FCF_SRC_ADDR_MODE = 6, ! }; ! ! enum IEEE802154_fcf_type_enums { ! IEEE154_TYPE_BEACON = 0, ! IEEE154_TYPE_DATA = 1, ! IEEE154_TYPE_ACK = 2, ! IEEE154_TYPE_CMD = 3, ! IEEE154_TYPE_UNDEFINED = 5, ! }; ! ! enum IEEE802154_fcf_sec_enums { ! IEEE154_SEC_NO_SECURITY = 0, ! IEEE154_SEC_YES_SECURITY = 1, ! }; ! ! enum IEEE802154_fcf_pending_enums { ! IEEE154_PENDING_NO_FRAMEPENDING = 0, ! IEEE154_PENDING_YES_FRAMEPENDING = 1, ! }; ! ! enum IEEE802154_fcf_ack_enums { ! IEEE154_ACK_NO_ACK_REQ = 0, ! IEEE154_ACK_YES_ACK_REQ = 1, ! }; ! ! enum IEEE802154_fcf_panid_enums { ! IEEE154_PANID_UNCOMPRESSED = 0, ! IEEE154_PANID_COMPRESSED = 1, ! }; ! ! enum IEEE802154_fcf_addr_mode_enums { ! IEEE154_ADDR_NONE = 0, ! IEEE154_ADDR_SHORT = 2, ! IEEE154_ADDR_EXT = 3, ! }; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! bool valid; ! uint8_t headerLength; //including the length field ! uint8_t frameType; ! bool securityEnabled; ! bool framePending; ! bool ackRequested; ! bool panIDCompression; ! uint8_t dsn; ! open_addr_t panid; ! open_addr_t dest; ! open_addr_t src; ! } ieee802154_header_iht; //iht for "internal header type" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== prototypes ====================================== ! ! void ieee802154_prependHeader (OpenQueueEntry_t* msg, ! uint8_t frameType, ! bool securityEnabled, ! uint8_t sequenceNumber, ! open_addr_t* nextHop); ! void ieee802154_retrieveHeader (OpenQueueEntry_t* msg, ! ieee802154_header_iht* ieee802514_header); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,113 ---- ! #ifndef __IEEE802154_H ! #define __IEEE802154_H ! ! /** ! \addtogroup MAClow ! \{ ! \addtogroup IEEE802154 ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! enum IEEE802154_fcf_enums { ! IEEE154_FCF_FRAME_TYPE = 0, ! IEEE154_FCF_SECURITY_ENABLED = 3, ! IEEE154_FCF_FRAME_PENDING = 4, ! IEEE154_FCF_ACK_REQ = 5, ! IEEE154_FCF_INTRAPAN = 6, ! IEEE154_FCF_IELIST_PRESENT = 1, ! IEEE154_FCF_DEST_ADDR_MODE = 2, ! IEEE154_FCF_FRAME_VERSION = 4, ! IEEE154_FCF_SRC_ADDR_MODE = 6, ! }; ! ! ! enum IEEE802154_fcf_frameversion_enums { ! IEEE154_FRAMEVERSION_2003 = 0, //ieee154-2003 ! IEEE154_FRAMEVERSION_2006 = 1, //ieee154-2006 ! IEEE154_FRAMEVERSION = 2, //ieee154 ! }; ! ! enum IEEE802154_fcf_type_enums { ! IEEE154_TYPE_BEACON = 0, ! IEEE154_TYPE_DATA = 1, ! IEEE154_TYPE_ACK = 2, ! IEEE154_TYPE_CMD = 3, ! IEEE154_TYPE_UNDEFINED = 5, ! }; ! ! enum IEEE802154_fcf_sec_enums { ! IEEE154_SEC_NO_SECURITY = 0, ! IEEE154_SEC_YES_SECURITY = 1, ! }; ! ! enum IEEE802154_fcf_ielist_enums { ! IEEE154_IELIST_NO = 0, ! IEEE154_IELIST_YES = 1, ! }; ! ! enum IEEE802154_fcf_pending_enums { ! IEEE154_PENDING_NO_FRAMEPENDING = 0, ! IEEE154_PENDING_YES_FRAMEPENDING = 1, ! }; ! ! enum IEEE802154_fcf_ack_enums { ! IEEE154_ACK_NO_ACK_REQ = 0, ! IEEE154_ACK_YES_ACK_REQ = 1, ! }; ! ! enum IEEE802154_fcf_panid_enums { ! IEEE154_PANID_UNCOMPRESSED = 0, ! IEEE154_PANID_COMPRESSED = 1, ! }; ! ! enum IEEE802154_fcf_addr_mode_enums { ! IEEE154_ADDR_NONE = 0, ! IEEE154_ADDR_SHORT = 2, ! IEEE154_ADDR_EXT = 3, ! }; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! bool valid; ! uint8_t headerLength; //including the length field ! uint8_t frameType; ! bool securityEnabled; ! bool framePending; ! bool ackRequested; ! bool panIDCompression; ! bool ieListPresent; ! uint8_t frameVersion; ! uint8_t dsn; ! open_addr_t panid; ! open_addr_t dest; ! open_addr_t src; ! } ieee802154_header_iht; //iht for "internal header type" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== prototypes ====================================== ! ! void ieee802154_prependHeader(OpenQueueEntry_t* msg, ! uint8_t frameType, ! uint8_t ielistpresent, ! uint8_t frameversion, ! bool securityEnabled, ! uint8_t sequenceNumber, ! open_addr_t* nextHop); ! ! void ieee802154_retrieveHeader (OpenQueueEntry_t* msg, ! ieee802154_header_iht* ieee802514_header); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/02a-MAClow/IEEE802154E.c ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.c *** openwsn/02a-MAClow/IEEE802154E.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.c Wed Jan 15 13:48:26 2014 *************** *** 1,1908 **** ! #include "openwsn.h" ! #include "IEEE802154E.h" ! #include "radio.h" ! #include "radiotimer.h" ! #include "IEEE802154.h" ! #include "openqueue.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "schedule.h" ! #include "packetfunctions.h" ! #include "scheduler.h" ! #include "leds.h" ! #include "neighbors.h" ! #include "debugpins.h" ! #include "res.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! // misc ! asn_t asn; // current absolute slot number ! slotOffset_t slotOffset; // current slot offset ! slotOffset_t nextActiveSlotOffset; // next active slot offset ! PORT_TIMER_WIDTH deSyncTimeout; // how many slots left before looses sync ! bool isSync; // TRUE iff mote is synchronized to network ! // as shown on the chronogram ! ieee154e_state_t state; // state of the FSM ! OpenQueueEntry_t* dataToSend; // pointer to the data to send ! OpenQueueEntry_t* dataReceived; // pointer to the data received ! OpenQueueEntry_t* ackToSend; // pointer to the ack to send ! OpenQueueEntry_t* ackReceived; // pointer to the ack received ! PORT_TIMER_WIDTH lastCapturedTime; // last captured time ! PORT_TIMER_WIDTH syncCapturedTime; // captured time used to sync ! //channel hopping ! uint8_t freq; // frequency of the current slot ! uint8_t asnOffset; // offset inside the frame ! } ieee154e_vars_t; ! ! ieee154e_vars_t ieee154e_vars; ! ! typedef struct { ! PORT_TIMER_WIDTH num_newSlot; ! PORT_TIMER_WIDTH num_timer; ! PORT_TIMER_WIDTH num_startOfFrame; ! PORT_TIMER_WIDTH num_endOfFrame; ! } ieee154e_dbg_t; ! ! ieee154e_dbg_t ieee154e_dbg; ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t numSyncPkt; // how many times synchronized on a non-ACK packet ! uint8_t numSyncAck; // how many times synchronized on an ACK ! PORT_SIGNED_INT_WIDTH minCorrection; // minimum time correction ! PORT_SIGNED_INT_WIDTH maxCorrection; // maximum time correction ! uint8_t numDeSync; // number of times a desync happened ! } ieee154e_stats_t; ! PRAGMA(pack()); ! ! ieee154e_stats_t ieee154e_stats; ! ! //=========================== prototypes ====================================== ! ! // SYNCHRONIZING ! void activity_synchronize_newSlot(); ! void activity_synchronize_startOfFrame(PORT_TIMER_WIDTH capturedTime); ! void activity_synchronize_endOfFrame(PORT_TIMER_WIDTH capturedTime); ! // TX ! void activity_ti1ORri1(); ! void activity_ti2(); ! void activity_tie1(); ! void activity_ti3(); ! void activity_tie2(); ! void activity_ti4(PORT_TIMER_WIDTH capturedTime); ! void activity_tie3(); ! void activity_ti5(PORT_TIMER_WIDTH capturedTime); ! void activity_ti6(); ! void activity_tie4(); ! void activity_ti7(); ! void activity_tie5(); ! void activity_ti8(PORT_TIMER_WIDTH capturedTime); ! void activity_tie6(); ! void activity_ti9(PORT_TIMER_WIDTH capturedTime); ! // RX ! void activity_ri2(); ! void activity_rie1(); ! void activity_ri3(); ! void activity_rie2(); ! void activity_ri4(PORT_TIMER_WIDTH capturedTime); ! void activity_rie3(); ! void activity_ri5(PORT_TIMER_WIDTH capturedTime); ! void activity_ri6(); ! void activity_rie4(); ! void activity_ri7(); ! void activity_rie5(); ! void activity_ri8(PORT_TIMER_WIDTH capturedTime); ! void activity_rie6(); ! void activity_ri9(PORT_TIMER_WIDTH capturedTime); ! // frame validity check ! bool isValidAdv(ieee802154_header_iht* ieee802514_header); ! bool isValidRxFrame(ieee802154_header_iht* ieee802514_header); ! bool isValidAck(ieee802154_header_iht* ieee802514_header, ! OpenQueueEntry_t* packetSent); ! // ASN handling ! void incrementAsnOffset(); ! void asnWriteToAdv(OpenQueueEntry_t* advFrame); ! void asnStoreFromAdv(OpenQueueEntry_t* advFrame); ! // synchronization ! void synchronizePacket(PORT_TIMER_WIDTH timeReceived); ! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection); ! void changeIsSync(bool newIsSync); ! // notifying upper layer ! void notif_sendDone(OpenQueueEntry_t* packetSent, error_t error); ! void notif_receive(OpenQueueEntry_t* packetReceived); ! // statistics ! void resetStats(); ! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); ! // misc ! uint8_t calculateFrequency(uint8_t channelOffset); ! void changeState(ieee154e_state_t newstate); ! void endSlot(); ! bool debugPrint_asn(); ! bool debugPrint_isSync(); ! ! //=========================== admin =========================================== ! ! /** ! \brief This function initializes this module. ! ! Call this function once before any other function in this module, possibly ! during boot-up. ! */ ! void ieee154e_init() { ! ! // initialize variables ! memset(&ieee154e_vars,0,sizeof(ieee154e_vars_t)); ! memset(&ieee154e_dbg,0,sizeof(ieee154e_dbg_t)); ! ! if (idmanager_getIsDAGroot()==TRUE) { ! changeIsSync(TRUE); ! } else { ! changeIsSync(FALSE); ! } ! ! resetStats(); ! ieee154e_stats.numDeSync = 0; ! ! // switch radio on ! radio_rfOn(); ! ! // set callback functions for the radio ! radio_setOverflowCb(isr_ieee154e_newSlot); ! radio_setCompareCb(isr_ieee154e_timer); ! radio_setStartFrameCb(ieee154e_startOfFrame); ! radio_setEndFrameCb(ieee154e_endOfFrame); ! // have the radio start its timer ! radio_startTimer(TsSlotDuration); ! } ! ! //=========================== public ========================================== ! ! /** ! /brief Difference between some older ASN and the current ASN. ! ! \param someASN [in] some ASN to compare to the current ! ! \returns The ASN difference, or 0xffff if more than 65535 different ! */ ! PORT_TIMER_WIDTH ieee154e_asnDiff(asn_t* someASN) { ! PORT_TIMER_WIDTH diff; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! if (ieee154e_vars.asn.byte4 != someASN->byte4) { ! ENABLE_INTERRUPTS(); ! return (PORT_TIMER_WIDTH)0xFFFFFFFF;; ! } ! ! diff = 0; ! if (ieee154e_vars.asn.bytes2and3 == someASN->bytes2and3) { ! ENABLE_INTERRUPTS(); ! return ieee154e_vars.asn.bytes0and1-someASN->bytes0and1; ! } else if (ieee154e_vars.asn.bytes2and3-someASN->bytes2and3==1) { ! diff = ieee154e_vars.asn.bytes0and1; ! diff += 0xffff-someASN->bytes0and1; ! diff += 1; ! } else { ! diff = (PORT_TIMER_WIDTH)0xFFFFFFFF;; ! } ! ENABLE_INTERRUPTS(); ! return diff; ! } ! ! //======= events ! ! /** ! \brief Indicates a new slot has just started. ! ! This function executes in ISR mode, when the new slot timer fires. ! */ ! void isr_ieee154e_newSlot() { ! radio_setTimerPeriod(TsSlotDuration); ! if (ieee154e_vars.isSync==FALSE) { ! activity_synchronize_newSlot(); ! } else { ! activity_ti1ORri1(); ! } ! ieee154e_dbg.num_newSlot++; ! } ! ! /** ! \brief Indicates the FSM timer has fired. ! ! This function executes in ISR mode, when the FSM timer fires. ! */ ! void isr_ieee154e_timer() { ! switch (ieee154e_vars.state) { ! case S_TXDATAOFFSET: ! activity_ti2(); ! break; ! case S_TXDATAPREPARE: ! activity_tie1(); ! break; ! case S_TXDATAREADY: ! activity_ti3(); ! break; ! case S_TXDATADELAY: ! activity_tie2(); ! break; ! case S_TXDATA: ! activity_tie3(); ! break; ! case S_RXACKOFFSET: ! activity_ti6(); ! break; ! case S_RXACKPREPARE: ! activity_tie4(); ! break; ! case S_RXACKREADY: ! activity_ti7(); ! break; ! case S_RXACKLISTEN: ! activity_tie5(); ! break; ! case S_RXACK: ! activity_tie6(); ! break; ! case S_RXDATAOFFSET: ! activity_ri2(); ! break; ! case S_RXDATAPREPARE: ! activity_rie1(); ! break; ! case S_RXDATAREADY: ! activity_ri3(); ! break; ! case S_RXDATALISTEN: ! activity_rie2(); ! break; ! case S_RXDATA: ! activity_rie3(); ! break; ! case S_TXACKOFFSET: ! activity_ri6(); ! break; ! case S_TXACKPREPARE: ! activity_rie4(); ! break; ! case S_TXACKREADY: ! activity_ri7(); ! break; ! case S_TXACKDELAY: ! activity_rie5(); ! break; ! case S_TXACK: ! activity_rie6(); ! break; ! default: ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_TIMERFIRES, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! break; ! } ! ieee154e_dbg.num_timer++; ! } ! ! /** ! \brief Indicates the radio just received the first byte of a packet. ! ! This function executes in ISR mode. ! */ ! void ieee154e_startOfFrame(PORT_TIMER_WIDTH capturedTime) { ! if (ieee154e_vars.isSync==FALSE) { ! activity_synchronize_startOfFrame(capturedTime); ! } else { ! switch (ieee154e_vars.state) { ! case S_TXDATADELAY: ! activity_ti4(capturedTime); ! break; ! case S_RXACKREADY: ! /* ! It is possible to receive in this state for radio where there is no ! way of differentiated between "ready to listen" and "listening" ! (e.g. CC2420). We must therefore expect to the start of a packet in ! this "ready" state. ! */ ! // no break! ! case S_RXACKLISTEN: ! activity_ti8(capturedTime); ! break; ! case S_RXDATAREADY: ! /* ! Similarly as above. ! */ ! // no break! ! case S_RXDATALISTEN: ! activity_ri4(capturedTime); ! break; ! case S_TXACKDELAY: ! activity_ri8(capturedTime); ! break; ! default: ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_NEWSLOT, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! break; ! } ! } ! ieee154e_dbg.num_startOfFrame++; ! } ! ! /** ! \brief Indicates the radio just received the last byte of a packet. ! ! This function executes in ISR mode. ! */ ! void ieee154e_endOfFrame(PORT_TIMER_WIDTH capturedTime) { ! if (ieee154e_vars.isSync==FALSE) { ! activity_synchronize_endOfFrame(capturedTime); ! } else { ! switch (ieee154e_vars.state) { ! case S_TXDATA: ! activity_ti5(capturedTime); ! break; ! case S_RXACK: ! activity_ti9(capturedTime); ! break; ! case S_RXDATA: ! activity_ri5(capturedTime); ! break; ! case S_TXACK: ! activity_ri9(capturedTime); ! break; ! default: ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDOFFRAME, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! break; ! } ! } ! ieee154e_dbg.num_endOfFrame++; ! } ! ! //======= misc ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_asn() { ! asn_t output; ! output.byte4 = ieee154e_vars.asn.byte4; ! output.bytes2and3 = ieee154e_vars.asn.bytes2and3; ! output.bytes0and1 = ieee154e_vars.asn.bytes0and1; ! openserial_printStatus(STATUS_ASN,(uint8_t*)&output,sizeof(output)); ! return TRUE; ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_isSync() { ! uint8_t output=0; ! output = ieee154e_vars.isSync; ! openserial_printStatus(STATUS_ISSYNC,(uint8_t*)&output,sizeof(uint8_t)); ! return TRUE; ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_macStats() { ! // send current stats over serial ! openserial_printStatus(STATUS_MACSTATS,(uint8_t*)&ieee154e_stats,sizeof(ieee154e_stats_t)); ! return TRUE; ! } ! ! //=========================== private ========================================= ! ! //======= SYNCHRONIZING ! ! port_INLINE void activity_synchronize_newSlot() { ! // I'm in the middle of receiving a packet ! if (ieee154e_vars.state==S_SYNCRX) { ! return; ! } ! ! // if this is the first time I call this function while not synchronized, ! // switch on the radio in Rx mode ! if (ieee154e_vars.state!=S_SYNCLISTEN) { ! // change state ! changeState(S_SYNCLISTEN); ! ! // turn off the radio (in case it wasn't yet) ! radio_rfOff(); ! ! // configure the radio to listen to the default synchronizing channel ! radio_setFrequency(SYNCHRONIZING_CHANNEL); ! ! // update record of current channel ! ieee154e_vars.freq = SYNCHRONIZING_CHANNEL; ! ! // switch on the radio in Rx mode. ! radio_rxEnable(); ! radio_rxNow(); ! } ! ! // increment ASN (used only to schedule serial activity) ! incrementAsnOffset(); ! ! // to be able to receive and transmist serial even when not synchronized ! // take turns every 8 slots sending and receiving ! if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0000) { ! openserial_stop(); ! openserial_startOutput(); ! } else if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0008) { ! openserial_stop(); ! openserial_startInput(); ! } ! } ! ! port_INLINE void activity_synchronize_startOfFrame(PORT_TIMER_WIDTH capturedTime) { ! ! // don't care about packet if I'm not listening ! if (ieee154e_vars.state!=S_SYNCLISTEN) { ! return; ! } ! ! // change state ! changeState(S_SYNCRX); ! ! // stop the serial ! openserial_stop(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // record the captured time (for sync) ! ieee154e_vars.syncCapturedTime = capturedTime; ! } ! ! port_INLINE void activity_synchronize_endOfFrame(PORT_TIMER_WIDTH capturedTime) { ! ieee802154_header_iht ieee802514_header; ! ! // check state ! if (ieee154e_vars.state!=S_SYNCRX) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDFRAME_SYNC, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)0); ! // abort ! endSlot(); ! } ! ! // change state ! changeState(S_SYNCPROC); ! ! // get a buffer to put the (received) frame in ! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.dataReceived==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; ! ! /* ! The do-while loop that follows is a little parsing trick. ! Because it contains a while(0) condition, it gets executed only once. ! The behavior is: ! - if a break occurs inside the do{} body, the error code below the loop ! gets executed. This indicates something is wrong with the packet being ! parsed. ! - if a return occurs inside the do{} body, the error code below the loop ! does not get executed. This indicates the received packet is correct. ! */ ! do { // this "loop" is only executed once ! ! // retrieve the received data frame from the radio's Rx buffer ! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); ! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, ! &ieee154e_vars.dataReceived->length, ! sizeof(ieee154e_vars.dataReceived->packet), ! &ieee154e_vars.dataReceived->l1_rssi, ! &ieee154e_vars.dataReceived->l1_lqi, ! &ieee154e_vars.dataReceived->l1_crc); ! ! // break if packet too short ! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX) { ! // break from the do-while loop and execute abort code below ! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, ! (errorparameter_t)0, ! ieee154e_vars.dataReceived->length); ! break; ! } ! ! // toss CRC (2 last bytes) ! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); ! ! // break if invalid CRC ! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { ! // break from the do-while loop and execute abort code below ! break; ! } ! ! // parse the IEEE802.15.4 header (synchronize, end of frame) ! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); ! ! // break if invalid IEEE802.15.4 header ! if (ieee802514_header.valid==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // store header details in packet buffer ! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; ! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; ! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! ! // toss the IEEE802.15.4 header ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); ! ! // break if invalid ADV ! if (isValidAdv(&ieee802514_header)==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // turn off the radio ! radio_rfOff(); ! ! // record the ASN from the ADV payload ! asnStoreFromAdv(ieee154e_vars.dataReceived); ! ! // toss the ADV payload ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ADV_PAYLOAD_LENGTH); ! ! // synchronize (for the first time) to the sender's ADV ! synchronizePacket(ieee154e_vars.syncCapturedTime); ! ! // declare synchronized ! changeIsSync(TRUE); ! ! // log the info ! openserial_printInfo(COMPONENT_IEEE802154E,ERR_SYNCHRONIZED, ! (errorparameter_t)ieee154e_vars.slotOffset, ! (errorparameter_t)0); ! ! // send received ADV up the stack so RES can update statistics (synchronizing) ! notif_receive(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // official end of synchronization ! endSlot(); ! ! // everything went well, return here not to execute the error code below ! return; ! ! } while (0); ! ! // free the (invalid) received data buffer so RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // return to listening state ! changeState(S_SYNCLISTEN); ! } ! ! //======= TX ! ! port_INLINE void activity_ti1ORri1() { ! cellType_t cellType; ! open_addr_t neighbor; ! uint8_t i; ! ! // increment ASN (do this first so debug pins are in sync) ! incrementAsnOffset(); ! ! // wiggle debug pins ! debugpins_slot_toggle(); ! if (ieee154e_vars.slotOffset==0) { ! debugpins_frame_toggle(); ! } ! ! // desynchronize if needed ! if (idmanager_getIsDAGroot()==FALSE) { ! ieee154e_vars.deSyncTimeout--; ! if (ieee154e_vars.deSyncTimeout==0) { ! // declare myself desynchronized ! changeIsSync(FALSE); ! ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_DESYNCHRONIZED, ! (errorparameter_t)ieee154e_vars.slotOffset, ! (errorparameter_t)0); ! ! // update the statistics ! ieee154e_stats.numDeSync++; ! ! // abort ! endSlot(); ! return; ! } ! } ! ! // if the previous slot took too long, we will not be in the right state ! if (ieee154e_vars.state!=S_SLEEP) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_STARTSLOT, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! return; ! } ! ! if (ieee154e_vars.slotOffset==ieee154e_vars.nextActiveSlotOffset) { ! // this is the next active slot ! ! // advance the schedule ! schedule_advanceSlot(); ! ! // find the next one ! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); ! } else { ! // this is NOT the next active slot, abort ! // stop using serial ! openserial_stop(); ! // abort the slot ! endSlot(); ! //start outputing serial ! openserial_startOutput(); ! return; ! } ! ! // check the schedule to see what type of slot this is ! cellType = schedule_getType(); ! switch (cellType) { ! case CELLTYPE_ADV: ! // stop using serial ! openserial_stop(); ! // look for an ADV packet in the queue ! ieee154e_vars.dataToSend = openqueue_macGetAdvPacket(); ! if (ieee154e_vars.dataToSend==NULL) { // I will be listening for an ADV ! // change state ! changeState(S_RXDATAOFFSET); ! // arm rt1 ! radiotimer_schedule(DURATION_rt1); ! } else { // I will be sending an ADV ! // change state ! changeState(S_TXDATAOFFSET); ! // change owner ! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; ! // fill in the ASN field of the ADV ! asnWriteToAdv(ieee154e_vars.dataToSend); ! // record that I attempt to transmit this packet ! ieee154e_vars.dataToSend->l2_numTxAttempts++; ! // arm tt1 ! radiotimer_schedule(DURATION_tt1); ! } ! break; ! case CELLTYPE_TXRX: ! case CELLTYPE_TX: ! // stop using serial ! openserial_stop(); ! // check whether we can send ! if (schedule_getOkToSend()) { ! schedule_getNeighbor(&neighbor); ! ieee154e_vars.dataToSend = openqueue_macGetDataPacket(&neighbor); ! } else { ! ieee154e_vars.dataToSend = NULL; ! } ! if (ieee154e_vars.dataToSend!=NULL) { // I have a packet to send ! // change state ! changeState(S_TXDATAOFFSET); ! // change owner ! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; ! // record that I attempt to transmit this packet ! ieee154e_vars.dataToSend->l2_numTxAttempts++; ! // arm tt1 ! radiotimer_schedule(DURATION_tt1); ! } else if (cellType==CELLTYPE_TX){ ! // abort ! endSlot(); ! } ! if (cellType==CELLTYPE_TX || ! (cellType==CELLTYPE_TXRX && ieee154e_vars.dataToSend!=NULL)) { ! break; ! } ! case CELLTYPE_RX: ! // stop using serial ! openserial_stop(); ! // change state ! changeState(S_RXDATAOFFSET); ! // arm rt1 ! radiotimer_schedule(DURATION_rt1); ! break; ! case CELLTYPE_SERIALRX: ! // stop using serial ! openserial_stop(); ! // abort the slot ! endSlot(); ! //start inputting serial data ! openserial_startInput(); ! //this is to emulate a set of serial input slots without having the slotted structure. ! radio_setTimerPeriod(TsSlotDuration*(NUMSERIALRX)); ! ! //increase ASN by NUMSERIALRX-1 slots as at this slot is already incremented by 1 ! for (i=0;ipayload, ! ieee154e_vars.dataToSend->length); ! ! // enable the radio in Tx mode. This does not send the packet. ! radio_txEnable(); ! ! // arm tt2 ! radiotimer_schedule(DURATION_tt2); ! ! // change state ! changeState(S_TXDATAREADY); ! } ! ! port_INLINE void activity_tie1() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXDATAPREPARE_OVERFLOW, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti3() { ! // change state ! changeState(S_TXDATADELAY); ! ! // arm tt3 ! radiotimer_schedule(DURATION_tt3); ! ! // give the 'go' to transmit ! radio_txNow(); ! } ! ! port_INLINE void activity_tie2() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIO_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti4(PORT_TIMER_WIDTH capturedTime) { ! // change state ! changeState(S_TXDATA); ! ! // cancel tt3 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // arm tt4 ! radiotimer_schedule(DURATION_tt4); ! } ! ! port_INLINE void activity_tie3() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti5(PORT_TIMER_WIDTH capturedTime) { ! bool listenForAck; ! ! // change state ! changeState(S_RXACKOFFSET); ! ! // cancel tt4 ! radiotimer_cancel(); ! ! // turn off the radio ! radio_rfOff(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // decides whether to listen for an ACK ! if (packetfunctions_isBroadcastMulticast(&ieee154e_vars.dataToSend->l2_nextORpreviousHop)==TRUE) { ! listenForAck = FALSE; ! } else { ! listenForAck = TRUE; ! } ! ! if (listenForAck==TRUE) { ! // arm tt5 ! radiotimer_schedule(DURATION_tt5); ! } else { ! // indicate succesful Tx to schedule to keep statistics ! schedule_indicateTx(&ieee154e_vars.asn,TRUE); ! // indicate to upper later the packet was sent successfully ! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); ! // reset local variable ! ieee154e_vars.dataToSend = NULL; ! // abort ! endSlot(); ! } ! } ! ! port_INLINE void activity_ti6() { ! // change state ! changeState(S_RXACKPREPARE); ! ! // calculate the frequency to transmit on ! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); ! ! // configure the radio for that frequency ! //radio_setFrequency(frequency); ! radio_setFrequency(ieee154e_vars.freq); ! ! // enable the radio in Rx mode. The radio is not actively listening yet. ! radio_rxEnable(); ! ! // arm tt6 ! radiotimer_schedule(DURATION_tt6); ! ! // change state ! changeState(S_RXACKREADY); ! } ! ! port_INLINE void activity_tie4() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXACKPREPARE_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti7() { ! // change state ! changeState(S_RXACKLISTEN); ! ! // start listening ! radio_rxNow(); ! ! // arm tt7 ! radiotimer_schedule(DURATION_tt7); ! } ! ! port_INLINE void activity_tie5() { ! // indicate transmit failed to schedule to keep stats ! schedule_indicateTx(&ieee154e_vars.asn,FALSE); ! ! // decrement transmits left counter ! ieee154e_vars.dataToSend->l2_retriesLeft--; ! ! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { ! // indicate tx fail if no more retries left ! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); ! } else { ! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component ! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; ! } ! ! // reset local variable ! ieee154e_vars.dataToSend = NULL; ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti8(PORT_TIMER_WIDTH capturedTime) { ! // change state ! changeState(S_RXACK); ! ! // cancel tt7 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // arm tt8 ! radiotimer_schedule(DURATION_tt8); ! } ! ! port_INLINE void activity_tie6() { ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti9(PORT_TIMER_WIDTH capturedTime) { ! ieee802154_header_iht ieee802514_header; ! volatile PORT_SIGNED_INT_WIDTH timeCorrection; ! uint8_t byte0; ! uint8_t byte1; ! ! // change state ! changeState(S_TXPROC); ! ! // cancel tt8 ! radiotimer_cancel(); ! ! // turn off the radio ! radio_rfOff(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // get a buffer to put the (received) ACK in ! ieee154e_vars.ackReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.ackReceived==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.ackReceived->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.ackReceived->owner = COMPONENT_IEEE802154E; ! ! /* ! The do-while loop that follows is a little parsing trick. ! Because it contains a while(0) condition, it gets executed only once. ! Below the do-while loop is some code to cleans up the ack variable. ! Anywhere in the do-while loop, a break statement can be called to jump to ! the clean up code early. If the loop ends without a break, the received ! packet was correct. If it got aborted early (through a break), the packet ! was faulty. ! */ ! do { // this "loop" is only executed once ! ! // retrieve the received ack frame from the radio's Rx buffer ! ieee154e_vars.ackReceived->payload = &(ieee154e_vars.ackReceived->packet[FIRST_FRAME_BYTE]); ! radio_getReceivedFrame( ieee154e_vars.ackReceived->payload, ! &ieee154e_vars.ackReceived->length, ! sizeof(ieee154e_vars.ackReceived->packet), ! &ieee154e_vars.ackReceived->l1_rssi, ! &ieee154e_vars.ackReceived->l1_lqi, ! &ieee154e_vars.ackReceived->l1_crc); ! ! // break if wrong length ! if (ieee154e_vars.ackReceived->lengthlength>LENGTH_IEEE154_MAX) { ! // break from the do-while loop and execute the clean-up code below ! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, ! (errorparameter_t)1, ! ieee154e_vars.ackReceived->length); ! ! break; ! } ! ! // toss CRC (2 last bytes) ! packetfunctions_tossFooter( ieee154e_vars.ackReceived, LENGTH_CRC); ! ! // break if invalid CRC ! if (ieee154e_vars.ackReceived->l1_crc==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // parse the IEEE802.15.4 header (RX ACK) ! ieee802154_retrieveHeader(ieee154e_vars.ackReceived,&ieee802514_header); ! ! // break if invalid IEEE802.15.4 header ! if (ieee802514_header.valid==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // store header details in packet buffer ! ieee154e_vars.ackReceived->l2_frameType = ieee802514_header.frameType; ! ieee154e_vars.ackReceived->l2_dsn = ieee802514_header.dsn; ! memcpy(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! ! // toss the IEEE802.15.4 header ! packetfunctions_tossHeader(ieee154e_vars.ackReceived,ieee802514_header.headerLength); ! ! // break if invalid ACK ! if (isValidAck(&ieee802514_header,ieee154e_vars.dataToSend)==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // resynchronize if I'm not a DAGroot and ACK from preferred parent ! if (idmanager_getIsDAGroot()==FALSE && ! neighbors_isPreferredParent(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop)) ) { ! byte0 = ieee154e_vars.ackReceived->payload[0]; ! byte1 = ieee154e_vars.ackReceived->payload[1]; ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_TIMER_WIDTH)byte1<<8 | (PORT_TIMER_WIDTH)byte0); ! timeCorrection /= US_PER_TICK; ! timeCorrection = -timeCorrection; ! synchronizeAck(timeCorrection); ! } ! ! // inform schedule of successful transmission ! schedule_indicateTx(&ieee154e_vars.asn,TRUE); ! ! // inform upper layer ! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); ! ieee154e_vars.dataToSend = NULL; ! ! // in any case, execute the clean-up code below (processing of ACK done) ! } while (0); ! ! // free the received ack so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); ! ! // clear local variable ! ieee154e_vars.ackReceived = NULL; ! ! // official end of Tx slot ! endSlot(); ! } ! ! //======= RX ! ! port_INLINE void activity_ri2() { ! // change state ! changeState(S_RXDATAPREPARE); ! ! // calculate the frequency to transmit on ! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); ! ! // configure the radio for that frequency ! //radio_setFrequency(frequency); ! radio_setFrequency(ieee154e_vars.freq); ! ! // enable the radio in Rx mode. The radio does not actively listen yet. ! radio_rxEnable(); ! ! ! // arm rt2 ! radiotimer_schedule(DURATION_rt2); ! ! // change state ! changeState(S_RXDATAREADY); ! } ! ! port_INLINE void activity_rie1() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXDATAPREPARE_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri3() { ! // change state ! changeState(S_RXDATALISTEN); ! ! // give the 'go' to receive ! radio_rxNow(); ! ! // arm rt3 ! radiotimer_schedule(DURATION_rt3); ! } ! ! port_INLINE void activity_rie2() { ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri4(PORT_TIMER_WIDTH capturedTime) { ! // change state ! changeState(S_RXDATA); ! ! // cancel rt3 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // record the captured time to sync ! ieee154e_vars.syncCapturedTime = capturedTime; ! ! // arm rt4 ! radiotimer_schedule(DURATION_rt4); ! } ! ! port_INLINE void activity_rie3() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri5(PORT_TIMER_WIDTH capturedTime) { ! ieee802154_header_iht ieee802514_header; ! ! // change state ! changeState(S_TXACKOFFSET); ! ! // cancel rt4 ! radiotimer_cancel(); ! ! // turn off the radio ! radio_rfOff(); ! ! // get a buffer to put the (received) data in ! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.dataReceived==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; ! ! /* ! The do-while loop that follows is a little parsing trick. ! Because it contains a while(0) condition, it gets executed only once. ! The behavior is: ! - if a break occurs inside the do{} body, the error code below the loop ! gets executed. This indicates something is wrong with the packet being ! parsed. ! - if a return occurs inside the do{} body, the error code below the loop ! does not get executed. This indicates the received packet is correct. ! */ ! do { // this "loop" is only executed once ! ! // retrieve the received data frame from the radio's Rx buffer ! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); ! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, ! &ieee154e_vars.dataReceived->length, ! sizeof(ieee154e_vars.dataReceived->packet), ! &ieee154e_vars.dataReceived->l1_rssi, ! &ieee154e_vars.dataReceived->l1_lqi, ! &ieee154e_vars.dataReceived->l1_crc); ! ! // break if wrong length ! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX ) { ! // jump to the error code below this do-while loop ! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, ! (errorparameter_t)2, ! ieee154e_vars.dataReceived->length); ! break; ! } ! ! // toss CRC (2 last bytes) ! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); ! ! // if CRC doesn't check, stop ! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { ! // jump to the error code below this do-while loop ! break; ! } ! ! // parse the IEEE802.15.4 header (RX DATA) ! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); ! ! // break if invalid IEEE802.15.4 header ! if (ieee802514_header.valid==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // store header details in packet buffer ! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; ! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; ! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! ! // toss the IEEE802.15.4 header ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); ! ! // if I just received a valid ADV, record the ASN and toss the ADV payload ! if (isValidAdv(&ieee802514_header)==TRUE) { ! if (idmanager_getIsDAGroot()==FALSE) { ! asnStoreFromAdv(ieee154e_vars.dataReceived); ! } ! // toss the ADV payload ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ADV_PAYLOAD_LENGTH); ! } ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // if I just received an invalid frame, stop ! if (isValidRxFrame(&ieee802514_header)==FALSE) { ! // jump to the error code below this do-while loop ! break; ! } ! ! // check if ack requested ! if (ieee802514_header.ackRequested==1) { ! // arm rt5 ! radiotimer_schedule(DURATION_rt5); ! } else { ! // synchronize to the received packet iif I'm not a DAGroot and this is my preferred parent ! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { ! synchronizePacket(ieee154e_vars.syncCapturedTime); ! } ! // indicate reception to upper layer (no ACK asked) ! notif_receive(ieee154e_vars.dataReceived); ! // reset local variable ! ieee154e_vars.dataReceived = NULL; ! // abort ! endSlot(); ! } ! ! // everything went well, return here not to execute the error code below ! return; ! ! } while(0); ! ! // free the (invalid) received data so RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri6() { ! PORT_SIGNED_INT_WIDTH timeCorrection; ! ! // change state ! changeState(S_TXACKPREPARE); ! ! // get a buffer to put the ack to send in ! ieee154e_vars.ackToSend = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.ackToSend==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // indicate we received a packet anyway (we don't want to loose any) ! notif_receive(ieee154e_vars.dataReceived); ! // free local variable ! ieee154e_vars.dataReceived = NULL; ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.ackToSend->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.ackToSend->owner = COMPONENT_IEEE802154E; ! ! // calculate the time timeCorrection (this is the time when the packet arrive w.r.t the time it should be. ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.syncCapturedTime-(PORT_SIGNED_INT_WIDTH)TsTxOffset); ! ! // add the payload to the ACK (i.e. the timeCorrection) ! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(IEEE802154E_ACK_ht)); ! timeCorrection = -timeCorrection; ! timeCorrection *= US_PER_TICK; ! ieee154e_vars.ackToSend->payload[0] = (uint8_t)((((PORT_TIMER_WIDTH)timeCorrection) ) & 0xff); ! ieee154e_vars.ackToSend->payload[1] = (uint8_t)((((PORT_TIMER_WIDTH)timeCorrection)>>8) & 0xff); ! ! // prepend the IEEE802.15.4 header to the ACK ! ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; ! ieee154e_vars.ackToSend->l2_dsn = ieee154e_vars.dataReceived->l2_dsn; ! ieee802154_prependHeader(ieee154e_vars.ackToSend, ! ieee154e_vars.ackToSend->l2_frameType, ! IEEE154_SEC_NO_SECURITY, ! ieee154e_vars.dataReceived->l2_dsn, ! &(ieee154e_vars.dataReceived->l2_nextORpreviousHop) ! ); ! ! // space for 2-byte CRC ! packetfunctions_reserveFooterSize(ieee154e_vars.ackToSend,2); ! ! // calculate the frequency to transmit on ! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); ! ! // configure the radio for that frequency ! //radio_setFrequency(frequency); ! radio_setFrequency(ieee154e_vars.freq); ! ! // load the packet in the radio's Tx buffer ! radio_loadPacket(ieee154e_vars.ackToSend->payload, ! ieee154e_vars.ackToSend->length); ! ! // enable the radio in Tx mode. This does not send that packet. ! radio_txEnable(); ! ! // arm rt6 ! radiotimer_schedule(DURATION_rt6); ! ! // change state ! changeState(S_TXACKREADY); ! } ! ! port_INLINE void activity_rie4() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXACKPREPARE_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri7() { ! // change state ! changeState(S_TXACKDELAY); ! ! // arm rt7 ! radiotimer_schedule(DURATION_rt7); ! ! // give the 'go' to transmit ! radio_txNow(); ! } ! ! port_INLINE void activity_rie5() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIOTX_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri8(PORT_TIMER_WIDTH capturedTime) { ! // change state ! changeState(S_TXACK); ! ! // cancel rt7 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // arm rt8 ! radiotimer_schedule(DURATION_rt8); ! } ! ! port_INLINE void activity_rie6() { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDACKDURATION_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri9(PORT_TIMER_WIDTH capturedTime) { ! // change state ! changeState(S_RXPROC); ! ! // cancel rt8 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // free the ack we just sent so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); ! ! // clear local variable ! ieee154e_vars.ackToSend = NULL; ! ! // synchronize to the received packet ! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { ! synchronizePacket(ieee154e_vars.syncCapturedTime); ! } ! ! // inform upper layer of reception (after ACK sent) ! notif_receive(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // official end of Rx slot ! endSlot(); ! } ! ! //======= frame validity check ! ! /** ! \brief Decides whether the packet I just received is a valid ADV ! ! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just ! received. ! ! A valid ADV frame satisfies the following conditions: ! - its IEEE802.15.4 header is well formatted ! - it's a BEACON frame ! - it's sent to the my PANid ! - its payload length is the expected ADV payload length ! ! \returns TRUE if packet is a valid ADV, FALSE otherwise ! */ ! port_INLINE bool isValidAdv(ieee802154_header_iht* ieee802514_header) { ! return ieee802514_header->valid==TRUE && \ ! ieee802514_header->frameType==IEEE154_TYPE_BEACON && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! ieee154e_vars.dataReceived->length==ADV_PAYLOAD_LENGTH; ! } ! ! /** ! \brief Decides whether the packet I just received is valid received frame. ! ! A valid Rx frame satisfies the following constraints: ! - its IEEE802.15.4 header is well formatted ! - it's a DATA of BEACON frame (i.e. not ACK and not COMMAND) ! - it's sent on the same PANid as mine ! - it's for me (unicast or broadcast) ! ! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just received ! ! \returns TRUE if packet is valid received frame, FALSE otherwise ! */ ! port_INLINE bool isValidRxFrame(ieee802154_header_iht* ieee802514_header) { ! return ieee802514_header->valid==TRUE && \ ! ( ! ieee802514_header->frameType==IEEE154_TYPE_DATA || ! ieee802514_header->frameType==IEEE154_TYPE_BEACON ! ) && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! ( ! idmanager_isMyAddress(&ieee802514_header->dest) || ! packetfunctions_isBroadcastMulticast(&ieee802514_header->dest) ! ); ! } ! ! /** ! \brief Decides whether the packet I just received is a valid ACK. ! ! A packet is a valid ACK if it satisfies the following conditions: ! - the IEEE802.15.4 header is valid ! - the frame type is 'ACK' ! - the sequence number in the ACK matches the sequence number of the packet sent ! - the ACK contains my PANid ! - the packet is unicast to me ! - the packet comes from the neighbor I sent the data to ! ! \param [in] ieee802514_header IEEE802.15.4 header of the packet I just received ! \param [in] packetSent points to the packet I just sent ! ! \returns TRUE if packet is a valid ACK, FALSE otherwise. ! */ ! port_INLINE bool isValidAck(ieee802154_header_iht* ieee802514_header, OpenQueueEntry_t* packetSent) { ! /* ! return ieee802514_header->valid==TRUE && \ ! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ ! ieee802514_header->dsn==packetSent->l2_dsn && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! idmanager_isMyAddress(&ieee802514_header->dest) && \ ! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); ! */ ! // poipoi don't check for seq num ! return ieee802514_header->valid==TRUE && \ ! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! idmanager_isMyAddress(&ieee802514_header->dest) && \ ! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); ! } ! ! //======= ASN handling ! ! port_INLINE void incrementAsnOffset() { ! // increment the asn ! ieee154e_vars.asn.bytes0and1++; ! if (ieee154e_vars.asn.bytes0and1==0) { ! ieee154e_vars.asn.bytes2and3++; ! if (ieee154e_vars.asn.bytes2and3==0) { ! ieee154e_vars.asn.byte4++; ! } ! } ! // increment the offsets ! ieee154e_vars.slotOffset = (ieee154e_vars.slotOffset+1)%schedule_getFrameLength(); ! ieee154e_vars.asnOffset = (ieee154e_vars.asnOffset+1)%16; ! } ! ! port_INLINE void asnWriteToAdv(OpenQueueEntry_t* advFrame) { ! advFrame->l2_payload[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! advFrame->l2_payload[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! advFrame->l2_payload[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! advFrame->l2_payload[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! advFrame->l2_payload[4] = ieee154e_vars.asn.byte4; ! } ! ! //from upper layer that want to send the ASN to compute timming or latency ! void asnWriteToPkt(OpenQueueEntry_t* frame) { ! frame->payload[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! frame->payload[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! frame->payload[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! frame->payload[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! frame->payload[4] = ieee154e_vars.asn.byte4; ! } ! ! void asnWriteToSerial(uint8_t* array) { ! array[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! array[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! array[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! array[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! array[4] = ieee154e_vars.asn.byte4; ! } ! ! ! port_INLINE void asnStoreFromAdv(OpenQueueEntry_t* advFrame) { ! ! // store the ASN ! ieee154e_vars.asn.bytes0and1 = ieee154e_vars.dataReceived->payload[0]+ ! 256*ieee154e_vars.dataReceived->payload[1]; ! ieee154e_vars.asn.bytes2and3 = ieee154e_vars.dataReceived->payload[2]+ ! 256*ieee154e_vars.dataReceived->payload[3]; ! ieee154e_vars.asn.byte4 = ieee154e_vars.dataReceived->payload[4]; ! ! // determine the current slotOffset ! /* ! Note: this is a bit of a hack. Normally, slotOffset=ASN%slotlength. But since ! the ADV is exchanged in slot 0, we know that we're currently at slotOffset==0 ! */ ! ieee154e_vars.slotOffset = 0; ! schedule_syncSlotOffset(ieee154e_vars.slotOffset); ! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); ! ! /* ! infer the asnOffset based on the fact that ! ieee154e_vars.freq = 11 + (asnOffset + channelOffset)%16 ! */ ! ieee154e_vars.asnOffset = ieee154e_vars.freq - 11 - schedule_getChannelOffset(); ! } ! ! //======= synchronization ! ! void synchronizePacket(PORT_TIMER_WIDTH timeReceived) { ! PORT_SIGNED_INT_WIDTH timeCorrection; ! PORT_TIMER_WIDTH newPeriod; ! PORT_TIMER_WIDTH currentValue; ! PORT_TIMER_WIDTH currentPeriod; ! // record the current timer value and period ! currentValue = radio_getTimerValue(); ! currentPeriod = radio_getTimerPeriod(); ! // calculate new period ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)timeReceived-(PORT_SIGNED_INT_WIDTH)TsTxOffset); ! newPeriod = TsSlotDuration; ! // detect whether I'm too close to the edge of the slot, in that case, ! // skip a slot and increase the temporary slot length to be 2 slots long ! if (currentValue LIMITLARGETIMECORRECTION ! ) ! ) { ! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, ! (errorparameter_t)timeCorrection, ! (errorparameter_t)0); ! } ! // update the stats ! ieee154e_stats.numSyncPkt++; ! updateStats(timeCorrection); ! } ! ! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection) { ! PORT_TIMER_WIDTH newPeriod; ! PORT_TIMER_WIDTH currentPeriod; ! // calculate new period ! currentPeriod = radio_getTimerPeriod(); ! newPeriod = (PORT_TIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)currentPeriod-timeCorrection); ! // resynchronize by applying the new period ! radio_setTimerPeriod(newPeriod); ! // reset the de-synchronization timeout ! ieee154e_vars.deSyncTimeout = DESYNCTIMEOUT; ! // log a large timeCorrection ! if ( ! ieee154e_vars.isSync==TRUE && ! ( ! timeCorrection<-LIMITLARGETIMECORRECTION || ! timeCorrection> LIMITLARGETIMECORRECTION ! ) ! ) { ! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, ! (errorparameter_t)timeCorrection, ! (errorparameter_t)1); ! } ! // update the stats ! ieee154e_stats.numSyncAck++; ! updateStats(timeCorrection); ! } ! ! void changeIsSync(bool newIsSync) { ! ieee154e_vars.isSync = newIsSync; ! ! if (ieee154e_vars.isSync==TRUE) { ! leds_sync_on(); ! resetStats(); ! } else { ! leds_sync_off(); ! schedule_resetBackoff(); ! } ! } ! ! //======= notifying upper layer ! ! void notif_sendDone(OpenQueueEntry_t* packetSent, error_t error) { ! // record the outcome of the trasmission attempt ! packetSent->l2_sendDoneError = error; ! // record the current ASN ! memcpy(&packetSent->l2_asn,&ieee154e_vars.asn,sizeof(asn_t)); ! // associate this packet with the virtual component ! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it ! packetSent->owner = COMPONENT_IEEE802154E_TO_RES; ! // post RES's sendDone task ! scheduler_push_task(task_resNotifSendDone,TASKPRIO_RESNOTIF_TXDONE); ! // wake up the scheduler ! SCHEDULER_WAKEUP(); ! } ! ! void notif_receive(OpenQueueEntry_t* packetReceived) { ! // record the current ASN ! memcpy(&packetReceived->l2_asn, &ieee154e_vars.asn, sizeof(asn_t)); ! // indicate reception to the schedule, to keep statistics ! schedule_indicateRx(&packetReceived->l2_asn); ! // associate this packet with the virtual component ! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it ! packetReceived->owner = COMPONENT_IEEE802154E_TO_RES; ! // post RES's Receive task ! scheduler_push_task(task_resNotifReceive,TASKPRIO_RESNOTIF_RX); ! // wake up the scheduler ! SCHEDULER_WAKEUP(); ! } ! ! //======= stats ! ! port_INLINE void resetStats() { ! ieee154e_stats.numSyncPkt = 0; ! ieee154e_stats.numSyncAck = 0; ! ieee154e_stats.minCorrection = 127; ! ieee154e_stats.maxCorrection = -127; ! // do not reset the number of de-synchronizations ! } ! ! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection) { ! // update minCorrection ! if (timeCorrectionieee154e_stats.maxCorrection) { ! ieee154e_stats.maxCorrection = timeCorrection; ! } ! } ! ! //======= misc ! ! /** ! \brief Calculates the frequency channel to transmit on, based on the ! absolute slot number and the channel offset of the requested slot. ! ! During normal operation, the frequency used is a function of the ! channelOffset indicating in the schedule, and of the ASN of the ! slot. This ensures channel hopping, consecutive packets sent in the same slot ! in the schedule are done on a difference frequency channel. ! ! During development, you can force single channel operation by having this ! function return a constant channel number (between 11 and 26). This allows you ! to use a single-channel sniffer; but you can not schedule two links on two ! different channel offsets in the same slot. ! ! \param [in] channelOffset channel offset for the current slot ! ! \returns The calculated frequency channel, an integer between 11 and 26. ! */ ! port_INLINE uint8_t calculateFrequency(uint8_t channelOffset) { ! // comment the following line out to disable channel hopping ! return SYNCHRONIZING_CHANNEL; // single channel ! //return 11+(ieee154e_vars.asnOffset+channelOffset)%16; //channel hopping ! } ! ! /** ! \brief Changes the state of the IEEE802.15.4e FSM. ! ! Besides simply updating the state global variable, ! this function toggles the FSM debug pin. ! ! \param [in] newstate The state the IEEE802.15.4e FSM is now in. ! */ ! void changeState(ieee154e_state_t newstate) { ! // update the state ! ieee154e_vars.state = newstate; ! // wiggle the FSM debug pin ! switch (ieee154e_vars.state) { ! case S_SYNCLISTEN: ! case S_TXDATAOFFSET: ! debugpins_fsm_set(); ! break; ! case S_SLEEP: ! case S_RXDATAOFFSET: ! debugpins_fsm_clr(); ! break; ! case S_SYNCRX: ! case S_SYNCPROC: ! case S_TXDATAPREPARE: ! case S_TXDATAREADY: ! case S_TXDATADELAY: ! case S_TXDATA: ! case S_RXACKOFFSET: ! case S_RXACKPREPARE: ! case S_RXACKREADY: ! case S_RXACKLISTEN: ! case S_RXACK: ! case S_TXPROC: ! case S_RXDATAPREPARE: ! case S_RXDATAREADY: ! case S_RXDATALISTEN: ! case S_RXDATA: ! case S_TXACKOFFSET: ! case S_TXACKPREPARE: ! case S_TXACKREADY: ! case S_TXACKDELAY: ! case S_TXACK: ! case S_RXPROC: ! debugpins_fsm_toggle(); ! break; ! } ! } ! ! /** ! \brief Housekeeping tasks to do at the end of each slot. ! ! This functions is called once in each slot, when there is nothing more ! to do. This might be when an error occured, or when everything went well. ! This function resets the state of the FSM so it is ready for the next slot. ! ! Note that by the time this function is called, any received packet should already ! have been sent to the upper layer. Similarly, in a Tx slot, the sendDone ! function should already have been done. If this is not the case, this function ! will do that for you, but assume that something went wrong. ! */ ! void endSlot() { ! // turn off the radio ! radio_rfOff(); ! ! // clear any pending timer ! radiotimer_cancel(); ! ! // reset capturedTimes ! ieee154e_vars.lastCapturedTime = 0; ! ieee154e_vars.syncCapturedTime = 0; ! ! // clean up dataToSend ! if (ieee154e_vars.dataToSend!=NULL) { ! // if everything went well, dataToSend was set to NULL in ti9 ! // getting here means transmit failed ! ! // indicate Tx fail to schedule to update stats ! schedule_indicateTx(&ieee154e_vars.asn,FALSE); ! ! //decrement transmits left counter ! ieee154e_vars.dataToSend->l2_retriesLeft--; ! ! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { ! // indicate tx fail if no more retries left ! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); ! } else { ! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component ! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; ! } ! ! // reset local variable ! ieee154e_vars.dataToSend = NULL; ! } ! ! // clean up dataReceived ! if (ieee154e_vars.dataReceived!=NULL) { ! // assume something went wrong. If everything went well, dataReceived ! // would have been set to NULL in ri9. ! // indicate "received packet" to upper layer since we don't want to loose packets ! notif_receive(ieee154e_vars.dataReceived); ! // reset local variable ! ieee154e_vars.dataReceived = NULL; ! } ! ! // clean up ackToSend ! if (ieee154e_vars.ackToSend!=NULL) { ! // free ackToSend so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); ! // reset local variable ! ieee154e_vars.ackToSend = NULL; ! } ! ! // clean up ackReceived ! if (ieee154e_vars.ackReceived!=NULL) { ! // free ackReceived so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); ! // reset local variable ! ieee154e_vars.ackReceived = NULL; ! } ! ! // change state ! changeState(S_SLEEP); ! } ! ! bool ieee154e_isSynch(){ ! return ieee154e_vars.isSync; ! } \ No newline at end of file --- 1,2061 ---- ! #include "openwsn.h" ! #include "IEEE802154E.h" ! #include "radio.h" ! #include "radiotimer.h" ! #include "IEEE802154.h" ! #include "openqueue.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "schedule.h" ! #include "packetfunctions.h" ! #include "scheduler.h" ! #include "leds.h" ! #include "neighbors.h" ! #include "debugpins.h" ! #include "res.h" ! ! #include "thread.h" ! ! //=========================== variables ======================================= ! ! ieee154e_vars_t ieee154e_vars; ! ieee154e_stats_t ieee154e_stats; ! ieee154e_dbg_t ieee154e_dbg; ! ! //static char openwsn_ieee802154e_rec_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! //static char openwsn_ieee802154e_send_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! ! //=========================== prototypes ====================================== ! void isr_ieee154e_newSlot(void); ! void isr_ieee154e_timer(void); ! // SYNCHRONIZING ! void activity_synchronize_newSlot(void); ! void activity_synchronize_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_synchronize_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); ! // TX ! void activity_ti1ORri1(void); ! void activity_ti2(void); ! void activity_tie1(void); ! void activity_ti3(void); ! void activity_tie2(void); ! void activity_ti4(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_tie3(void); ! void activity_ti5(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_ti6(void); ! void activity_tie4(void); ! void activity_ti7(void); ! void activity_tie5(void); ! void activity_ti8(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_tie6(void); ! void activity_ti9(PORT_RADIOTIMER_WIDTH capturedTime); ! // RX ! void activity_ri2(void); ! void activity_rie1(void); ! void activity_ri3(void); ! void activity_rie2(void); ! void activity_ri4(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_rie3(void); ! void activity_ri5(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_ri6(void); ! void activity_rie4(void); ! void activity_ri7(void); ! void activity_rie5(void); ! void activity_ri8(PORT_RADIOTIMER_WIDTH capturedTime); ! void activity_rie6(void); ! void activity_ri9(PORT_RADIOTIMER_WIDTH capturedTime); ! // frame validity check ! ! bool isValidRxFrame(ieee802154_header_iht* ieee802514_header); ! bool isValidAck(ieee802154_header_iht* ieee802514_header, ! OpenQueueEntry_t* packetSent); ! // IEs Handling ! bool ieee154e_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE);//xv poipoi ! void ieee154e_processSlotframeLinkIE(OpenQueueEntry_t* pkt,uint8_t * ptr);//xv poipoi ! // ASN handling ! void incrementAsnOffset(void); ! void asnStoreFromAdv(uint8_t* asn); ! void joinPriorityStoreFromAdv(uint8_t jp); ! // synchronization ! void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived); ! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection); ! void changeIsSync(bool newIsSync); ! // notifying upper layer ! void notif_sendDone(OpenQueueEntry_t* packetSent, owerror_t error); ! void notif_receive(OpenQueueEntry_t* packetReceived); ! // statistics ! void resetStats(void); ! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection); ! // misc ! uint8_t calculateFrequency(uint8_t channelOffset); ! void changeState(ieee154e_state_t newstate); ! void endSlot(void); ! bool debugPrint_asn(void); ! bool debugPrint_isSync(void); ! ! //=========================== admin =========================================== ! ! /** ! \brief This function initializes this module. ! ! Call this function once before any other function in this module, possibly ! during boot-up. ! */ ! void ieee154e_init(void) { ! puts(__PRETTY_FUNCTION__); ! // initialize variables ! memset(&ieee154e_vars,0,sizeof(ieee154e_vars_t)); ! memset(&ieee154e_dbg,0,sizeof(ieee154e_dbg_t)); ! ! if (idmanager_getIsDAGroot()==TRUE) { ! changeIsSync(TRUE); ! } else { ! changeIsSync(FALSE); ! } ! ! resetStats(); ! ieee154e_stats.numDeSync = 0; ! ! // switch radio on ! radio_rfOn(); ! ! // set callback functions for the radio ! radio_setOverflowCb(isr_ieee154e_newSlot); ! radio_setCompareCb(isr_ieee154e_timer); ! radio_setStartFrameCb(ieee154e_startOfFrame); ! radio_setEndFrameCb(ieee154e_endOfFrame); ! // have the radio start its timer ! radio_startTimer(TsSlotDuration); ! } ! ! //=========================== public ========================================== ! ! /** ! /brief Difference between some older ASN and the current ASN. ! ! \param[in] someASN some ASN to compare to the current ! ! \returns The ASN difference, or 0xffff if more than 65535 different ! */ ! PORT_RADIOTIMER_WIDTH ieee154e_asnDiff(asn_t* someASN) { ! PORT_RADIOTIMER_WIDTH diff; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! if (ieee154e_vars.asn.byte4 != someASN->byte4) { ! ENABLE_INTERRUPTS(); ! return (PORT_RADIOTIMER_WIDTH)0xFFFFFFFF;; ! } ! ! diff = 0; ! if (ieee154e_vars.asn.bytes2and3 == someASN->bytes2and3) { ! ENABLE_INTERRUPTS(); ! return ieee154e_vars.asn.bytes0and1-someASN->bytes0and1; ! } else if (ieee154e_vars.asn.bytes2and3-someASN->bytes2and3==1) { ! diff = ieee154e_vars.asn.bytes0and1; ! diff += 0xffff-someASN->bytes0and1; ! diff += 1; ! } else { ! diff = (PORT_RADIOTIMER_WIDTH)0xFFFFFFFF;; ! } ! ENABLE_INTERRUPTS(); ! return diff; ! } ! ! //======= events ! ! /** ! \brief Indicates a new slot has just started. ! ! This function executes in ISR mode, when the new slot timer fires. ! */ ! void isr_ieee154e_newSlot(void) { ! radio_setTimerPeriod(TsSlotDuration); ! if (ieee154e_vars.isSync==FALSE) { ! if (idmanager_getIsDAGroot()==TRUE) { ! changeIsSync(TRUE); ! } else { ! activity_synchronize_newSlot(); ! } ! } else { ! activity_ti1ORri1(); ! } ! ieee154e_dbg.num_newSlot++; ! } ! ! /** ! \brief Indicates the FSM timer has fired. ! ! This function executes in ISR mode, when the FSM timer fires. ! */ ! void isr_ieee154e_timer(void) { ! switch (ieee154e_vars.state) { ! case S_TXDATAOFFSET: ! activity_ti2(); ! break; ! case S_TXDATAPREPARE: ! activity_tie1(); ! break; ! case S_TXDATAREADY: ! activity_ti3(); ! break; ! case S_TXDATADELAY: ! activity_tie2(); ! break; ! case S_TXDATA: ! activity_tie3(); ! break; ! case S_RXACKOFFSET: ! activity_ti6(); ! break; ! case S_RXACKPREPARE: ! activity_tie4(); ! break; ! case S_RXACKREADY: ! activity_ti7(); ! break; ! case S_RXACKLISTEN: ! activity_tie5(); ! break; ! case S_RXACK: ! activity_tie6(); ! break; ! case S_RXDATAOFFSET: ! activity_ri2(); ! break; ! case S_RXDATAPREPARE: ! activity_rie1(); ! break; ! case S_RXDATAREADY: ! activity_ri3(); ! break; ! case S_RXDATALISTEN: ! activity_rie2(); ! break; ! case S_RXDATA: ! activity_rie3(); ! break; ! case S_TXACKOFFSET: ! activity_ri6(); ! break; ! case S_TXACKPREPARE: ! activity_rie4(); ! break; ! case S_TXACKREADY: ! activity_ri7(); ! break; ! case S_TXACKDELAY: ! activity_rie5(); ! break; ! case S_TXACK: ! activity_rie6(); ! break; ! default: ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_TIMERFIRES, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! break; ! } ! ieee154e_dbg.num_timer++; ! } ! ! /** ! \brief Indicates the radio just received the first byte of a packet. ! ! This function executes in ISR mode. ! */ ! void ieee154e_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { ! if (ieee154e_vars.isSync==FALSE) { ! activity_synchronize_startOfFrame(capturedTime); ! } else { ! switch (ieee154e_vars.state) { ! case S_TXDATADELAY: ! activity_ti4(capturedTime); ! break; ! case S_RXACKREADY: ! /* ! It is possible to receive in this state for radio where there is no ! way of differentiated between "ready to listen" and "listening" ! (e.g. CC2420). We must therefore expect to the start of a packet in ! this "ready" state. ! */ ! // no break! ! case S_RXACKLISTEN: ! activity_ti8(capturedTime); ! break; ! case S_RXDATAREADY: ! /* ! Similarly as above. ! */ ! // no break! ! case S_RXDATALISTEN: ! activity_ri4(capturedTime); ! break; ! case S_TXACKDELAY: ! activity_ri8(capturedTime); ! break; ! default: ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_NEWSLOT, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! break; ! } ! } ! ieee154e_dbg.num_startOfFrame++; ! } ! ! /** ! \brief Indicates the radio just received the last byte of a packet. ! ! This function executes in ISR mode. ! */ ! void ieee154e_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { ! if (ieee154e_vars.isSync==FALSE) { ! activity_synchronize_endOfFrame(capturedTime); ! } else { ! switch (ieee154e_vars.state) { ! case S_TXDATA: ! activity_ti5(capturedTime); ! break; ! case S_RXACK: ! activity_ti9(capturedTime); ! break; ! case S_RXDATA: ! activity_ri5(capturedTime); ! break; ! case S_TXACK: ! activity_ri9(capturedTime); ! break; ! default: ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDOFFRAME, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! break; ! } ! } ! ieee154e_dbg.num_endOfFrame++; ! } ! ! //======= misc ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_asn(void) { ! asn_t output; ! output.byte4 = ieee154e_vars.asn.byte4; ! output.bytes2and3 = ieee154e_vars.asn.bytes2and3; ! output.bytes0and1 = ieee154e_vars.asn.bytes0and1; ! openserial_printStatus(STATUS_ASN,(uint8_t*)&output,sizeof(output)); ! return TRUE; ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_isSync(void) { ! uint8_t output=0; ! output = ieee154e_vars.isSync; ! openserial_printStatus(STATUS_ISSYNC,(uint8_t*)&output,sizeof(uint8_t)); ! return TRUE; ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_macStats(void) { ! // send current stats over serial ! ieee154e_stats.dutyCycle/=(float)SUPERFRAME_LENGTH; //avg on the all slots of a frame ! ieee154e_stats.dutyCycle/=STATUS_MAX;//because this is executed once every 10 times of debugprint ! ieee154e_stats.dutyCycle*=100.0;//as is a percentage ! openserial_printStatus(STATUS_MACSTATS,(uint8_t*)&ieee154e_stats,sizeof(ieee154e_stats_t)); ! ieee154e_stats.dutyCycle=0; //reset for the next superframe. ! ! return TRUE; ! } ! ! //=========================== private ========================================= ! ! //======= SYNCHRONIZING ! ! port_INLINE void activity_synchronize_newSlot(void) { ! // I'm in the middle of receiving a packet ! if (ieee154e_vars.state==S_SYNCRX) { ! return; ! } ! ! // if this is the first time I call this function while not synchronized, ! // switch on the radio in Rx mode ! if (ieee154e_vars.state!=S_SYNCLISTEN) { ! // change state ! changeState(S_SYNCLISTEN); ! ! // turn off the radio (in case it wasn't yet) ! radio_rfOff(); ! ! // configure the radio to listen to the default synchronizing channel ! radio_setFrequency(SYNCHRONIZING_CHANNEL); ! ! // update record of current channel ! ieee154e_vars.freq = SYNCHRONIZING_CHANNEL; ! ! // switch on the radio in Rx mode. ! radio_rxEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; ! radio_rxNow(); ! } ! ! // increment ASN (used only to schedule serial activity) ! incrementAsnOffset(); ! ! // to be able to receive and transmist serial even when not synchronized ! // take turns every 8 slots sending and receiving ! if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0000) { ! openserial_stop(); ! openserial_startOutput(); ! } else if ((ieee154e_vars.asn.bytes0and1&0x000f)==0x0008) { ! openserial_stop(); ! openserial_startInput(); ! } ! } ! ! port_INLINE void activity_synchronize_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { ! ! // don't care about packet if I'm not listening ! if (ieee154e_vars.state!=S_SYNCLISTEN) { ! return; ! } ! ! // change state ! changeState(S_SYNCRX); ! ! // stop the serial ! openserial_stop(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // record the captured time (for sync) ! ieee154e_vars.syncCapturedTime = capturedTime; ! } ! ! port_INLINE void activity_synchronize_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime) { ! ieee802154_header_iht ieee802514_header; ! uint16_t lenIE=0;//len of IEs being received if any. ! ! // check state ! if (ieee154e_vars.state!=S_SYNCRX) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_ENDFRAME_SYNC, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)0); ! // abort ! endSlot(); ! } ! ! // change state ! changeState(S_SYNCPROC); ! ! // get a buffer to put the (received) frame in ! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.dataReceived==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; ! ! /* ! The do-while loop that follows is a little parsing trick. ! Because it contains a while(0) condition, it gets executed only once. ! The behavior is: ! - if a break occurs inside the do{} body, the error code below the loop ! gets executed. This indicates something is wrong with the packet being ! parsed. ! - if a return occurs inside the do{} body, the error code below the loop ! does not get executed. This indicates the received packet is correct. ! */ ! do { // this "loop" is only executed once ! ! // retrieve the received data frame from the radio's Rx buffer ! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); ! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, ! &ieee154e_vars.dataReceived->length, ! sizeof(ieee154e_vars.dataReceived->packet), ! &ieee154e_vars.dataReceived->l1_rssi, ! &ieee154e_vars.dataReceived->l1_lqi, ! &ieee154e_vars.dataReceived->l1_crc); ! ! // break if packet too short ! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX) { ! // break from the do-while loop and execute abort code below ! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, ! (errorparameter_t)0, ! ieee154e_vars.dataReceived->length); ! break; ! } ! ! // toss CRC (2 last bytes) ! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); ! ! // break if invalid CRC ! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { ! // break from the do-while loop and execute abort code below ! break; ! } ! ! // parse the IEEE802.15.4 header (synchronize, end of frame) ! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); ! ! // break if invalid IEEE802.15.4 header ! if (ieee802514_header.valid==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // store header details in packet buffer ! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; ! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; ! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! ! // toss the IEEE802.15.4 header -- this does not include IEs as they are processed ! // next. ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); ! ! // handle IEs -- xv poipoi ! // break if invalid ADV ! if ((ieee802514_header.valid==TRUE && ! ieee802514_header.ieListPresent==TRUE && ! ieee802514_header.frameType==IEEE154_TYPE_BEACON && ! packetfunctions_sameAddress(&ieee802514_header.panid,idmanager_getMyID(ADDR_PANID)) && ! ieee154e_processIEs(ieee154e_vars.dataReceived,&lenIE))==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // turn off the radio ! radio_rfOff(); ! //compute radio duty cycle ! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); ! ! // toss the IEs including Synch ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,lenIE); ! ! // synchronize (for the first time) to the sender's ADV ! synchronizePacket(ieee154e_vars.syncCapturedTime); ! ! // declare synchronized ! changeIsSync(TRUE); ! ! // log the info ! openserial_printInfo(COMPONENT_IEEE802154E,ERR_SYNCHRONIZED, ! (errorparameter_t)ieee154e_vars.slotOffset, ! (errorparameter_t)0); ! ! // send received ADV up the stack so RES can update statistics (synchronizing) ! notif_receive(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // official end of synchronization ! endSlot(); ! ! // everything went well, return here not to execute the error code below ! return; ! ! } while (0); ! ! // free the (invalid) received data buffer so RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // return to listening state ! changeState(S_SYNCLISTEN); ! } ! ! //xv poipoi - IE Handling ! port_INLINE bool ieee154e_processIEs(OpenQueueEntry_t* pkt, uint16_t * lenIE) ! { ! uint8_t ptr,byte0,byte1; ! uint8_t temp_8b,gr_elem_id,subid; ! uint16_t temp_16b,len,sublen; ! volatile PORT_SIGNED_INT_WIDTH timeCorrection; ! ! ptr=0; ! //candidate IE header if type ==0 header IE if type==1 payload IE ! temp_8b = *((uint8_t*)(pkt->payload)+ptr); ! ptr++; ! temp_16b = temp_8b + ((*((uint8_t*)(pkt->payload)+ptr))<< 8); ! ptr++; ! *lenIE = ptr; ! if ((temp_16b & IEEE802154E_DESC_TYPE_PAYLOAD_IE) == IEEE802154E_DESC_TYPE_PAYLOAD_IE){ ! //payload IE - last bit is 1 ! len=(temp_16b & IEEE802154E_DESC_LEN_PAYLOAD_IE_MASK)>>IEEE802154E_DESC_LEN_PAYLOAD_IE_SHIFT; ! gr_elem_id= (temp_16b & IEEE802154E_DESC_GROUPID_PAYLOAD_IE_MASK)>>IEEE802154E_DESC_GROUPID_PAYLOAD_IE_SHIFT; ! }else { ! //header IE - last bit is 0 ! len=(temp_16b & IEEE802154E_DESC_LEN_HEADER_IE_MASK)>>IEEE802154E_DESC_LEN_HEADER_IE_SHIFT; ! gr_elem_id = (temp_16b & IEEE802154E_DESC_ELEMENTID_HEADER_IE_MASK)>>IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT; ! } ! ! *lenIE += len; ! //now determine sub elements if any ! switch(gr_elem_id){ ! //this is the only groupID that we parse. See page 82. ! case IEEE802154E_MLME_IE_GROUPID: ! //IE content can be any of the sub-IEs. Parse and see which ! do{ ! //read sub IE header ! temp_8b = *((uint8_t*)(pkt->payload)+ptr); ! ptr = ptr + 1; ! temp_16b = temp_8b +(*((uint8_t*)(pkt->payload)+ptr) << 8); ! ptr = ptr + 1; ! len = len - 2; //remove header fields len ! if ((temp_16b & IEEE802154E_DESC_TYPE_LONG) == IEEE802154E_DESC_TYPE_LONG){ ! //long sub-IE - last bit is 1 ! sublen=(temp_16b & IEEE802154E_DESC_LEN_LONG_MLME_IE_MASK)>>IEEE802154E_DESC_LEN_LONG_MLME_IE_SHIFT; ! subid= (temp_16b & IEEE802154E_DESC_SUBID_LONG_MLME_IE_MASK)>>IEEE802154E_DESC_SUBID_LONG_MLME_IE_SHIFT; ! }else { ! //short IE - last bit is 0 ! sublen =(temp_16b & IEEE802154E_DESC_LEN_SHORT_MLME_IE_MASK)>>IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; ! subid = (temp_16b & IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK)>>IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT; ! } ! switch(subid){ ! case IEEE802154E_MLME_SYNC_IE_SUBID: ! //content is ASN and Join Priority ! if (idmanager_getIsDAGroot()==FALSE) { ! asnStoreFromAdv((uint8_t*)(pkt->payload)+ptr); ! ptr = ptr + 5; //add ASN len ! joinPriorityStoreFromAdv(*((uint8_t*)(pkt->payload)+ptr)); ! ptr = ptr + 1; ! } ! break; ! case IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID: ! ieee154e_processSlotframeLinkIE(pkt,&ptr); ! break; ! case IEEE802154E_MLME_TIMESLOT_IE_SUBID: ! //TODO ! break; ! default: ! return FALSE; ! break; ! } ! len = len - sublen; ! } while(len>0); ! ! break; ! //the rest are elementID ! case IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID: ! //IE content is time correction -- apply the time correction on ack received. ! if (idmanager_getIsDAGroot()==FALSE && ! neighbors_isPreferredParent(&(pkt->l2_nextORpreviousHop)) ) { ! byte0 = *((uint8_t*)(pkt->payload)+ptr); ! ptr++; ! byte1 = *((uint8_t*)(pkt->payload)+ptr); ! ptr++; ! ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_RADIOTIMER_WIDTH)byte1<<8 | (PORT_RADIOTIMER_WIDTH)byte0); ! timeCorrection /= US_PER_TICK; ! timeCorrection = -timeCorrection; ! synchronizeAck(timeCorrection); ! } ! break; ! default: ! *lenIE = 0;//no header or not recognized. ! return FALSE; ! } ! if (*lenIE>127) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_HEADER_TOO_LONG, ! (errorparameter_t)*lenIE, ! (errorparameter_t)1); ! } ! return TRUE; ! } ! ! port_INLINE void ieee154e_processSlotframeLinkIE(OpenQueueEntry_t* pkt,uint8_t * ptr){ ! uint8_t numSlotFrames,i,j,localptr; ! slotframelink_IE_t sfInfo; ! linkInfo_subIE_t linkInfo; ! localptr=*ptr; ! // number of slot frames 1B ! numSlotFrames = *((uint8_t*)(pkt->payload)+localptr); ! localptr++; ! // for each slotframe ! i=0; ! while(i < numSlotFrames){ ! //1-slotftramehandle 1B ! sfInfo.slotframehandle=*((uint8_t*)(pkt->payload)+localptr); ! localptr++; ! //2-slotframe size 2B ! sfInfo.slotframesize = *((uint8_t*)(pkt->payload)+localptr); ! localptr++; ! sfInfo.slotframesize |= (*((uint8_t*)(pkt->payload)+localptr))<<8; ! localptr++;; ! //3-number of links 1B ! sfInfo.numlinks= *((uint8_t*)(pkt->payload)+localptr); ! localptr++; ! ! for (j=0;jpayload)+localptr); ! localptr++; ! linkInfo.tsNum |= (*((uint8_t*)(pkt->payload)+localptr))<<8; ! localptr++; ! //Ch.Offset 2B ! linkInfo.choffset = *((uint8_t*)(pkt->payload)+localptr); ! localptr++; ! linkInfo.choffset |= (*((uint8_t*)(pkt->payload)+localptr))<<8; ! localptr++; ! //LinkOption bitmap 1B ! linkInfo.linkoptions = *((uint8_t*)(pkt->payload)+localptr); ! localptr++; ! //xv poipoi ! //TODO - inform schedule of that link so it can update if needed. ! } ! i++; ! } ! *ptr=localptr; ! } ! ! //======= TX ! ! port_INLINE void activity_ti1ORri1(void) { ! cellType_t cellType; ! open_addr_t neighbor; ! uint8_t i; ! synch_IE_t syn_IE; ! ! // increment ASN (do this first so debug pins are in sync) ! incrementAsnOffset(); ! ! // wiggle debug pins ! debugpins_slot_toggle(); ! if (ieee154e_vars.slotOffset==0) { ! debugpins_frame_toggle(); ! } ! ! // desynchronize if needed ! if (idmanager_getIsDAGroot()==FALSE) { ! ieee154e_vars.deSyncTimeout--; ! if (ieee154e_vars.deSyncTimeout==0) { ! // declare myself desynchronized ! changeIsSync(FALSE); ! ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_DESYNCHRONIZED, ! (errorparameter_t)ieee154e_vars.slotOffset, ! (errorparameter_t)0); ! ! // update the statistics ! ieee154e_stats.numDeSync++; ! ! // abort ! endSlot(); ! return; ! } ! } ! ! // if the previous slot took too long, we will not be in the right state ! if (ieee154e_vars.state!=S_SLEEP) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WRONG_STATE_IN_STARTSLOT, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! // abort ! endSlot(); ! return; ! } ! ! if (ieee154e_vars.slotOffset==ieee154e_vars.nextActiveSlotOffset) { ! // this is the next active slot ! ! // advance the schedule ! schedule_advanceSlot(); ! ! // find the next one ! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); ! } else { ! // this is NOT the next active slot, abort ! // stop using serial ! openserial_stop(); ! // abort the slot ! endSlot(); ! //start outputing serial ! openserial_startOutput(); ! return; ! } ! ! // check the schedule to see what type of slot this is ! cellType = schedule_getType(); ! switch (cellType) { ! case CELLTYPE_ADV: ! // stop using serial ! openserial_stop(); ! // look for an ADV packet in the queue ! ieee154e_vars.dataToSend = openqueue_macGetAdvPacket(); ! if (ieee154e_vars.dataToSend==NULL) { // I will be listening for an ADV ! // change state ! changeState(S_RXDATAOFFSET); ! // arm rt1 ! radiotimer_schedule(DURATION_rt1); ! } else { // I will be sending an ADV ! // change state ! changeState(S_TXDATAOFFSET); ! // change owner ! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; ! //copy synch IE -- should be Little endian??? ! // fill in the ASN field of the ADV ! ieee154e_getAsn(syn_IE.asn); ! syn_IE.join_priority = neighbors_getMyDAGrank()/(2*MINHOPRANKINCREASE); //poipoi -- use dagrank(rank) ! ! memcpy(ieee154e_vars.dataToSend->l2_ASNpayload,&syn_IE,sizeof(synch_IE_t)); ! ! // record that I attempt to transmit this packet ! ieee154e_vars.dataToSend->l2_numTxAttempts++; ! // arm tt1 ! radiotimer_schedule(DURATION_tt1); ! } ! break; ! case CELLTYPE_TXRX: ! case CELLTYPE_TX: ! // stop using serial ! openserial_stop(); ! // check whether we can send ! if (schedule_getOkToSend()) { ! schedule_getNeighbor(&neighbor); ! ieee154e_vars.dataToSend = openqueue_macGetDataPacket(&neighbor); ! } else { ! ieee154e_vars.dataToSend = NULL; ! } ! if (ieee154e_vars.dataToSend!=NULL) { // I have a packet to send ! // change state ! changeState(S_TXDATAOFFSET); ! // change owner ! ieee154e_vars.dataToSend->owner = COMPONENT_IEEE802154E; ! // record that I attempt to transmit this packet ! ieee154e_vars.dataToSend->l2_numTxAttempts++; ! // arm tt1 ! radiotimer_schedule(DURATION_tt1); ! } else if (cellType==CELLTYPE_TX){ ! // abort ! endSlot(); ! } ! if (cellType==CELLTYPE_TX || ! (cellType==CELLTYPE_TXRX && ieee154e_vars.dataToSend!=NULL)) { ! break; ! } ! case CELLTYPE_RX: ! // stop using serial ! openserial_stop(); ! // change state ! changeState(S_RXDATAOFFSET); ! // arm rt1 ! radiotimer_schedule(DURATION_rt1); ! break; ! case CELLTYPE_SERIALRX: ! // stop using serial ! openserial_stop(); ! // abort the slot ! endSlot(); ! //start inputting serial data ! openserial_startInput(); ! //this is to emulate a set of serial input slots without having the slotted structure. ! ! radio_setTimerPeriod(TsSlotDuration*(NUMSERIALRX)); ! ! //increase ASN by NUMSERIALRX-1 slots as at this slot is already incremented by 1 ! for (i=0;ipayload, ! ieee154e_vars.dataToSend->length); ! ! // enable the radio in Tx mode. This does not send the packet. ! radio_txEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; ! // arm tt2 ! radiotimer_schedule(DURATION_tt2); ! ! // change state ! changeState(S_TXDATAREADY); ! } ! ! port_INLINE void activity_tie1(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXDATAPREPARE_OVERFLOW, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti3(void) { ! // change state ! changeState(S_TXDATADELAY); ! ! // arm tt3 ! radiotimer_schedule(DURATION_tt3); ! ! // give the 'go' to transmit ! radio_txNow(); ! } ! ! port_INLINE void activity_tie2(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIO_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! //start of frame interrupt ! port_INLINE void activity_ti4(PORT_RADIOTIMER_WIDTH capturedTime) { ! // change state ! changeState(S_TXDATA); ! ! // cancel tt3 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // arm tt4 ! radiotimer_schedule(DURATION_tt4); ! } ! ! port_INLINE void activity_tie3(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti5(PORT_RADIOTIMER_WIDTH capturedTime) { ! bool listenForAck; ! ! // change state ! changeState(S_RXACKOFFSET); ! ! // cancel tt4 ! radiotimer_cancel(); ! ! // turn off the radio ! radio_rfOff(); ! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // decides whether to listen for an ACK ! if (packetfunctions_isBroadcastMulticast(&ieee154e_vars.dataToSend->l2_nextORpreviousHop)==TRUE) { ! listenForAck = FALSE; ! } else { ! listenForAck = TRUE; ! } ! ! if (listenForAck==TRUE) { ! // arm tt5 ! radiotimer_schedule(DURATION_tt5); ! } else { ! // indicate succesful Tx to schedule to keep statistics ! schedule_indicateTx(&ieee154e_vars.asn,TRUE); ! // indicate to upper later the packet was sent successfully ! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); ! // reset local variable ! ieee154e_vars.dataToSend = NULL; ! // abort ! endSlot(); ! } ! } ! ! port_INLINE void activity_ti6(void) { ! // change state ! changeState(S_RXACKPREPARE); ! ! // calculate the frequency to transmit on ! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); ! ! // configure the radio for that frequency ! radio_setFrequency(ieee154e_vars.freq); ! ! // enable the radio in Rx mode. The radio is not actively listening yet. ! radio_rxEnable(); ! //caputre init of radio for duty cycle calculation ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; ! // arm tt6 ! radiotimer_schedule(DURATION_tt6); ! ! // change state ! changeState(S_RXACKREADY); ! } ! ! port_INLINE void activity_tie4(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXACKPREPARE_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti7(void) { ! // change state ! changeState(S_RXACKLISTEN); ! ! // start listening ! radio_rxNow(); ! ! // arm tt7 ! radiotimer_schedule(DURATION_tt7); ! } ! ! port_INLINE void activity_tie5(void) { ! // indicate transmit failed to schedule to keep stats ! schedule_indicateTx(&ieee154e_vars.asn,FALSE); ! ! // decrement transmits left counter ! ieee154e_vars.dataToSend->l2_retriesLeft--; ! ! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { ! // indicate tx fail if no more retries left ! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); ! } else { ! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component ! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; ! } ! ! // reset local variable ! ieee154e_vars.dataToSend = NULL; ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti8(PORT_RADIOTIMER_WIDTH capturedTime) { ! // change state ! changeState(S_RXACK); ! ! // cancel tt7 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // arm tt8 ! radiotimer_schedule(DURATION_tt8); ! } ! ! port_INLINE void activity_tie6(void) { ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ti9(PORT_RADIOTIMER_WIDTH capturedTime) { ! ieee802154_header_iht ieee802514_header; ! volatile PORT_SIGNED_INT_WIDTH timeCorrection; ! uint16_t lenIE; ! ! // change state ! changeState(S_TXPROC); ! ! // cancel tt8 ! radiotimer_cancel(); ! ! // turn off the radio ! radio_rfOff(); ! //compute tics radio on. ! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // get a buffer to put the (received) ACK in ! ieee154e_vars.ackReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.ackReceived==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.ackReceived->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.ackReceived->owner = COMPONENT_IEEE802154E; ! ! /* ! The do-while loop that follows is a little parsing trick. ! Because it contains a while(0) condition, it gets executed only once. ! Below the do-while loop is some code to cleans up the ack variable. ! Anywhere in the do-while loop, a break statement can be called to jump to ! the clean up code early. If the loop ends without a break, the received ! packet was correct. If it got aborted early (through a break), the packet ! was faulty. ! */ ! do { // this "loop" is only executed once ! ! // retrieve the received ack frame from the radio's Rx buffer ! ieee154e_vars.ackReceived->payload = &(ieee154e_vars.ackReceived->packet[FIRST_FRAME_BYTE]); ! radio_getReceivedFrame( ieee154e_vars.ackReceived->payload, ! &ieee154e_vars.ackReceived->length, ! sizeof(ieee154e_vars.ackReceived->packet), ! &ieee154e_vars.ackReceived->l1_rssi, ! &ieee154e_vars.ackReceived->l1_lqi, ! &ieee154e_vars.ackReceived->l1_crc); ! ! // break if wrong length ! if (ieee154e_vars.ackReceived->lengthlength>LENGTH_IEEE154_MAX) { ! // break from the do-while loop and execute the clean-up code below ! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, ! (errorparameter_t)1, ! ieee154e_vars.ackReceived->length); ! ! break; ! } ! ! // toss CRC (2 last bytes) ! packetfunctions_tossFooter( ieee154e_vars.ackReceived, LENGTH_CRC); ! ! // break if invalid CRC ! if (ieee154e_vars.ackReceived->l1_crc==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // parse the IEEE802.15.4 header (RX ACK) ! ieee802154_retrieveHeader(ieee154e_vars.ackReceived,&ieee802514_header); ! ! // break if invalid IEEE802.15.4 header ! if (ieee802514_header.valid==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // store header details in packet buffer ! ieee154e_vars.ackReceived->l2_frameType = ieee802514_header.frameType; ! ieee154e_vars.ackReceived->l2_dsn = ieee802514_header.dsn; ! memcpy(&(ieee154e_vars.ackReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! ! // toss the IEEE802.15.4 header ! packetfunctions_tossHeader(ieee154e_vars.ackReceived,ieee802514_header.headerLength); ! ! // break if invalid ACK ! if (isValidAck(&ieee802514_header,ieee154e_vars.dataToSend)==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! //hanlde IEs --xv poipoi ! if (ieee802514_header.ieListPresent==FALSE){ ! break; //ack should contain IEs. ! } ! ! if (ieee154e_processIEs(ieee154e_vars.ackReceived,&lenIE)==FALSE){ ! //invalid IEs on ACK. ! break; ! } ! ! // toss the IEs including ACK -- xv poipoi ! packetfunctions_tossHeader(ieee154e_vars.ackReceived,lenIE); ! ! // inform schedule of successful transmission ! schedule_indicateTx(&ieee154e_vars.asn,TRUE); ! ! // inform upper layer ! notif_sendDone(ieee154e_vars.dataToSend,E_SUCCESS); ! ieee154e_vars.dataToSend = NULL; ! ! // in any case, execute the clean-up code below (processing of ACK done) ! } while (0); ! ! // free the received ack so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); ! ! // clear local variable ! ieee154e_vars.ackReceived = NULL; ! ! // official end of Tx slot ! endSlot(); ! } ! ! //======= RX ! ! port_INLINE void activity_ri2(void) { ! // change state ! changeState(S_RXDATAPREPARE); ! ! // calculate the frequency to transmit on ! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); ! ! // configure the radio for that frequency ! radio_setFrequency(ieee154e_vars.freq); ! ! // enable the radio in Rx mode. The radio does not actively listen yet. ! radio_rxEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; ! ! // arm rt2 ! radiotimer_schedule(DURATION_rt2); ! ! // change state ! changeState(S_RXDATAREADY); ! } ! ! port_INLINE void activity_rie1(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXRXDATAPREPARE_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri3(void) { ! // change state ! changeState(S_RXDATALISTEN); ! ! // give the 'go' to receive ! radio_rxNow(); ! ! // arm rt3 ! radiotimer_schedule(DURATION_rt3); ! } ! ! port_INLINE void activity_rie2(void) { ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri4(PORT_RADIOTIMER_WIDTH capturedTime) { ! ! // change state ! changeState(S_RXDATA); ! ! // cancel rt3 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // record the captured time to sync ! ieee154e_vars.syncCapturedTime = capturedTime; ! ! radiotimer_schedule(DURATION_rt4); ! } ! ! port_INLINE void activity_rie3(void) { ! ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDDATADURATION_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri5(PORT_RADIOTIMER_WIDTH capturedTime) { ! ieee802154_header_iht ieee802514_header; ! uint16_t lenIE=0; ! ! // change state ! changeState(S_TXACKOFFSET); ! ! // cancel rt4 ! radiotimer_cancel(); ! ! // turn off the radio ! //radio_rfOff(); ! ieee154e_vars.radioOnTics+=radio_getTimerValue()-ieee154e_vars.radioOnInit; ! // get a buffer to put the (received) data in ! ieee154e_vars.dataReceived = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.dataReceived==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.dataReceived->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.dataReceived->owner = COMPONENT_IEEE802154E; ! ! /* ! The do-while loop that follows is a little parsing trick. ! Because it contains a while(0) condition, it gets executed only once. ! The behavior is: ! - if a break occurs inside the do{} body, the error code below the loop ! gets executed. This indicates something is wrong with the packet being ! parsed. ! - if a return occurs inside the do{} body, the error code below the loop ! does not get executed. This indicates the received packet is correct. ! */ ! do { // this "loop" is only executed once ! ! // retrieve the received data frame from the radio's Rx buffer ! ieee154e_vars.dataReceived->payload = &(ieee154e_vars.dataReceived->packet[FIRST_FRAME_BYTE]); ! radio_getReceivedFrame( ieee154e_vars.dataReceived->payload, ! &ieee154e_vars.dataReceived->length, ! sizeof(ieee154e_vars.dataReceived->packet), ! &ieee154e_vars.dataReceived->l1_rssi, ! &ieee154e_vars.dataReceived->l1_lqi, ! &ieee154e_vars.dataReceived->l1_crc); ! ! // break if wrong length ! if (ieee154e_vars.dataReceived->lengthlength>LENGTH_IEEE154_MAX ) { ! // jump to the error code below this do-while loop ! openserial_printError(COMPONENT_IEEE802154E,ERR_INVALIDPACKETFROMRADIO, ! (errorparameter_t)2, ! ieee154e_vars.dataReceived->length); ! break; ! } ! ! // toss CRC (2 last bytes) ! packetfunctions_tossFooter( ieee154e_vars.dataReceived, LENGTH_CRC); ! ! // if CRC doesn't check, stop ! if (ieee154e_vars.dataReceived->l1_crc==FALSE) { ! // jump to the error code below this do-while loop ! break; ! } ! ! // parse the IEEE802.15.4 header (RX DATA) ! ieee802154_retrieveHeader(ieee154e_vars.dataReceived,&ieee802514_header); ! ! // break if invalid IEEE802.15.4 header ! if (ieee802514_header.valid==FALSE) { ! // break from the do-while loop and execute the clean-up code below ! break; ! } ! ! // store header details in packet buffer ! ieee154e_vars.dataReceived->l2_frameType = ieee802514_header.frameType; ! ieee154e_vars.dataReceived->l2_dsn = ieee802514_header.dsn; ! memcpy(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop),&(ieee802514_header.src),sizeof(open_addr_t)); ! ! // toss the IEEE802.15.4 header ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,ieee802514_header.headerLength); ! ! // handle IEs xv poipoi ! //reset join priority ! ! if ((ieee802514_header.valid==TRUE && ! ieee802514_header.ieListPresent==TRUE && ! packetfunctions_sameAddress(&ieee802514_header.panid,idmanager_getMyID(ADDR_PANID)) && ! ieee154e_processIEs(ieee154e_vars.dataReceived,&lenIE))==FALSE) { ! //log that the packet is not carrying IEs ! } ! ! // toss the IEs including Synch ! packetfunctions_tossHeader(ieee154e_vars.dataReceived,lenIE); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // if I just received an invalid frame, stop ! if (isValidRxFrame(&ieee802514_header)==FALSE) { ! // jump to the error code below this do-while loop ! break; ! } ! ! // check if ack requested ! if (ieee802514_header.ackRequested==1) { ! // arm rt5 ! radiotimer_schedule(DURATION_rt5); ! } else { ! // synchronize to the received packet iif I'm not a DAGroot and this is my preferred parent ! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { ! synchronizePacket(ieee154e_vars.syncCapturedTime); ! } ! // indicate reception to upper layer (no ACK asked) ! notif_receive(ieee154e_vars.dataReceived); ! // reset local variable ! ieee154e_vars.dataReceived = NULL; ! // abort ! endSlot(); ! } ! ! // everything went well, return here not to execute the error code below ! return; ! ! } while(0); ! ! // free the (invalid) received data so RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri6(void) { ! PORT_SIGNED_INT_WIDTH timeCorrection; ! header_IE_descriptor_t header_desc; ! ! // change state ! changeState(S_TXACKPREPARE); ! ! // get a buffer to put the ack to send in ! ieee154e_vars.ackToSend = openqueue_getFreePacketBuffer(COMPONENT_IEEE802154E); ! if (ieee154e_vars.ackToSend==NULL) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // indicate we received a packet anyway (we don't want to loose any) ! notif_receive(ieee154e_vars.dataReceived); ! // free local variable ! ieee154e_vars.dataReceived = NULL; ! // abort ! endSlot(); ! return; ! } ! ! // declare ownership over that packet ! ieee154e_vars.ackToSend->creator = COMPONENT_IEEE802154E; ! ieee154e_vars.ackToSend->owner = COMPONENT_IEEE802154E; ! ! // calculate the time timeCorrection (this is the time when the packet arrive w.r.t the time it should be. ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.syncCapturedTime-(PORT_SIGNED_INT_WIDTH)TsTxOffset); ! ! // add the payload to the ACK (i.e. the timeCorrection) ! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(ack_timecorrection_IE_t)); ! timeCorrection = -timeCorrection; ! timeCorrection *= US_PER_TICK; ! ieee154e_vars.ackToSend->payload[0] = (uint8_t)((((PORT_RADIOTIMER_WIDTH)timeCorrection) ) & 0xff); ! ieee154e_vars.ackToSend->payload[1] = (uint8_t)((((PORT_RADIOTIMER_WIDTH)timeCorrection)>>8) & 0xff); ! ! // add header IE header -- xv poipoi -- pkt is filled in reverse order.. ! packetfunctions_reserveHeaderSize(ieee154e_vars.ackToSend,sizeof(header_IE_descriptor_t)); ! //create the header for ack IE ! header_desc.length_elementid_type=(sizeof(ack_timecorrection_IE_t)<< IEEE802154E_DESC_LEN_HEADER_IE_SHIFT)| ! (IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID << IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT)| ! IEEE802154E_DESC_TYPE_SHORT; ! memcpy(ieee154e_vars.ackToSend->payload,&header_desc,sizeof(header_IE_descriptor_t)); ! ! // prepend the IEEE802.15.4 header to the ACK ! ieee154e_vars.ackToSend->l2_frameType = IEEE154_TYPE_ACK; ! ieee154e_vars.ackToSend->l2_dsn = ieee154e_vars.dataReceived->l2_dsn; ! ieee802154_prependHeader(ieee154e_vars.ackToSend, ! ieee154e_vars.ackToSend->l2_frameType, ! IEEE154_IELIST_YES,//ie in ack ! IEEE154_FRAMEVERSION,//enhanced ack ! IEEE154_SEC_NO_SECURITY, ! ieee154e_vars.dataReceived->l2_dsn, ! &(ieee154e_vars.dataReceived->l2_nextORpreviousHop) ! ); ! ! // space for 2-byte CRC ! packetfunctions_reserveFooterSize(ieee154e_vars.ackToSend,2); ! ! // calculate the frequency to transmit on ! ieee154e_vars.freq = calculateFrequency(schedule_getChannelOffset()); ! ! // configure the radio for that frequency ! radio_setFrequency(ieee154e_vars.freq); ! ! // load the packet in the radio's Tx buffer ! radio_loadPacket(ieee154e_vars.ackToSend->payload, ! ieee154e_vars.ackToSend->length); ! ! // enable the radio in Tx mode. This does not send that packet. ! radio_txEnable(); ! ieee154e_vars.radioOnInit=radio_getTimerValue(); ! ieee154e_vars.radioOnThisSlot=TRUE; ! // arm rt6 ! radiotimer_schedule(DURATION_rt6); ! ! // change state ! changeState(S_TXACKREADY); ! } ! ! port_INLINE void activity_rie4(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_MAXTXACKPREPARE_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri7(void) { ! // change state ! changeState(S_TXACKDELAY); ! ! // arm rt7 ! radiotimer_schedule(DURATION_rt7); ! ! // give the 'go' to transmit ! radio_txNow(); ! } ! ! port_INLINE void activity_rie5(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDRADIOTX_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri8(PORT_RADIOTIMER_WIDTH capturedTime) { ! // change state ! changeState(S_TXACK); ! ! // cancel rt7 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // arm rt8 ! radiotimer_schedule(DURATION_rt8); ! } ! ! port_INLINE void activity_rie6(void) { ! // log the error ! openserial_printError(COMPONENT_IEEE802154E,ERR_WDACKDURATION_OVERFLOWS, ! (errorparameter_t)ieee154e_vars.state, ! (errorparameter_t)ieee154e_vars.slotOffset); ! ! // abort ! endSlot(); ! } ! ! port_INLINE void activity_ri9(PORT_RADIOTIMER_WIDTH capturedTime) { ! // change state ! changeState(S_RXPROC); ! ! // cancel rt8 ! radiotimer_cancel(); ! ! // record the captured time ! ieee154e_vars.lastCapturedTime = capturedTime; ! ! // free the ack we just sent so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); ! ! // clear local variable ! ieee154e_vars.ackToSend = NULL; ! ! // synchronize to the received packet ! if (idmanager_getIsDAGroot()==FALSE && neighbors_isPreferredParent(&(ieee154e_vars.dataReceived->l2_nextORpreviousHop))) { ! synchronizePacket(ieee154e_vars.syncCapturedTime); ! } ! ! // inform upper layer of reception (after ACK sent) ! notif_receive(ieee154e_vars.dataReceived); ! ! // clear local variable ! ieee154e_vars.dataReceived = NULL; ! ! // official end of Rx slot ! endSlot(); ! } ! ! //======= frame validity check ! ! /** ! \brief Decides whether the packet I just received is valid received frame. ! ! A valid Rx frame satisfies the following constraints: ! - its IEEE802.15.4 header is well formatted ! - it's a DATA of BEACON frame (i.e. not ACK and not COMMAND) ! - it's sent on the same PANid as mine ! - it's for me (unicast or broadcast) ! ! \param[in] ieee802514_header IEEE802.15.4 header of the packet I just received ! ! \returns TRUE if packet is valid received frame, FALSE otherwise ! */ ! port_INLINE bool isValidRxFrame(ieee802154_header_iht* ieee802514_header) { ! return ieee802514_header->valid==TRUE && \ ! ( ! ieee802514_header->frameType==IEEE154_TYPE_DATA || ! ieee802514_header->frameType==IEEE154_TYPE_BEACON ! ) && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! ( ! idmanager_isMyAddress(&ieee802514_header->dest) || ! packetfunctions_isBroadcastMulticast(&ieee802514_header->dest) ! ); ! } ! ! /** ! \brief Decides whether the packet I just received is a valid ACK. ! ! A packet is a valid ACK if it satisfies the following conditions: ! - the IEEE802.15.4 header is valid ! - the frame type is 'ACK' ! - the sequence number in the ACK matches the sequence number of the packet sent ! - the ACK contains my PANid ! - the packet is unicast to me ! - the packet comes from the neighbor I sent the data to ! ! \param[in] ieee802514_header IEEE802.15.4 header of the packet I just received ! \param[in] packetSent points to the packet I just sent ! ! \returns TRUE if packet is a valid ACK, FALSE otherwise. ! */ ! port_INLINE bool isValidAck(ieee802154_header_iht* ieee802514_header, OpenQueueEntry_t* packetSent) { ! /* ! return ieee802514_header->valid==TRUE && \ ! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ ! ieee802514_header->dsn==packetSent->l2_dsn && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! idmanager_isMyAddress(&ieee802514_header->dest) && \ ! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); ! */ ! // poipoi don't check for seq num ! return ieee802514_header->valid==TRUE && \ ! ieee802514_header->frameType==IEEE154_TYPE_ACK && \ ! packetfunctions_sameAddress(&ieee802514_header->panid,idmanager_getMyID(ADDR_PANID)) && \ ! idmanager_isMyAddress(&ieee802514_header->dest) && \ ! packetfunctions_sameAddress(&ieee802514_header->src,&packetSent->l2_nextORpreviousHop); ! } ! ! //======= ASN handling ! ! port_INLINE void incrementAsnOffset(void) { ! // increment the asn ! ieee154e_vars.asn.bytes0and1++; ! if (ieee154e_vars.asn.bytes0and1==0) { ! ieee154e_vars.asn.bytes2and3++; ! if (ieee154e_vars.asn.bytes2and3==0) { ! ieee154e_vars.asn.byte4++; ! } ! } ! // increment the offsets ! ieee154e_vars.slotOffset = (ieee154e_vars.slotOffset+1)%schedule_getFrameLength(); ! ieee154e_vars.asnOffset = (ieee154e_vars.asnOffset+1)%16; ! } ! ! //from upper layer that want to send the ASN to compute timing or latency ! port_INLINE void ieee154e_getAsn(uint8_t* array) { ! array[0] = (ieee154e_vars.asn.bytes0and1 & 0xff); ! array[1] = (ieee154e_vars.asn.bytes0and1/256 & 0xff); ! array[2] = (ieee154e_vars.asn.bytes2and3 & 0xff); ! array[3] = (ieee154e_vars.asn.bytes2and3/256 & 0xff); ! array[4] = ieee154e_vars.asn.byte4; ! } ! ! port_INLINE void joinPriorityStoreFromAdv(uint8_t jp){ ! ieee154e_vars.dataReceived->l2_joinPriority = jp; ! ieee154e_vars.dataReceived->l2_joinPriorityPresent = TRUE; ! } ! ! ! port_INLINE void asnStoreFromAdv(uint8_t* asn) { ! ! // store the ASN ! ieee154e_vars.asn.bytes0and1 = asn[0]+ ! 256*asn[1]; ! ieee154e_vars.asn.bytes2and3 = asn[2]+ ! 256*asn[3]; ! ieee154e_vars.asn.byte4 = asn[4]; ! ! // determine the current slotOffset ! /* ! Note: this is a bit of a hack. Normally, slotOffset=ASN%slotlength. But since ! the ADV is exchanged in slot 0, we know that we're currently at slotOffset==0 ! */ ! ieee154e_vars.slotOffset = 0; ! schedule_syncSlotOffset(ieee154e_vars.slotOffset); ! ieee154e_vars.nextActiveSlotOffset = schedule_getNextActiveSlotOffset(); ! ! /* ! infer the asnOffset based on the fact that ! ieee154e_vars.freq = 11 + (asnOffset + channelOffset)%16 ! */ ! ieee154e_vars.asnOffset = ieee154e_vars.freq - 11 - schedule_getChannelOffset(); ! } ! ! //======= synchronization ! ! void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived) { ! PORT_SIGNED_INT_WIDTH timeCorrection; ! PORT_RADIOTIMER_WIDTH newPeriod; ! PORT_RADIOTIMER_WIDTH currentValue; ! PORT_RADIOTIMER_WIDTH currentPeriod; ! // record the current timer value and period ! currentValue = radio_getTimerValue(); ! currentPeriod = radio_getTimerPeriod(); ! // calculate new period ! timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)timeReceived-(PORT_SIGNED_INT_WIDTH)TsTxOffset); ! ! newPeriod = TsSlotDuration; ! // detect whether I'm too close to the edge of the slot, in that case, ! // skip a slot and increase the temporary slot length to be 2 slots long ! if (currentValue LIMITLARGETIMECORRECTION ! ) ! ) { ! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, ! (errorparameter_t)timeCorrection, ! (errorparameter_t)0); ! } ! // update the stats ! ieee154e_stats.numSyncPkt++; ! updateStats(timeCorrection); ! } ! ! void synchronizeAck(PORT_SIGNED_INT_WIDTH timeCorrection) { ! PORT_RADIOTIMER_WIDTH newPeriod; ! PORT_RADIOTIMER_WIDTH currentPeriod; ! // calculate new period ! currentPeriod = radio_getTimerPeriod(); ! newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)currentPeriod-timeCorrection); ! ! // resynchronize by applying the new period ! radio_setTimerPeriod(newPeriod); ! // reset the de-synchronization timeout ! ieee154e_vars.deSyncTimeout = DESYNCTIMEOUT; ! // log a large timeCorrection ! if ( ! ieee154e_vars.isSync==TRUE && ! ( ! timeCorrection<-LIMITLARGETIMECORRECTION || ! timeCorrection> LIMITLARGETIMECORRECTION ! ) ! ) { ! openserial_printError(COMPONENT_IEEE802154E,ERR_LARGE_TIMECORRECTION, ! (errorparameter_t)timeCorrection, ! (errorparameter_t)1); ! } ! // update the stats ! ieee154e_stats.numSyncAck++; ! updateStats(timeCorrection); ! } ! ! void changeIsSync(bool newIsSync) { ! ieee154e_vars.isSync = newIsSync; ! ! if (ieee154e_vars.isSync==TRUE) { ! leds_sync_on(); ! resetStats(); ! } else { ! leds_sync_off(); ! schedule_resetBackoff(); ! } ! } ! ! //======= notifying upper layer ! ! void notif_sendDone(OpenQueueEntry_t* packetSent, owerror_t error) { ! // record the outcome of the trasmission attempt ! packetSent->l2_sendDoneError = error; ! // record the current ASN ! memcpy(&packetSent->l2_asn,&ieee154e_vars.asn,sizeof(asn_t)); ! // associate this packet with the virtual component ! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it ! packetSent->owner = COMPONENT_IEEE802154E_TO_RES; ! // post RES's sendDone task ! scheduler_push_task(task_resNotifSendDone,TASKPRIO_RESNOTIF_TXDONE); ! /*thread_create(openwsn_ieee802154e_send_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_IEEE802154E, CREATE_STACKTEST, ! task_resNotifSendDone, "task resNotifSendDone");*/ ! // wake up the scheduler ! SCHEDULER_WAKEUP(); ! } ! ! void notif_receive(OpenQueueEntry_t* packetReceived) { ! // record the current ASN ! memcpy(&packetReceived->l2_asn, &ieee154e_vars.asn, sizeof(asn_t)); ! // indicate reception to the schedule, to keep statistics ! schedule_indicateRx(&packetReceived->l2_asn); ! // associate this packet with the virtual component ! // COMPONENT_IEEE802154E_TO_RES so RES can knows it's for it ! packetReceived->owner = COMPONENT_IEEE802154E_TO_RES; ! ! // post RES's Receive task ! scheduler_push_task(task_resNotifReceive,TASKPRIO_RESNOTIF_RX); ! /*thread_create(openwsn_ieee802154e_rec_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_IEEE802154E, CREATE_STACKTEST, ! task_resNotifSendDone, "task resNotifSendDone");*/ ! // wake up the scheduler ! SCHEDULER_WAKEUP(); ! } ! ! //======= stats ! ! port_INLINE void resetStats(void) { ! ieee154e_stats.numSyncPkt = 0; ! ieee154e_stats.numSyncAck = 0; ! ieee154e_stats.minCorrection = 127; ! ieee154e_stats.maxCorrection = -127; ! ieee154e_stats.dutyCycle = 0; ! // do not reset the number of de-synchronizations ! } ! ! void updateStats(PORT_SIGNED_INT_WIDTH timeCorrection) { ! // update minCorrection ! if (timeCorrectionieee154e_stats.maxCorrection) { ! ieee154e_stats.maxCorrection = timeCorrection; ! } ! } ! ! //======= misc ! ! /** ! \brief Calculates the frequency channel to transmit on, based on the ! absolute slot number and the channel offset of the requested slot. ! ! During normal operation, the frequency used is a function of the ! channelOffset indicating in the schedule, and of the ASN of the ! slot. This ensures channel hopping, consecutive packets sent in the same slot ! in the schedule are done on a difference frequency channel. ! ! During development, you can force single channel operation by having this ! function return a constant channel number (between 11 and 26). This allows you ! to use a single-channel sniffer; but you can not schedule two links on two ! different channel offsets in the same slot. ! ! \param[in] channelOffset channel offset for the current slot ! ! \returns The calculated frequency channel, an integer between 11 and 26. ! */ ! port_INLINE uint8_t calculateFrequency(uint8_t channelOffset) { ! // comment the following line out to disable channel hopping ! return SYNCHRONIZING_CHANNEL; // single channel ! //return 11+(ieee154e_vars.asnOffset+channelOffset)%16; //channel hopping ! } ! ! /** ! \brief Changes the state of the IEEE802.15.4e FSM. ! ! Besides simply updating the state global variable, ! this function toggles the FSM debug pin. ! ! \param[in] newstate The state the IEEE802.15.4e FSM is now in. ! */ ! void changeState(ieee154e_state_t newstate) { ! // update the state ! ieee154e_vars.state = newstate; ! // wiggle the FSM debug pin ! switch (ieee154e_vars.state) { ! case S_SYNCLISTEN: ! case S_TXDATAOFFSET: ! debugpins_fsm_set(); ! break; ! case S_SLEEP: ! case S_RXDATAOFFSET: ! debugpins_fsm_clr(); ! break; ! case S_SYNCRX: ! case S_SYNCPROC: ! case S_TXDATAPREPARE: ! case S_TXDATAREADY: ! case S_TXDATADELAY: ! case S_TXDATA: ! case S_RXACKOFFSET: ! case S_RXACKPREPARE: ! case S_RXACKREADY: ! case S_RXACKLISTEN: ! case S_RXACK: ! case S_TXPROC: ! case S_RXDATAPREPARE: ! case S_RXDATAREADY: ! case S_RXDATALISTEN: ! case S_RXDATA: ! case S_TXACKOFFSET: ! case S_TXACKPREPARE: ! case S_TXACKREADY: ! case S_TXACKDELAY: ! case S_TXACK: ! case S_RXPROC: ! debugpins_fsm_toggle(); ! break; ! } ! } ! ! /** ! \brief Housekeeping tasks to do at the end of each slot. ! ! This functions is called once in each slot, when there is nothing more ! to do. This might be when an error occured, or when everything went well. ! This function resets the state of the FSM so it is ready for the next slot. ! ! Note that by the time this function is called, any received packet should already ! have been sent to the upper layer. Similarly, in a Tx slot, the sendDone ! function should already have been done. If this is not the case, this function ! will do that for you, but assume that something went wrong. ! */ ! void endSlot(void) { ! ! float aux; //duty cycle helper. ! // turn off the radio ! radio_rfOff(); ! // compute the duty cycle if radio has been turned on ! if (ieee154e_vars.radioOnThisSlot==TRUE){ ! ieee154e_vars.radioOnTics+=(radio_getTimerValue()-ieee154e_vars.radioOnInit); ! } ! // clear any pending timer ! radiotimer_cancel(); ! ! // reset capturedTimes ! ieee154e_vars.lastCapturedTime = 0; ! ieee154e_vars.syncCapturedTime = 0; ! ! //instant duty cycle.. average is computed at debugprint_macstats. ! aux=(float)ieee154e_vars.radioOnTics/(float)radio_getTimerPeriod(); ! ieee154e_stats.dutyCycle+=aux;//accumulate and avg will be done on serial print ! //clear vars for duty cycle on this slot ! ieee154e_vars.radioOnTics=0; ! ieee154e_vars.radioOnThisSlot=FALSE; ! ! // clean up dataToSend ! if (ieee154e_vars.dataToSend!=NULL) { ! // if everything went well, dataToSend was set to NULL in ti9 ! // getting here means transmit failed ! ! // indicate Tx fail to schedule to update stats ! schedule_indicateTx(&ieee154e_vars.asn,FALSE); ! ! //decrement transmits left counter ! ieee154e_vars.dataToSend->l2_retriesLeft--; ! ! if (ieee154e_vars.dataToSend->l2_retriesLeft==0) { ! // indicate tx fail if no more retries left ! notif_sendDone(ieee154e_vars.dataToSend,E_FAIL); ! } else { ! // return packet to the virtual COMPONENT_RES_TO_IEEE802154E component ! ieee154e_vars.dataToSend->owner = COMPONENT_RES_TO_IEEE802154E; ! } ! ! // reset local variable ! ieee154e_vars.dataToSend = NULL; ! } ! ! // clean up dataReceived ! if (ieee154e_vars.dataReceived!=NULL) { ! // assume something went wrong. If everything went well, dataReceived ! // would have been set to NULL in ri9. ! // indicate "received packet" to upper layer since we don't want to loose packets ! notif_receive(ieee154e_vars.dataReceived); ! // reset local variable ! ieee154e_vars.dataReceived = NULL; ! } ! ! // clean up ackToSend ! if (ieee154e_vars.ackToSend!=NULL) { ! // free ackToSend so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackToSend); ! // reset local variable ! ieee154e_vars.ackToSend = NULL; ! } ! ! // clean up ackReceived ! if (ieee154e_vars.ackReceived!=NULL) { ! // free ackReceived so corresponding RAM memory can be recycled ! openqueue_freePacketBuffer(ieee154e_vars.ackReceived); ! // reset local variable ! ieee154e_vars.ackReceived = NULL; ! } ! ! ! // change state ! changeState(S_SLEEP); ! } ! ! bool ieee154e_isSynch(void){ ! return ieee154e_vars.isSync; ! } diff -crB openwsn/02a-MAClow/IEEE802154E.h ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.h *** openwsn/02a-MAClow/IEEE802154E.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/IEEE802154E.h Wed Jan 15 13:48:26 2014 *************** *** 1,154 **** ! #ifndef __IEEE802154E_H ! #define __IEEE802154E_H ! ! /** ! \addtogroup MAClow ! \{ ! \addtogroup IEEE802154E ! \{ ! */ ! ! #include "openwsn.h" ! #include "board_info.h" ! ! //=========================== debug define ==================================== ! ! //=========================== define ========================================== ! ! #define SYNCHRONIZING_CHANNEL 20 // channel the mote listens on to synchronize ! #define TXRETRIES 3 // number of MAC retries before declaring failed ! #define TX_POWER 31 // 1=-25dBm, 31=0dBm (max value) ! #define RESYNCHRONIZATIONGUARD 5 // in 32kHz ticks. min distance to the end of the slot to succesfully synchronize ! #define US_PER_TICK 30 // number of us per 32kHz clock tick ! #define KATIMEOUT 66 // in slots: @15ms per slot -> ~1 seconds ! #define DESYNCTIMEOUT 333 // in slots: @15ms per slot -> ~5 seconds ! #define LIMITLARGETIMECORRECTION 5 // threshold number of ticks to declare a timeCorrection "large" ! #define LENGTH_IEEE154_MAX 128 // max length of a valid radio packet ! ! /** ! When a packet is received, it is written inside the OpenQueueEntry_t->packet ! buffer, starting at the byte defined below. When a packet is relayed, it ! traverses the stack in which the MAC and IPHC headers are parsed and stripped ! off, then put on again. During that process, the IPv6 hop limit field is ! decremented. Depending on the new value of the hop limit, the IPHC header ! compression algorithm might not be able to compress it, and hence has to carry ! it inline, adding a byte to the header. To avoid having to move bytes around ! inside OpenQueueEntry_t->packet buffer, we start writing the received packet a ! bit after the start of the packet. ! */ ! #define FIRST_FRAME_BYTE 1 ! ! // the different states of the IEEE802.15.4e state machine ! typedef enum { ! S_SLEEP = 0x00, // ready for next slot ! // synchronizing ! S_SYNCLISTEN = 0x01, // listened for packet to synchronize to network ! S_SYNCRX = 0x02, // receiving packet to synchronize to network ! S_SYNCPROC = 0x03, // processing packet just received ! // TX ! S_TXDATAOFFSET = 0x04, // waiting to prepare for Tx data ! S_TXDATAPREPARE = 0x05, // preparing for Tx data ! S_TXDATAREADY = 0x06, // ready to Tx data, waiting for 'go' ! S_TXDATADELAY = 0x07, // 'go' signal given, waiting for SFD Tx data ! S_TXDATA = 0x08, // Tx data SFD received, sending bytes ! S_RXACKOFFSET = 0x09, // Tx data done, waiting to prepare for Rx ACK ! S_RXACKPREPARE = 0x0a, // preparing for Rx ACK ! S_RXACKREADY = 0x0b, // ready to Rx ACK, waiting for 'go' ! S_RXACKLISTEN = 0x0c, // idle listening for ACK ! S_RXACK = 0x0d, // Rx ACK SFD received, receiving bytes ! S_TXPROC = 0x0e, // processing sent data ! // RX ! S_RXDATAOFFSET = 0x0f, // waiting to prepare for Rx data ! S_RXDATAPREPARE = 0x10, // preparing for Rx data ! S_RXDATAREADY = 0x11, // ready to Rx data, waiting for 'go' ! S_RXDATALISTEN = 0x12, // idle listening for data ! S_RXDATA = 0x13, // data SFD received, receiving more bytes ! S_TXACKOFFSET = 0x14, // waiting to prepare for Tx ACK ! S_TXACKPREPARE = 0x15, // preparing for Tx ACK ! S_TXACKREADY = 0x16, // Tx ACK ready, waiting for 'go' ! S_TXACKDELAY = 0x17, // 'go' signal given, waiting for SFD Tx ACK ! S_TXACK = 0x18, // Tx ACK SFD received, sending bytes ! S_RXPROC = 0x19, // processing received data ! } ieee154e_state_t; ! ! // Atomic durations ! // expressed in 32kHz ticks: ! // - ticks = duration_in_seconds * 32768 ! // - duration_in_seconds = ticks / 32768 ! enum ieee154e_atomicdurations_enum { ! // time-slot related ! TsTxOffset = 131, // 4000us ! TsLongGT = 43, // 1300us ! TsTxAckDelay = 151, // 4606us ! TsShortGT = 16, // 500us ! TsSlotDuration = PORT_TsSlotDuration, // 15000us ! // execution speed related ! maxTxDataPrepare = PORT_maxTxDataPrepare, ! maxRxAckPrepare = PORT_maxRxAckPrepare, ! maxRxDataPrepare = PORT_maxRxDataPrepare, ! maxTxAckPrepare = PORT_maxTxAckPrepare, ! // radio speed related ! delayTx = PORT_delayTx, // between GO signal and SFD ! delayRx = PORT_delayRx, // between GO signal and start listening ! // radio watchdog ! wdRadioTx = 33, // 1000us (needs to be >delayTx) ! wdDataDuration = 164, // 5000us (measured 4280us with max payload) ! wdAckDuration = 98, // 3000us (measured 1000us) ! }; ! ! ! ! // FSM timer durations (combinations of atomic durations) ! // TX ! #define DURATION_tt1 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx-maxTxDataPrepare ! #define DURATION_tt2 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx ! #define DURATION_tt3 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx+wdRadioTx ! #define DURATION_tt4 ieee154e_vars.lastCapturedTime+wdDataDuration ! #define DURATION_tt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx-maxRxAckPrepare ! #define DURATION_tt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx ! #define DURATION_tt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay+TsShortGT ! #define DURATION_tt8 ieee154e_vars.lastCapturedTime+wdAckDuration ! // RX ! #define DURATION_rt1 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx-maxRxDataPrepare ! #define DURATION_rt2 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx ! #define DURATION_rt3 ieee154e_vars.lastCapturedTime+TsTxOffset+TsLongGT ! #define DURATION_rt4 ieee154e_vars.lastCapturedTime+wdDataDuration ! #define DURATION_rt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx-maxTxAckPrepare ! #define DURATION_rt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx ! #define DURATION_rt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx+wdRadioTx ! #define DURATION_rt8 ieee154e_vars.lastCapturedTime+wdAckDuration ! ! //=========================== typedef ========================================= ! ! //IEEE802.15.4E acknowledgement (ACK) ! typedef struct { ! PORT_SIGNED_INT_WIDTH timeCorrection; ! } IEEE802154E_ACK_ht; ! ! #define ADV_PAYLOAD_LENGTH 5 ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void ieee154e_init(); ! // public ! PORT_TIMER_WIDTH ieee154e_asnDiff(asn_t* someASN); ! bool ieee154e_isSynch(); ! void asnWriteToPkt(OpenQueueEntry_t* frame); ! void asnWriteToSerial(uint8_t* array); ! // events ! void ieee154e_startOfFrame(PORT_TIMER_WIDTH capturedTime); ! void ieee154e_endOfFrame(PORT_TIMER_WIDTH capturedTime); ! // misc ! bool debugPrint_asn(); ! bool debugPrint_isSync(); ! bool debugPrint_macStats(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,308 ---- ! #ifndef __IEEE802154E_H ! #define __IEEE802154E_H ! ! /** ! \addtogroup MAClow ! \{ ! \addtogroup IEEE802154E ! \{ ! */ ! ! #include "openwsn.h" ! #include "board_info.h" ! #include "schedule.h" ! ! //=========================== debug define ==================================== ! ! //=========================== define ========================================== ! ! #define SYNCHRONIZING_CHANNEL 20 // channel the mote listens on to synchronize ! #define TXRETRIES 3 // number of MAC retries before declaring failed ! #define TX_POWER 31 // 1=-25dBm, 31=0dBm (max value) ! #define RESYNCHRONIZATIONGUARD 5 // in 32kHz ticks. min distance to the end of the slot to succesfully synchronize ! #define US_PER_TICK 30 // number of us per 32kHz clock tick ! #define KATIMEOUT 66 // in slots: @15ms per slot -> ~1 seconds ! #define DESYNCTIMEOUT 333 // in slots: @15ms per slot -> ~5 seconds ! #define LIMITLARGETIMECORRECTION 5 // threshold number of ticks to declare a timeCorrection "large" ! #define LENGTH_IEEE154_MAX 128 // max length of a valid radio packet ! ! //15.4e information elements related ! #define IEEE802154E_PAYLOAD_DESC_LEN_SHIFT 0x04 ! #define IEEE802154E_PAYLOAD_DESC_GROUP_ID_MLME (0x01 << 1) //includes shift 1 ! #define IEEE802154E_DESC_TYPE_LONG 0x01 ! #define IEEE802154E_DESC_TYPE_SHORT 0x00 ! ! #define IEEE802154E_DESC_TYPE_HEADER_IE 0x00 ! #define IEEE802154E_DESC_TYPE_PAYLOAD_IE 0x01 ! //len field on PAYLOAD/HEADER DESC ! #define IEEE802154E_DESC_LEN_HEADER_IE_MASK 0xFE00 ! #define IEEE802154E_DESC_LEN_PAYLOAD_IE_MASK 0xFFE0 ! ! #define IEEE802154E_DESC_LEN_HEADER_IE_SHIFT 9 ! #define IEEE802154E_DESC_LEN_PAYLOAD_IE_SHIFT 5 ! ! //groupID/elementID field on PAYLOAD/HEADER DESC ! #define IEEE802154E_DESC_ELEMENTID_HEADER_IE_MASK 0x01FE ! #define IEEE802154E_DESC_GROUPID_PAYLOAD_IE_MASK 0x001E ! ! #define IEEE802154E_DESC_ELEMENTID_HEADER_IE_SHIFT 1 ! #define IEEE802154E_DESC_GROUPID_PAYLOAD_IE_SHIFT 1 ! ! //MLME Sub IE LONG page 83 ! #define IEEE802154E_DESC_LEN_LONG_MLME_IE_MASK 0xFFE0 ! #define IEEE802154E_DESC_SUBID_LONG_MLME_IE_MASK 0x001E ! ! #define IEEE802154E_DESC_LEN_LONG_MLME_IE_SHIFT 5 ! #define IEEE802154E_DESC_SUBID_LONG_MLME_IE_SHIFT 1 ! ! //MLME Sub IE SHORT page 82 ! #define IEEE802154E_DESC_LEN_SHORT_MLME_IE_MASK 0xFF00 ! #define IEEE802154E_DESC_SUBID_SHORT_MLME_IE_MASK 0x00FE ! ! #define IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT 8 ! #define IEEE802154E_DESC_SUBID_SHORT_MLME_IE_SHIFT 1 ! ! ! #define IEEE802154E_MLME_SYNC_IE_SUBID 0x1A ! #define IEEE802154E_MLME_SYNC_IE_SUBID_SHIFT 1 ! #define IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID 0x1B ! #define IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID_SHIFT 1 ! #define IEEE802154E_MLME_TIMESLOT_IE_SUBID 0x1c ! #define IEEE802154E_MLME_TIMESLOT_IE_SUBID_SHIFT 1 ! ! #define IEEE802154E_MLME_IE_GROUPID 0x01 ! #define IEEE802154E_ACK_NACK_TIMECORRECTION_ELEMENTID 0x1E ! ! #define IEEE802154E_ ! /** ! When a packet is received, it is written inside the OpenQueueEntry_t->packet ! buffer, starting at the byte defined below. When a packet is relayed, it ! traverses the stack in which the MAC and IPHC headers are parsed and stripped ! off, then put on again. During that process, the IPv6 hop limit field is ! decremented. Depending on the new value of the hop limit, the IPHC header ! compression algorithm might not be able to compress it, and hence has to carry ! it inline, adding a byte to the header. To avoid having to move bytes around ! inside OpenQueueEntry_t->packet buffer, we start writing the received packet a ! bit after the start of the packet. ! */ ! #define FIRST_FRAME_BYTE 1 ! ! // the different states of the IEEE802.15.4e state machine ! typedef enum { ! S_SLEEP = 0x00, // ready for next slot ! // synchronizing ! S_SYNCLISTEN = 0x01, // listened for packet to synchronize to network ! S_SYNCRX = 0x02, // receiving packet to synchronize to network ! S_SYNCPROC = 0x03, // processing packet just received ! // TX ! S_TXDATAOFFSET = 0x04, // waiting to prepare for Tx data ! S_TXDATAPREPARE = 0x05, // preparing for Tx data ! S_TXDATAREADY = 0x06, // ready to Tx data, waiting for 'go' ! S_TXDATADELAY = 0x07, // 'go' signal given, waiting for SFD Tx data ! S_TXDATA = 0x08, // Tx data SFD received, sending bytes ! S_RXACKOFFSET = 0x09, // Tx data done, waiting to prepare for Rx ACK ! S_RXACKPREPARE = 0x0a, // preparing for Rx ACK ! S_RXACKREADY = 0x0b, // ready to Rx ACK, waiting for 'go' ! S_RXACKLISTEN = 0x0c, // idle listening for ACK ! S_RXACK = 0x0d, // Rx ACK SFD received, receiving bytes ! S_TXPROC = 0x0e, // processing sent data ! // RX ! S_RXDATAOFFSET = 0x0f, // waiting to prepare for Rx data ! S_RXDATAPREPARE = 0x10, // preparing for Rx data ! S_RXDATAREADY = 0x11, // ready to Rx data, waiting for 'go' ! S_RXDATALISTEN = 0x12, // idle listening for data ! S_RXDATA = 0x13, // data SFD received, receiving more bytes ! S_TXACKOFFSET = 0x14, // waiting to prepare for Tx ACK ! S_TXACKPREPARE = 0x15, // preparing for Tx ACK ! S_TXACKREADY = 0x16, // Tx ACK ready, waiting for 'go' ! S_TXACKDELAY = 0x17, // 'go' signal given, waiting for SFD Tx ACK ! S_TXACK = 0x18, // Tx ACK SFD received, sending bytes ! S_RXPROC = 0x19, // processing received data ! } ieee154e_state_t; ! ! // Atomic durations ! // expressed in 32kHz ticks: ! // - ticks = duration_in_seconds * 32768 ! // - duration_in_seconds = ticks / 32768 ! enum ieee154e_atomicdurations_enum { ! // time-slot related ! TsTxOffset = 131, // 4000us ! TsLongGT = 43, // 1300us ! TsTxAckDelay = 151, // 4606us ! TsShortGT = 16, // 500us ! // TsShortGT = 30, // 900us, stm32 can work well with this value ! TsSlotDuration = PORT_TsSlotDuration, // 15000us ! // execution speed related ! maxTxDataPrepare = PORT_maxTxDataPrepare, ! maxRxAckPrepare = PORT_maxRxAckPrepare, ! maxRxDataPrepare = PORT_maxRxDataPrepare, ! maxTxAckPrepare = PORT_maxTxAckPrepare, ! // radio speed related ! delayTx = PORT_delayTx, // between GO signal and SFD ! delayRx = PORT_delayRx, // between GO signal and start listening ! // radio watchdog ! wdRadioTx = 33, // 1000us (needs to be >delayTx) ! wdDataDuration = 164, // 5000us (measured 4280us with max payload) ! wdAckDuration = 98, // 3000us (measured 1000us) ! }; ! ! ! //shift of bytes in the linkOption bitmap ! enum ieee154e_linkOption_enum { ! FLAG_TX_S = 7, ! FLAG_RX_S = 6, ! FLAG_SHARED_S = 5, ! FLAG_TIMEKEEPING_S = 4, ! }; ! ! // FSM timer durations (combinations of atomic durations) ! // TX ! #define DURATION_tt1 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx-maxTxDataPrepare ! #define DURATION_tt2 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx ! #define DURATION_tt3 ieee154e_vars.lastCapturedTime+TsTxOffset-delayTx+wdRadioTx ! #define DURATION_tt4 ieee154e_vars.lastCapturedTime+wdDataDuration ! #define DURATION_tt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx-maxRxAckPrepare ! #define DURATION_tt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-TsShortGT-delayRx ! #define DURATION_tt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay+TsShortGT ! #define DURATION_tt8 ieee154e_vars.lastCapturedTime+wdAckDuration ! // RX ! #define DURATION_rt1 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx-maxRxDataPrepare ! #define DURATION_rt2 ieee154e_vars.lastCapturedTime+TsTxOffset-TsLongGT-delayRx ! #define DURATION_rt3 ieee154e_vars.lastCapturedTime+TsTxOffset+TsLongGT ! #define DURATION_rt4 ieee154e_vars.lastCapturedTime+wdDataDuration ! #define DURATION_rt5 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx-maxTxAckPrepare ! #define DURATION_rt6 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx ! #define DURATION_rt7 ieee154e_vars.lastCapturedTime+TsTxAckDelay-delayTx+wdRadioTx ! #define DURATION_rt8 ieee154e_vars.lastCapturedTime+wdAckDuration ! ! //=========================== typedef ========================================= ! ! //IEEE802.15.4E acknowledgement (ACK) ! typedef struct { ! PORT_SIGNED_INT_WIDTH timeCorrection; ! } IEEE802154E_ACK_ht; ! ! //includes payload header IE short + MLME short Header + Sync IE ! #define ADV_PAYLOAD_LENGTH sizeof(payload_IE_descriptor_t) + \ ! sizeof(MLME_IE_subHeader_t) + \ ! sizeof(synch_IE_t) ! ! ! ! ! //=========================== module variables ================================ ! ! typedef struct { ! // misc ! asn_t asn; // current absolute slot number ! slotOffset_t slotOffset; // current slot offset ! slotOffset_t nextActiveSlotOffset; // next active slot offset ! PORT_RADIOTIMER_WIDTH deSyncTimeout; // how many slots left before looses sync ! bool isSync; // TRUE iff mote is synchronized to network ! // as shown on the chronogram ! ieee154e_state_t state; // state of the FSM ! OpenQueueEntry_t* dataToSend; // pointer to the data to send ! OpenQueueEntry_t* dataReceived; // pointer to the data received ! OpenQueueEntry_t* ackToSend; // pointer to the ack to send ! OpenQueueEntry_t* ackReceived; // pointer to the ack received ! PORT_RADIOTIMER_WIDTH lastCapturedTime; // last captured time ! PORT_RADIOTIMER_WIDTH syncCapturedTime; // captured time used to sync ! //channel hopping ! uint8_t freq; // frequency of the current slot ! uint8_t asnOffset; // offset inside the frame ! ! PORT_RADIOTIMER_WIDTH radioOnInit; //when within the slot the radio turns on ! PORT_RADIOTIMER_WIDTH radioOnTics;//how many tics within the slot the radio is on ! bool radioOnThisSlot; //to control if the radio has been turned on in a slot. ! } ieee154e_vars_t; ! ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t numSyncPkt; // how many times synchronized on a non-ACK packet ! uint8_t numSyncAck; // how many times synchronized on an ACK ! PORT_SIGNED_INT_WIDTH minCorrection; // minimum time correction ! PORT_SIGNED_INT_WIDTH maxCorrection; // maximum time correction ! uint8_t numDeSync; // number of times a desync happened ! float dutyCycle; // mac dutyCycle at each superframe ! } ieee154e_stats_t; ! //PRAGMA(pack()); ! ! typedef struct { ! PORT_RADIOTIMER_WIDTH num_newSlot; ! PORT_RADIOTIMER_WIDTH num_timer; ! PORT_RADIOTIMER_WIDTH num_startOfFrame; ! PORT_RADIOTIMER_WIDTH num_endOfFrame; ! } ieee154e_dbg_t; ! ! ! //=========================== IEs ============================================= ! //the header for all header IEs ! typedef struct{ ! uint16_t length_elementid_type; ! }header_IE_descriptor_t; ! //header descriptor. elementid will be 0 as described in 15.4e pag. 81 ! //type is 0 as described on p. 80 ! ! ! //the content for ack ie -- it is a header IE with values - element id =0x1e len=2 type=0 ! //PRAGMA(pack(1)); ! typedef struct { ! int16_t timesync_info; ! }ack_timecorrection_IE_t; ! //PRAGMA(pack()); ! //the header for all payload IEs ! ! ! typedef struct{//11b len 4b gid 1b type ! uint16_t length_groupid_type; //bytes on the IE content- that is the embedded MLME or Header IE. ! //groupid == 0x01 MLME | type long = 1 ! }payload_IE_descriptor_t; // payload descriptor. groupid will be 1 as described in 15.4e pag. 81 ! ! //MLME sub id header appended to payload descriptor. we use group id=1 type=1 ! typedef struct{ ! uint16_t length_subID_type; ! }MLME_IE_subHeader_t; ! ! //the Synchronization IE. it is a payload IE with values - subid=0x1a type=0 (short) len=6 ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t asn[5]; ! uint8_t join_priority; ! }synch_IE_t; ! //PRAGMA(pack()); ! ! //the Slotframe and Link IE ! typedef struct { ! uint8_t slotframehandle; ! uint16_t slotframesize; ! uint8_t numlinks; ! }slotframelink_IE_t; ! ! typedef struct { ! uint16_t tsNum; ! uint16_t choffset; ! uint8_t linkoptions; ! }linkInfo_subIE_t; ! ! //=========================== prototypes ====================================== ! ! // admin ! void ieee154e_init(void); ! // public ! PORT_RADIOTIMER_WIDTH ieee154e_asnDiff(asn_t* someASN); ! bool ieee154e_isSynch(void); ! void ieee154e_getAsn(uint8_t* array); ! // events ! void ieee154e_startOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); ! void ieee154e_endOfFrame(PORT_RADIOTIMER_WIDTH capturedTime); ! // misc ! bool debugPrint_asn(void); ! bool debugPrint_isSync(void); ! bool debugPrint_macStats(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/02a-MAClow/Makefile ../../../sys/net/openwsn/02a-MAClow/Makefile *** openwsn/02a-MAClow/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/02a-MAClow/Makefile Wed Jan 15 13:48:26 2014 *************** *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) + $(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 + $(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 , August 2010 ! */ ! ! #include "openwsn.h" ! #include "stupidmac.h" ! #include "IEEE802154.h" ! #include "radio.h" ! #include "packetfunctions.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "timers.h" ! #include "packetfunctions.h" ! #include "neighbors.h" ! #include "nores.h" ! ! //=========================== variables ======================================= ! ! OpenQueueEntry_t* stupidmac_dataFrameToSend; // NULL at beginning and end of slot ! OpenQueueEntry_t* stupidmac_packetACK; // NULL at beginning and end, free at end of slot ! OpenQueueEntry_t* stupidmac_dataFrameReceived; // !NULL between data received, and sent to upper layer ! uint8_t stupidmac_dsn; ! uint8_t stupidmac_state; ! #ifndef SERIALINSCHEDULER ! bool stupidmac_serialInOutputMode; ! #endif ! ! //=========================== prototypes ====================================== ! ! #include "IEEE802154_common.c" ! void packetReceived(); ! void armRandomBackoffTimer(); ! void change_state(uint8_t newstate); ! ! //======= from upper layer ! ! //in stupidMAC, the radio is always on, listening ! void stupidmac_init() { ! radio_rxOn(openwsn_frequency_channel); ! change_state(S_IDLE_LISTENING); ! stupidmac_dataFrameToSend = NULL; ! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); ! } ! ! //a packet sent from the upper layer is simply stored into the OpenQueue buffer. ! //The timerBackoff is armed to service the packet later on. ! error_t stupidmac_send(OpenQueueEntry_t* msg) { ! //metadata ! msg->owner = COMPONENT_MAC; ! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { ! msg->l2_retriesLeft = 1; ! } else { ! msg->l2_retriesLeft = TXRETRIES; ! } ! msg->l1_txPower = TX_POWER; ! msg->l1_channel = openwsn_frequency_channel; ! //IEEE802.15.4 header ! prependIEEE802154header(msg, ! msg->l2_frameType, ! IEEE154_SEC_NO_SECURITY, ! stupidmac_dsn++, ! &(msg->l2_nextORpreviousHop) ! ); ! // space for 2-byte CRC ! packetfunctions_reserveFooterSize(msg,2); ! //simulate timer backoff fires so that packet gets sent immediately ! timer_mac_backoff_fired(); ! return E_SUCCESS; ! } ! ! //======= from lower layer ! ! void stupidmac_sendDone(OpenQueueEntry_t* pkt, error_t error) { ! switch (stupidmac_state) { ! case S_TX_TXDATA: //[sendNowDone] transmitter ! if (error!=E_SUCCESS) { ! nores_sendDone(pkt,E_FAIL); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer();//arm timer to retransmission (?) ! change_state(S_IDLE_LISTENING); ! openserial_printError(COMPONENT_MAC,ERR_SENDNOWDONE_FAILED, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! return; ! } else { ! timer_startOneShot(TIMER_MAC_WATCHDOG,ACK_WAIT_TIME); ! change_state(S_TX_RXACK); ! } ! break; ! case S_RX_TXACK: //[sendNowDone] receiver ! //I'm a receiver, finished sending ACK (end of RX sequence) ! openqueue_freePacketBuffer(stupidmac_packetACK); ! packetReceived(); ! change_state(S_IDLE_LISTENING); ! break; ! default: ! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_SUBSEND_SENDDONE, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! change_state(S_IDLE_LISTENING); ! break; ! } ! } ! ! void radio_packet_received(OpenQueueEntry_t* msg) { ! ieee802154_header_iht received_ieee154_header; ! ieee802154_header_iht transmitted_ieee154_header; ! ! openserial_stop(); ! //ensure debug fires only after packet fully received ! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); ! ! msg->owner = COMPONENT_MAC; ! ! if (stupidmac_state!=S_TX_RXACK && stupidmac_state!=S_IDLE_LISTENING) { ! //not expecting this packet, throw away ! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was ! openqueue_freePacketBuffer(msg); ! return; ! } ! ! received_ieee154_header = retrieveIEEE802154header(msg); ! packetfunctions_tossHeader(msg,received_ieee154_header.headerLength); ! packetfunctions_tossFooter(msg,2); ! ! msg->l2_frameType = received_ieee154_header.frameType; ! memcpy(&(msg->l2_nextORpreviousHop),&(received_ieee154_header.src),sizeof(open_addr_t)); ! if ( received_ieee154_header.frameType==IEEE154_TYPE_DATA && ! !(idmanager_isMyAddress(&received_ieee154_header.panid))) { ! openserial_printError(COMPONENT_MAC,ERR_WRONG_PANID, ! (errorparameter_t)received_ieee154_header.panid.panid[0]*256+received_ieee154_header.panid.panid[1], ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! ! switch (stupidmac_state) { ! ! /*------------------- TX sequence ------------------------*/ ! case S_TX_RXACK: //[receive] transmitter ! transmitted_ieee154_header = retrieveIEEE802154header(stupidmac_dataFrameToSend); ! if (received_ieee154_header.dsn == transmitted_ieee154_header.dsn) { ! //I'm a transmitter, just received ACK (end of TX sequence) ! timer_stop(TIMER_MAC_WATCHDOG); ! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_ACKED); ! nores_sendDone(stupidmac_dataFrameToSend,E_SUCCESS); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer();//arm timer for next transmission ! change_state(S_IDLE_LISTENING); ! } ! openqueue_freePacketBuffer(msg);//free packet I received ! break; ! ! /*------------------- RX sequence ------------------------*/ ! case S_IDLE_LISTENING: //[receive] receiver ! //I'm a receiver, just received a packet ! if (received_ieee154_header.frameType==IEEE154_TYPE_DATA || received_ieee154_header.frameType==IEEE154_TYPE_CMD) { ! neighbors_indicateRx(&(msg->l2_nextORpreviousHop),msg->l1_rssi); ! if (idmanager_isMyAddress(&received_ieee154_header.dest)) { ! //this packet is unicast to me ! if (stupidmac_dataFrameReceived==NULL) { ! stupidmac_dataFrameReceived = msg; ! } else { ! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! } ! //the sender requests an ACK ! if (received_ieee154_header.ackRequested) { ! change_state(S_RX_TXACKPREPARE); ! stupidmac_packetACK = openqueue_getFreePacketBuffer(); ! if (stupidmac_packetACK!=NULL) { ! //send ACK ! stupidmac_packetACK->creator = COMPONENT_MAC; ! stupidmac_packetACK->owner = COMPONENT_MAC; ! stupidmac_packetACK->l1_txPower = TX_POWER; ! stupidmac_packetACK->l1_channel = openwsn_frequency_channel; ! stupidmac_packetACK->l2_retriesLeft = 1; ! prependIEEE802154header(stupidmac_packetACK, ! IEEE154_TYPE_ACK, ! IEEE154_SEC_NO_SECURITY, ! received_ieee154_header.dsn, ! NULL); ! packetfunctions_reserveFooterSize(stupidmac_packetACK,2); ! change_state(S_RX_TXACKREADY); ! change_state(S_RX_TXACK); ! if (radio_send(stupidmac_packetACK)!=E_SUCCESS) { ! //abort ! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, ! (errorparameter_t)0,(errorparameter_t)2); ! openqueue_freePacketBuffer(stupidmac_packetACK); ! change_state(S_IDLE_LISTENING); ! } ! } else { ! openserial_printError(COMPONENT_MAC,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0,(errorparameter_t)0); ! change_state(S_IDLE_LISTENING); ! void packetReceived(); ! return; ! } ! } else { ! packetReceived(); ! } ! } else if (packetfunctions_isBroadcastMulticast(&received_ieee154_header.dest)==TRUE) { ! //this packet is broadcast ! if (stupidmac_dataFrameReceived==NULL) { ! stupidmac_dataFrameReceived = msg; ! } else { ! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, ! (errorparameter_t)1, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! } ! packetReceived(); ! } else { ! openqueue_freePacketBuffer(msg); ! } ! } else { ! //not data. I could be an ACK but I'm not in S_TX_RXACK stupidmac_state, so I discard ! openqueue_freePacketBuffer(msg); ! } ! break; ! ! default: ! //this should never happen as error was caught above ! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was ! openqueue_freePacketBuffer(msg); ! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_RECEIVE, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! break; ! } ! } ! ! //=========================== private ========================================= ! ! void packetReceived() { ! if (stupidmac_dataFrameReceived->length>0) { ! //packet contains payload destined to an upper layer ! nores_receive(stupidmac_dataFrameReceived); ! } else { ! //packet contains no payload (KA) ! openqueue_freePacketBuffer(stupidmac_dataFrameReceived); ! } ! stupidmac_dataFrameReceived = NULL; ! } ! ! void armRandomBackoffTimer() { ! timer_startOneShot(TIMER_MAC_BACKOFF,MINBACKOFF); //TODO randomize ! } ! ! void change_state(uint8_t newstate) { ! stupidmac_state = newstate; ! switch (newstate) { ! case S_TX_TXDATAPREPARE: ! case S_TX_TXDATA: ! case S_RX_TXACKPREPARE: ! case S_RX_TXACK: ! //atomic P3OUT |= 0x20; ! break; ! case S_TX_TXDATAREADY: ! case S_TX_RXACK: ! case S_RX_TXACKREADY: ! case S_IDLE_LISTENING: ! //atomic P3OUT &= ~0x20; ! break; ! } ! } ! ! bool stupidmac_debugPrint() { ! return FALSE; ! } ! ! //======= timers firing ! ! //periodic timer used to transmit, and to trigger serial input/output ! void timer_mac_periodic_fired() { ! #ifndef SERIALINSCHEDULER ! openserial_stop(); ! #endif ! //trigger transmit ! armRandomBackoffTimer(); ! #ifndef SERIALINSCHEDULER ! //trigger serial input/output ! stupidmac_serialInOutputMode = !stupidmac_serialInOutputMode; ! if (stupidmac_serialInOutputMode) { ! openserial_startOutput(); ! } else { ! openserial_startInput(); ! } ! #endif ! } ! ! //this function is the one which really initiates the transmission of a packet. ! //It only does so if the MAC layer is in S_IDLE_LISTENING stupidmac_state, otherwise it defers ! void timer_mac_backoff_fired() { ! if (stupidmac_state==S_IDLE_LISTENING) { ! if (stupidmac_dataFrameToSend!=NULL) { ! openserial_printError(COMPONENT_MAC,ERR_DATAFRAMETOSEND_ERROR, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! stupidmac_dataFrameToSend = openqueue_inQueue(IS_NOT_ADV); ! if (stupidmac_dataFrameToSend==NULL) { ! stupidmac_dataFrameToSend = openqueue_inQueue(IS_ADV); ! } ! if (stupidmac_dataFrameToSend!=NULL) { ! change_state(S_TX_TXDATA); ! if (radio_send(stupidmac_dataFrameToSend)!=E_SUCCESS) { ! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer();//arm to retry later ! change_state(S_IDLE_LISTENING); ! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! } ! } else { ! //retry later on ! armRandomBackoffTimer(); ! } ! } ! ! void timer_mac_watchdog_fired() { ! switch (stupidmac_state) { ! case S_TX_RXACK: ! //I'm a transmitter, didn't receive ACK (end of TX sequence). ! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_NOT_ACKED); ! stupidmac_dataFrameToSend->l2_retriesLeft--; ! if (stupidmac_dataFrameToSend->l2_retriesLeft==0) { ! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer(); ! change_state(S_IDLE_LISTENING); ! break; ! } ! //retransmit later on ! armRandomBackoffTimer(); ! stupidmac_dataFrameToSend = NULL; ! change_state(S_IDLE_LISTENING); ! break; ! default: ! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_FASTTIMER_FIRED, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! change_state(S_IDLE_LISTENING); ! break; ! } } \ No newline at end of file --- 1,354 ---- ! /** ! \brief Implementation of stupidMAC ! ! \author Thomas Watteyne , August 2010 ! */ ! ! #include "openwsn.h" ! #include "stupidmac.h" ! #include "IEEE802154.h" ! #include "radio.h" ! #include "packetfunctions.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "timers.h" ! #include "packetfunctions.h" ! #include "neighbors.h" ! #include "nores.h" ! ! //=========================== variables ======================================= ! ! OpenQueueEntry_t* stupidmac_dataFrameToSend; // NULL at beginning and end of slot ! OpenQueueEntry_t* stupidmac_packetACK; // NULL at beginning and end, free at end of slot ! OpenQueueEntry_t* stupidmac_dataFrameReceived; // !NULL between data received, and sent to upper layer ! uint8_t stupidmac_dsn; ! uint8_t stupidmac_state; ! #ifndef SERIALINSCHEDULER ! bool stupidmac_serialInOutputMode; ! #endif ! ! //=========================== prototypes ====================================== ! ! #include "IEEE802154_common.c" ! void packetReceived(void); ! void armRandomBackoffTimer(void); ! void change_state(uint8_t newstate); ! ! //======= from upper layer ! ! //in stupidMAC, the radio is always on, listening ! void stupidmac_init(void) { ! radio_rxOn(openwsn_frequency_channel); ! change_state(S_IDLE_LISTENING); ! stupidmac_dataFrameToSend = NULL; ! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); ! } ! ! //a packet sent from the upper layer is simply stored into the OpenQueue buffer. ! //The timerBackoff is armed to service the packet later on. ! error_t stupidmac_send(OpenQueueEntry_t* msg) { ! //metadata ! msg->owner = COMPONENT_MAC; ! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { ! msg->l2_retriesLeft = 1; ! } else { ! msg->l2_retriesLeft = TXRETRIES; ! } ! msg->l1_txPower = TX_POWER; ! msg->l1_channel = openwsn_frequency_channel; ! //IEEE802.15.4 header ! prependIEEE802154header(msg, ! msg->l2_frameType, ! IEEE154_SEC_NO_SECURITY, ! stupidmac_dsn++, ! &(msg->l2_nextORpreviousHop) ! ); ! // space for 2-byte CRC ! packetfunctions_reserveFooterSize(msg,2); ! //simulate timer backoff fires so that packet gets sent immediately ! timer_mac_backoff_fired(); ! return E_SUCCESS; ! } ! ! //======= from lower layer ! ! void stupidmac_sendDone(OpenQueueEntry_t* pkt, error_t error) { ! switch (stupidmac_state) { ! case S_TX_TXDATA: //[sendNowDone] transmitter ! if (error!=E_SUCCESS) { ! nores_sendDone(pkt,E_FAIL); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer();//arm timer to retransmission (?) ! change_state(S_IDLE_LISTENING); ! openserial_printError(COMPONENT_MAC,ERR_SENDNOWDONE_FAILED, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! return; ! } else { ! timer_startOneShot(TIMER_MAC_WATCHDOG,ACK_WAIT_TIME); ! change_state(S_TX_RXACK); ! } ! break; ! case S_RX_TXACK: //[sendNowDone] receiver ! //I'm a receiver, finished sending ACK (end of RX sequence) ! openqueue_freePacketBuffer(stupidmac_packetACK); ! packetReceived(); ! change_state(S_IDLE_LISTENING); ! break; ! default: ! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_SUBSEND_SENDDONE, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! change_state(S_IDLE_LISTENING); ! break; ! } ! } ! ! void radio_packet_received(OpenQueueEntry_t* msg) { ! ieee802154_header_iht received_ieee154_header; ! ieee802154_header_iht transmitted_ieee154_header; ! ! openserial_stop(); ! //ensure debug fires only after packet fully received ! timer_startPeriodic(TIMER_MAC_PERIODIC,PERIODICTIMERPERIOD); ! ! msg->owner = COMPONENT_MAC; ! ! if (stupidmac_state!=S_TX_RXACK && stupidmac_state!=S_IDLE_LISTENING) { ! //not expecting this packet, throw away ! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was ! openqueue_freePacketBuffer(msg); ! return; ! } ! ! received_ieee154_header = retrieveIEEE802154header(msg); ! packetfunctions_tossHeader(msg,received_ieee154_header.headerLength); ! packetfunctions_tossFooter(msg,2); ! ! msg->l2_frameType = received_ieee154_header.frameType; ! memcpy(&(msg->l2_nextORpreviousHop),&(received_ieee154_header.src),sizeof(open_addr_t)); ! if ( received_ieee154_header.frameType==IEEE154_TYPE_DATA && ! !(idmanager_isMyAddress(&received_ieee154_header.panid))) { ! openserial_printError(COMPONENT_MAC,ERR_WRONG_PANID, ! (errorparameter_t)received_ieee154_header.panid.panid[0]*256+received_ieee154_header.panid.panid[1], ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! ! switch (stupidmac_state) { ! ! /*------------------- TX sequence ------------------------*/ ! case S_TX_RXACK: //[receive] transmitter ! transmitted_ieee154_header = retrieveIEEE802154header(stupidmac_dataFrameToSend); ! if (received_ieee154_header.dsn == transmitted_ieee154_header.dsn) { ! //I'm a transmitter, just received ACK (end of TX sequence) ! timer_stop(TIMER_MAC_WATCHDOG); ! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_ACKED); ! nores_sendDone(stupidmac_dataFrameToSend,E_SUCCESS); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer();//arm timer for next transmission ! change_state(S_IDLE_LISTENING); ! } ! openqueue_freePacketBuffer(msg);//free packet I received ! break; ! ! /*------------------- RX sequence ------------------------*/ ! case S_IDLE_LISTENING: //[receive] receiver ! //I'm a receiver, just received a packet ! if (received_ieee154_header.frameType==IEEE154_TYPE_DATA || received_ieee154_header.frameType==IEEE154_TYPE_CMD) { ! neighbors_indicateRx(&(msg->l2_nextORpreviousHop),msg->l1_rssi); ! if (idmanager_isMyAddress(&received_ieee154_header.dest)) { ! //this packet is unicast to me ! if (stupidmac_dataFrameReceived==NULL) { ! stupidmac_dataFrameReceived = msg; ! } else { ! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! } ! //the sender requests an ACK ! if (received_ieee154_header.ackRequested) { ! change_state(S_RX_TXACKPREPARE); ! stupidmac_packetACK = openqueue_getFreePacketBuffer(); ! if (stupidmac_packetACK!=NULL) { ! //send ACK ! stupidmac_packetACK->creator = COMPONENT_MAC; ! stupidmac_packetACK->owner = COMPONENT_MAC; ! stupidmac_packetACK->l1_txPower = TX_POWER; ! stupidmac_packetACK->l1_channel = openwsn_frequency_channel; ! stupidmac_packetACK->l2_retriesLeft = 1; ! prependIEEE802154header(stupidmac_packetACK, ! IEEE154_TYPE_ACK, ! IEEE154_SEC_NO_SECURITY, ! received_ieee154_header.dsn, ! NULL); ! packetfunctions_reserveFooterSize(stupidmac_packetACK,2); ! change_state(S_RX_TXACKREADY); ! change_state(S_RX_TXACK); ! if (radio_send(stupidmac_packetACK)!=E_SUCCESS) { ! //abort ! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, ! (errorparameter_t)0,(errorparameter_t)2); ! openqueue_freePacketBuffer(stupidmac_packetACK); ! change_state(S_IDLE_LISTENING); ! } ! } else { ! openserial_printError(COMPONENT_MAC,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0,(errorparameter_t)0); ! change_state(S_IDLE_LISTENING); ! void packetReceived(); ! return; ! } ! } else { ! packetReceived(); ! } ! } else if (packetfunctions_isBroadcastMulticast(&received_ieee154_header.dest)==TRUE) { ! //this packet is broadcast ! if (stupidmac_dataFrameReceived==NULL) { ! stupidmac_dataFrameReceived = msg; ! } else { ! openserial_printError(COMPONENT_MAC,ERR_BUSY_RECEIVING, ! (errorparameter_t)1, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! } ! packetReceived(); ! } else { ! openqueue_freePacketBuffer(msg); ! } ! } else { ! //not data. I could be an ACK but I'm not in S_TX_RXACK stupidmac_state, so I discard ! openqueue_freePacketBuffer(msg); ! } ! break; ! ! default: ! //this should never happen as error was caught above ! //do not go back to S_IDLE_LISTENING, just don't receive the packet and let the stupidmac_state machine be where it was ! openqueue_freePacketBuffer(msg); ! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_RECEIVE, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! break; ! } ! } ! ! //=========================== private ========================================= ! ! void packetReceived(void) { ! if (stupidmac_dataFrameReceived->length>0) { ! //packet contains payload destined to an upper layer ! nores_receive(stupidmac_dataFrameReceived); ! } else { ! //packet contains no payload (KA) ! openqueue_freePacketBuffer(stupidmac_dataFrameReceived); ! } ! stupidmac_dataFrameReceived = NULL; ! } ! ! void armRandomBackoffTimer(void) { ! timer_startOneShot(TIMER_MAC_BACKOFF,MINBACKOFF); //TODO randomize ! } ! ! void change_state(uint8_t newstate) { ! stupidmac_state = newstate; ! switch (newstate) { ! case S_TX_TXDATAPREPARE: ! case S_TX_TXDATA: ! case S_RX_TXACKPREPARE: ! case S_RX_TXACK: ! //atomic P3OUT |= 0x20; ! break; ! case S_TX_TXDATAREADY: ! case S_TX_RXACK: ! case S_RX_TXACKREADY: ! case S_IDLE_LISTENING: ! //atomic P3OUT &= ~0x20; ! break; ! } ! } ! ! bool stupidmac_debugPrint(void) { ! return FALSE; ! } ! ! //======= timers firing ! ! //periodic timer used to transmit, and to trigger serial input/output ! void timer_mac_periodic_fired(void) { ! #ifndef SERIALINSCHEDULER ! openserial_stop(); ! #endif ! //trigger transmit ! armRandomBackoffTimer(); ! #ifndef SERIALINSCHEDULER ! //trigger serial input/output ! stupidmac_serialInOutputMode = !stupidmac_serialInOutputMode; ! if (stupidmac_serialInOutputMode) { ! openserial_startOutput(); ! } else { ! openserial_startInput(); ! } ! #endif ! } ! ! //this function is the one which really initiates the transmission of a packet. ! //It only does so if the MAC layer is in S_IDLE_LISTENING stupidmac_state, otherwise it defers ! void timer_mac_backoff_fired(void) { ! if (stupidmac_state==S_IDLE_LISTENING) { ! if (stupidmac_dataFrameToSend!=NULL) { ! openserial_printError(COMPONENT_MAC,ERR_DATAFRAMETOSEND_ERROR, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! stupidmac_dataFrameToSend = openqueue_inQueue(IS_NOT_ADV); ! if (stupidmac_dataFrameToSend==NULL) { ! stupidmac_dataFrameToSend = openqueue_inQueue(IS_ADV); ! } ! if (stupidmac_dataFrameToSend!=NULL) { ! change_state(S_TX_TXDATA); ! if (radio_send(stupidmac_dataFrameToSend)!=E_SUCCESS) { ! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer();//arm to retry later ! change_state(S_IDLE_LISTENING); ! openserial_printError(COMPONENT_MAC,ERR_PREPARESEND_FAILED, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! } ! } else { ! //retry later on ! armRandomBackoffTimer(); ! } ! } ! ! void timer_mac_watchdog_fired(void) { ! switch (stupidmac_state) { ! case S_TX_RXACK: ! //I'm a transmitter, didn't receive ACK (end of TX sequence). ! neighbors_indicateTx(&(stupidmac_dataFrameToSend->l2_nextORpreviousHop),WAS_NOT_ACKED); ! stupidmac_dataFrameToSend->l2_retriesLeft--; ! if (stupidmac_dataFrameToSend->l2_retriesLeft==0) { ! nores_sendDone(stupidmac_dataFrameToSend,E_FAIL); ! stupidmac_dataFrameToSend = NULL; ! armRandomBackoffTimer(); ! change_state(S_IDLE_LISTENING); ! break; ! } ! //retransmit later on ! armRandomBackoffTimer(); ! stupidmac_dataFrameToSend = NULL; ! change_state(S_IDLE_LISTENING); ! break; ! default: ! openserial_printError(COMPONENT_MAC,ERR_WRONG_STATE_IN_FASTTIMER_FIRED, ! (errorparameter_t)stupidmac_state, ! (errorparameter_t)0); ! change_state(S_IDLE_LISTENING); ! break; ! } } \ No newline at end of file diff -crB openwsn/02a-MAClow/stupidmac/stupidmac.h ../../../sys/net/openwsn/02a-MAClow/stupidmac/stupidmac.h *** openwsn/02a-MAClow/stupidmac/stupidmac.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/stupidmac/stupidmac.h Wed Jan 15 13:48:26 2014 *************** *** 1,60 **** ! /** ! \brief Implementation of stupidMAC ! ! \author Thomas Watteyne , August 2010 ! */ ! ! #ifndef __STUPIDMAC_H ! #define __STUPIDMAC_H ! ! #include "openwsn.h" ! ! enum { ! //default ! S_IDLE_LISTENING = 0, ! //transmitter ! S_TX_TXDATAPREPARE = 1, ! S_TX_TXDATAREADY = 2, ! S_TX_TXDATA = 3, ! S_TX_RXACK = 4, ! //receiver ! S_RX_TXACKPREPARE = 5, ! S_RX_TXACKREADY = 6, ! S_RX_TXACK = 7, ! }; ! ! enum { ! IMMEDIATELY = 1, //used as timer value which is very small ! WATCHDOG_PREPARESEND = 16000, //500ms ! }; ! ! enum { ! WAS_ACKED = TRUE, ! WAS_NOT_ACKED = FALSE, ! }; ! ! //timer wait times (in 1/32768 seconds), slow version ! /*enum { ! PERIODICTIMERPERIOD = 9828, // 300ms ! MINBACKOFF = 6552, // 200ms ! ACK_WAIT_TIME = 3276, // 100ms ! };*/ ! ! //timer wait times (in 1/32768 seconds), fast version ! enum { ! PERIODICTIMERPERIOD = 982, // 30ms ! MINBACKOFF = 655, // 20ms ! ACK_WAIT_TIME = 327, // 10ms ! }; ! ! void stupidmac_init(); ! error_t stupidmac_send(OpenQueueEntry_t* msg); ! void stupidmac_sendDone(OpenQueueEntry_t* msg, error_t error); ! void stupidmac_packet_received(OpenQueueEntry_t* pkt); ! void stupidmac_sendDone(OpenQueueEntry_t* packetReceived, error_t error); ! void timer_mac_backoff_fired(); ! void timer_mac_watchdog_fired(); ! void timer_mac_periodic_fired(); ! bool stupidmac_debugPrint(); ! ! #endif --- 1,60 ---- ! /** ! \brief Implementation of stupidMAC ! ! \author Thomas Watteyne , August 2010 ! */ ! ! #ifndef __STUPIDMAC_H ! #define __STUPIDMAC_H ! ! #include "openwsn.h" ! ! enum { ! //default ! S_IDLE_LISTENING = 0, ! //transmitter ! S_TX_TXDATAPREPARE = 1, ! S_TX_TXDATAREADY = 2, ! S_TX_TXDATA = 3, ! S_TX_RXACK = 4, ! //receiver ! S_RX_TXACKPREPARE = 5, ! S_RX_TXACKREADY = 6, ! S_RX_TXACK = 7, ! }; ! ! enum { ! IMMEDIATELY = 1, //used as timer value which is very small ! WATCHDOG_PREPARESEND = 16000, //500ms ! }; ! ! enum { ! WAS_ACKED = TRUE, ! WAS_NOT_ACKED = FALSE, ! }; ! ! //timer wait times (in 1/32768 seconds), slow version ! /*enum { ! PERIODICTIMERPERIOD = 9828, // 300ms ! MINBACKOFF = 6552, // 200ms ! ACK_WAIT_TIME = 3276, // 100ms ! };*/ ! ! //timer wait times (in 1/32768 seconds), fast version ! enum { ! PERIODICTIMERPERIOD = 982, // 30ms ! MINBACKOFF = 655, // 20ms ! ACK_WAIT_TIME = 327, // 10ms ! }; ! ! void stupidmac_init(void); ! owerror_t stupidmac_send(OpenQueueEntry_t* msg); ! void stupidmac_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! void stupidmac_packet_received(OpenQueueEntry_t* pkt); ! void stupidmac_sendDone(OpenQueueEntry_t* packetReceived, owerror_t error); ! void timer_mac_backoff_fired(void); ! void timer_mac_watchdog_fired(void); ! void timer_mac_periodic_fired(void); ! bool stupidmac_debugPrint(void); ! ! #endif diff -crB openwsn/02a-MAClow/topology.c ../../../sys/net/openwsn/02a-MAClow/topology.c *** openwsn/02a-MAClow/topology.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/topology.c Wed Jan 15 13:48:26 2014 *************** *** 1,48 **** ! #include "openwsn.h" ! #include "topology.h" ! #include "idmanager.h" ! ! //=========================== defines ========================================= ! ! #define TOPOLOGY_MOTE1 0x6f ! #define TOPOLOGY_MOTE2 0xb9 ! #define TOPOLOGY_MOTE3 0x3b ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) { ! bool returnVal; ! switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) { ! case TOPOLOGY_MOTE1: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! case TOPOLOGY_MOTE2: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE1 || ! ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! case TOPOLOGY_MOTE3: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! default: ! returnVal=TRUE; ! } ! return returnVal; ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,56 ---- ! #include "openwsn.h" ! #include "topology.h" ! #include "idmanager.h" ! ! //=========================== defines ========================================= ! ! #define TOPOLOGY_MOTE1 0x01 ! #define TOPOLOGY_MOTE2 0x02 ! #define TOPOLOGY_MOTE3 0x03 ! #define TOPOLOGY_MOTE4 0x04 ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header) { ! bool returnVal; ! switch (idmanager_getMyID(ADDR_64B)->addr_64b[7]) { ! case TOPOLOGY_MOTE1: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! case TOPOLOGY_MOTE2: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE1 || ! ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! case TOPOLOGY_MOTE3: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE2 || ! ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE4) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! case TOPOLOGY_MOTE4: ! if (ieee802514_header->src.addr_64b[7]==TOPOLOGY_MOTE3) { ! returnVal=TRUE; ! } else { ! returnVal=FALSE; ! } ! break; ! default: ! returnVal=TRUE; ! } ! return returnVal; ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/02a-MAClow/topology.h ../../../sys/net/openwsn/02a-MAClow/topology.h *** openwsn/02a-MAClow/topology.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02a-MAClow/topology.h Wed Jan 15 13:48:26 2014 *************** *** 1,31 **** ! #ifndef __TOPOLOGY_H ! #define __TOPOLOGY_H ! ! /** ! \addtogroup MAClow ! \{ ! \addtogroup topology ! \{ ! */ ! ! #include "openwsn.h" ! #include "IEEE802154.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== prototypes ====================================== ! ! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,31 ---- ! #ifndef __TOPOLOGY_H ! #define __TOPOLOGY_H ! ! /** ! \addtogroup MAClow ! \{ ! \addtogroup topology ! \{ ! */ ! ! #include "openwsn.h" ! #include "IEEE802154.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== prototypes ====================================== ! ! bool topology_isAcceptablePacket(ieee802154_header_iht* ieee802514_header); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/02b-MAChigh/Makefile ../../../sys/net/openwsn/02b-MAChigh/Makefile *** openwsn/02b-MAChigh/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/02b-MAChigh/Makefile Wed Jan 15 13:48:26 2014 *************** *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) + $(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 + $(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;itype = ADDR_NONE; ! ! foundPreferred = FALSE; ! numNeighbors = 0; ! minRankVal = MAXDAGRANK; ! minRankIdx = MAXNUMNEIGHBORS+1; ! ! //===== step 1. Try to find preferred parent ! for (i=0; itype=ADDR_64B; ! foundPreferred=TRUE; ! } ! // identify neighbor with lowest rank ! if (neighbors_vars.neighbors[i].DAGrank < minRankVal) { ! minRankVal=neighbors_vars.neighbors[i].DAGrank; ! minRankIdx=i; ! } ! numNeighbors++; ! } ! } ! ! //===== step 2. (backup) Promote neighbor with min rank to preferred parent ! if (foundPreferred==FALSE && numNeighbors > 0){ ! // promote neighbor ! neighbors_vars.neighbors[minRankIdx].parentPreference = MAXPREFERENCE; ! neighbors_vars.neighbors[minRankIdx].stableNeighbor = TRUE; ! neighbors_vars.neighbors[minRankIdx].switchStabilityCounter = 0; ! // return its address ! memcpy(addressToWrite,&(neighbors_vars.neighbors[minRankIdx].addr_64b),sizeof(open_addr_t)); ! addressToWrite->type=ADDR_64B; ! foundPreferred=TRUE; ! } ! ! return foundPreferred; ! } ! ! /** ! \brief Find neighbor to which to send KA. ! ! This function iterates through the neighbor table and identifies the neighbor ! we need to send a KA to, if any. This neighbor satisfies the following ! conditions: ! - it is one of our preferred parents ! - we haven't heard it for over KATIMEOUT ! ! \returns A pointer to the neighbor's address, or NULL if no KA is needed. ! */ ! open_addr_t* neighbors_getKANeighbor() { ! uint8_t i; ! uint16_t timeSinceHeard; ! open_addr_t* addrPreferred; ! open_addr_t* addrOther; ! ! // initialize ! addrPreferred = NULL; ! addrOther = NULL; ! ! // scan through the neighbor table, and populate addrPreferred and addrOther ! for (i=0;iKATIMEOUT) { ! // this neighbor needs to be KA'ed to ! if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) { ! // its a preferred parent ! addrPreferred = &(neighbors_vars.neighbors[i].addr_64b); ! } else { ! // its not a preferred parent ! // Note: commented out since policy is not to KA to non-preferred parents ! // addrOther = &(neighbors_vars.neighbors[i].addr_64b); ! } ! } ! } ! } ! ! // return the addr of the most urgent KA to send: ! // - if available, preferred parent ! // - if not, non preferred parent ! if (addrPreferred!=NULL) { ! return addrPreferred; ! } else if (addrOther!=NULL) { ! return addrOther; ! } else { ! return NULL; ! } ! } ! ! //===== interrogators ! ! /** ! \brief Indicate whether some neighbor is a stable neighbor ! ! \param address [in] The address of the neighbor, a full 128-bit IPv6 addres. ! ! \returns TRUE if that neighbor is stable, FALSE otherwise. ! */ ! bool neighbors_isStableNeighbor(open_addr_t* address) { ! uint8_t i; ! open_addr_t temp_addr_64b; ! open_addr_t temp_prefix; ! bool returnVal; ! ! // by default, not stable ! returnVal = FALSE; ! ! // but neighbor's IPv6 address in prefix and EUI64 ! switch (address->type) { ! case ADDR_128B: ! packetfunctions_ip128bToMac64b(address,&temp_prefix,&temp_addr_64b); ! break; ! default: ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)0); ! return returnVal; ! } ! ! // iterate through neighbor table ! for (i=0;i= neighbors_getMyDAGrank()) { ! returnVal = TRUE; ! } else { ! returnVal = FALSE; ! } ! ! return returnVal; ! } ! ! //===== updating neighbor information ! ! /** ! \brief Indicate some (non-ACK) packet was received from a neighbor. ! ! This function should be called for each received (non-ACK) packet so neighbor ! statistics in the neighbor table can be updated. ! ! The fields which are updated are: ! - numRx ! - rssi ! - asn ! - stableNeighbor ! - switchStabilityCounter ! ! \param l2_src [in] MAC source address of the packet, i.e. the neighbor who sent ! the packet just received. ! \param rssi [in] RSSI with which this packet was received. ! \param asnTs [in] ASN at which this packet was received. ! */ ! void neighbors_indicateRx(open_addr_t* l2_src, ! int8_t rssi, ! asn_t* asnTs) { ! uint8_t i; ! bool newNeighbor; ! ! // update existing neighbor ! newNeighbor = TRUE; ! for (i=0;iBADNEIGHBORMAXRSSI) { ! neighbors_vars.neighbors[i].switchStabilityCounter++; ! if (neighbors_vars.neighbors[i].switchStabilityCounter>=SWITCHSTABILITYTHRESHOLD) { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! neighbors_vars.neighbors[i].stableNeighbor=TRUE; ! } ! } else { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! } ! } else if (neighbors_vars.neighbors[i].stableNeighbor==TRUE) { ! if (neighbors_vars.neighbors[i].rssi=SWITCHSTABILITYTHRESHOLD) { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! neighbors_vars.neighbors[i].stableNeighbor=FALSE; ! } ! } else { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! } ! } ! ! // stop looping ! break; ! } ! } ! ! // register new neighbor ! if (newNeighbor==TRUE) { ! registerNewNeighbor(l2_src, rssi, asnTs); ! } ! } ! ! /** ! \brief Indicate some packet was sent to some neighbor. ! ! This function should be called for each transmitted (non-ACK) packet so ! neighbor statistics in the neighbor table can be updated. ! ! The fields which are updated are: ! - numTx ! - numTxACK ! - asn ! ! \param l2_dest [in] MAC destination address of the packet, i.e. the neighbor ! who I just sent the packet to. ! \param numTxAttempts [in] Number of transmission attempts to this neighbor. ! \param was_finally_acked [in] TRUE iff the packet was ACK'ed by the neighbor ! on final transmission attempt. ! \param asnTs [in] ASN of the last transmission attempt. ! */ ! void neighbors_indicateTx(open_addr_t* l2_dest, ! uint8_t numTxAttempts, ! bool was_finally_acked, ! asn_t* asnTs) { ! uint8_t i; ! // don't run through this function if packet was sent to broadcast address ! if (packetfunctions_isBroadcastMulticast(l2_dest)==TRUE) { ! return; ! } ! ! // loop through neighbor table ! for (i=0;i(0xff-numTxAttempts)) { ! neighbors_vars.neighbors[i].numWraps++; //counting the number of times that tx wraps. ! neighbors_vars.neighbors[i].numTx/=2; ! neighbors_vars.neighbors[i].numTxACK/=2; ! } ! // update statistics ! neighbors_vars.neighbors[i].numTx += numTxAttempts; ! ! if (was_finally_acked==TRUE) { ! neighbors_vars.neighbors[i].numTxACK++; ! memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t)); ! } ! break; ! } ! } ! } ! ! /** ! \brief Indicate I just received a RPL DIO from a neighbor. ! ! This function should be called for each received a DIO is received so neighbor ! routing information in the neighbor table can be updated. ! ! The fields which are updated are: ! - DAGrank ! ! \param msg [in] The received message with msg->payload pointing to the DIO ! header. ! */ ! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg) { ! uint8_t i; ! ! // take ownership over the packet ! msg->owner = COMPONENT_NEIGHBORS; ! ! // update rank of that neighbor in table ! neighbors_vars.dio = (icmpv6rpl_dio_ht*)(msg->payload); ! if (isNeighbor(&(msg->l2_nextORpreviousHop))==TRUE) { ! for (i=0;il2_nextORpreviousHop),i)) { ! if ( ! neighbors_vars.dio->rank>neighbors_vars.neighbors[i].DAGrank && ! neighbors_vars.dio->rank - neighbors_vars.neighbors[i].DAGrank>DEFAULTLINKCOST ! ) { ! // the new DAGrank looks suspiciously high, only increment a bit ! neighbors_vars.neighbors[i].DAGrank += DEFAULTLINKCOST; ! openserial_printError(COMPONENT_NEIGHBORS,ERR_LARGE_DAGRANK, ! (errorparameter_t)neighbors_vars.dio->rank, ! (errorparameter_t)neighbors_vars.neighbors[i].DAGrank); ! } else { ! neighbors_vars.neighbors[i].DAGrank = neighbors_vars.dio->rank; ! } ! break; ! } ! } ! } ! // update my routing information ! neighbors_updateMyDAGrankAndNeighborPreference(); ! } ! ! //===== write addresses ! ! /** ! \brief Write the 64-bit address of some neighbor to some location. ! ! */ ! ! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index){ ! switch(addr_type) { ! case ADDR_64B: ! memcpy(&(address->addr_64b),&(neighbors_vars.neighbors[index].addr_64b.addr_64b),LENGTH_ADDR64b); ! address->type=ADDR_64B; ! break; ! default: ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)addr_type, ! (errorparameter_t)1); ! break; ! } ! } ! ! ! //===== managing routing info ! ! /** ! \brief Update my DAG rank and neighbor preference. ! ! Call this function whenever some data is changed that could cause this mote's ! routing decisions to change. Examples are: ! - I received a DIO which updated by neighbor table. If this DIO indicated a ! very low DAGrank, I may want to change by routing parent. ! - I became a DAGroot, so my DAGrank should be 0. ! */ ! void neighbors_updateMyDAGrankAndNeighborPreference() { ! uint8_t i; ! uint8_t linkCost; ! uint32_t tentativeDAGrank; // 32-bit since is used to sum ! uint8_t prefParentIdx; ! bool prefParentFound; ! ! // if I'm a DAGroot, my DAGrank is always 0 ! if ((idmanager_getIsDAGroot())==TRUE) { ! neighbors_vars.myDAGrank=0; ! return; ! } ! ! // reset my DAG rank to max value. May be lowered below. ! neighbors_vars.myDAGrank = MAXDAGRANK; ! ! // by default, I haven't found a preferred parent ! prefParentFound = FALSE; ! prefParentIdx = 0; ! ! // loop through neighbor table, update myDAGrank ! for (i=0;itype!=ADDR_64B) { ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)2); ! return; ! } ! // add this neighbor ! if (isNeighbor(address)==FALSE) { ! i=0; ! while(itype) { ! case ADDR_64B: ! return neighbors_vars.neighbors[rowNumber].used && ! packetfunctions_sameAddress(address,&neighbors_vars.neighbors[rowNumber].addr_64b); ! default: ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)3); ! return FALSE; ! } ! } --- 1,693 ---- ! #include "openwsn.h" ! #include "neighbors.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "idmanager.h" ! #include "openserial.h" ! #include "IEEE802154E.h" ! ! //=========================== variables ======================================= ! ! neighbors_vars_t neighbors_vars; ! ! //=========================== prototypes ====================================== ! ! void registerNewNeighbor( ! open_addr_t* neighborID, ! int8_t rssi, ! asn_t* asnTimestamp, ! bool joinPrioPresent, ! uint8_t joinPrio ! ); ! bool isNeighbor(open_addr_t* neighbor); ! void removeNeighbor(uint8_t neighborIndex); ! bool isThisRowMatching( ! open_addr_t* address, ! uint8_t rowNumber ! ); ! ! //=========================== public ========================================== ! ! /** ! \brief Initializes this module. ! */ ! void neighbors_init(void) { ! ! // clear module variables ! memset(&neighbors_vars,0,sizeof(neighbors_vars_t)); ! ! // set myDAGrank ! if (idmanager_getIsDAGroot()==TRUE) { ! neighbors_vars.myDAGrank=0; ! } else { ! neighbors_vars.myDAGrank=DEFAULTDAGRANK; ! } ! } ! ! //===== getters ! ! /** ! \brief Retrieve this mote's current DAG rank. ! ! \returns This mote's current DAG rank. ! */ ! dagrank_t neighbors_getMyDAGrank(void) { ! return neighbors_vars.myDAGrank; ! } ! ! /** ! \brief Retrieve the number of neighbors this mote's currently knows of. ! ! \returns The number of neighbors this mote's currently knows of. ! */ ! uint8_t neighbors_getNumNeighbors(void) { ! uint8_t i; ! uint8_t returnVal; ! ! returnVal=0; ! for (i=0;itype = ADDR_NONE; ! ! foundPreferred = FALSE; ! numNeighbors = 0; ! minRankVal = MAXDAGRANK; ! minRankIdx = MAXNUMNEIGHBORS+1; ! ! //===== step 1. Try to find preferred parent ! for (i=0; itype=ADDR_64B; ! foundPreferred=TRUE; ! } ! // identify neighbor with lowest rank ! if (neighbors_vars.neighbors[i].DAGrank < minRankVal) { ! minRankVal=neighbors_vars.neighbors[i].DAGrank; ! minRankIdx=i; ! } ! numNeighbors++; ! } ! } ! ! //===== step 2. (backup) Promote neighbor with min rank to preferred parent ! if (foundPreferred==FALSE && numNeighbors > 0){ ! // promote neighbor ! neighbors_vars.neighbors[minRankIdx].parentPreference = MAXPREFERENCE; ! neighbors_vars.neighbors[minRankIdx].stableNeighbor = TRUE; ! neighbors_vars.neighbors[minRankIdx].switchStabilityCounter = 0; ! // return its address ! memcpy(addressToWrite,&(neighbors_vars.neighbors[minRankIdx].addr_64b),sizeof(open_addr_t)); ! addressToWrite->type=ADDR_64B; ! foundPreferred=TRUE; ! } ! ! return foundPreferred; ! } ! ! /** ! \brief Find neighbor to which to send KA. ! ! This function iterates through the neighbor table and identifies the neighbor ! we need to send a KA to, if any. This neighbor satisfies the following ! conditions: ! - it is one of our preferred parents ! - we haven't heard it for over KATIMEOUT ! ! \returns A pointer to the neighbor's address, or NULL if no KA is needed. ! */ ! open_addr_t* neighbors_getKANeighbor(void) { ! uint8_t i; ! uint16_t timeSinceHeard; ! open_addr_t* addrPreferred; ! open_addr_t* addrOther; ! ! // initialize ! addrPreferred = NULL; ! addrOther = NULL; ! ! // scan through the neighbor table, and populate addrPreferred and addrOther ! for (i=0;iKATIMEOUT) { ! // this neighbor needs to be KA'ed to ! if (neighbors_vars.neighbors[i].parentPreference==MAXPREFERENCE) { ! // its a preferred parent ! addrPreferred = &(neighbors_vars.neighbors[i].addr_64b); ! } else { ! // its not a preferred parent ! // Note: commented out since policy is not to KA to non-preferred parents ! // addrOther = &(neighbors_vars.neighbors[i].addr_64b); ! } ! } ! } ! } ! ! // return the addr of the most urgent KA to send: ! // - if available, preferred parent ! // - if not, non preferred parent ! if (addrPreferred!=NULL) { ! return addrPreferred; ! } else if (addrOther!=NULL) { ! return addrOther; ! } else { ! return NULL; ! } ! } ! ! ! //===== interrogators ! ! /** ! \brief Indicate whether some neighbor is a stable neighbor ! ! \param[in] address The address of the neighbor, a full 128-bit IPv6 addres. ! ! \returns TRUE if that neighbor is stable, FALSE otherwise. ! */ ! bool neighbors_isStableNeighbor(open_addr_t* address) { ! uint8_t i; ! open_addr_t temp_addr_64b; ! open_addr_t temp_prefix; ! bool returnVal; ! ! // by default, not stable ! returnVal = FALSE; ! ! // but neighbor's IPv6 address in prefix and EUI64 ! switch (address->type) { ! case ADDR_128B: ! packetfunctions_ip128bToMac64b(address,&temp_prefix,&temp_addr_64b); ! break; ! default: ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)0); ! return returnVal; ! } ! ! // iterate through neighbor table ! for (i=0;i= neighbors_getMyDAGrank()) { ! returnVal = TRUE; ! } else { ! returnVal = FALSE; ! } ! ! return returnVal; ! } ! ! //===== updating neighbor information ! ! /** ! \brief Indicate some (non-ACK) packet was received from a neighbor. ! ! This function should be called for each received (non-ACK) packet so neighbor ! statistics in the neighbor table can be updated. ! ! The fields which are updated are: ! - numRx ! - rssi ! - asn ! - stableNeighbor ! - switchStabilityCounter ! ! \param[in] l2_src MAC source address of the packet, i.e. the neighbor who sent ! the packet just received. ! \param[in] rssi RSSI with which this packet was received. ! \param[in] asnTs ASN at which this packet was received. ! */ ! void neighbors_indicateRx(open_addr_t* l2_src, ! int8_t rssi, ! asn_t* asnTs, ! bool joinPrioPresent, ! uint8_t joinPrio) { ! uint8_t i; ! bool newNeighbor; ! ! // update existing neighbor ! newNeighbor = TRUE; ! for (i=0;iBADNEIGHBORMAXRSSI) { ! neighbors_vars.neighbors[i].switchStabilityCounter++; ! if (neighbors_vars.neighbors[i].switchStabilityCounter>=SWITCHSTABILITYTHRESHOLD) { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! neighbors_vars.neighbors[i].stableNeighbor=TRUE; ! } ! } else { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! } ! } else if (neighbors_vars.neighbors[i].stableNeighbor==TRUE) { ! if (neighbors_vars.neighbors[i].rssi=SWITCHSTABILITYTHRESHOLD) { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! neighbors_vars.neighbors[i].stableNeighbor=FALSE; ! } ! } else { ! neighbors_vars.neighbors[i].switchStabilityCounter=0; ! } ! } ! ! // stop looping ! break; ! } ! } ! ! // register new neighbor ! if (newNeighbor==TRUE) { ! registerNewNeighbor(l2_src, rssi, asnTs, joinPrioPresent,joinPrio); ! } ! } ! ! /** ! \brief Indicate some packet was sent to some neighbor. ! ! This function should be called for each transmitted (non-ACK) packet so ! neighbor statistics in the neighbor table can be updated. ! ! The fields which are updated are: ! - numTx ! - numTxACK ! - asn ! ! \param[in] l2_dest MAC destination address of the packet, i.e. the neighbor ! who I just sent the packet to. ! \param[in] numTxAttempts Number of transmission attempts to this neighbor. ! \param[in] was_finally_acked TRUE iff the packet was ACK'ed by the neighbor ! on final transmission attempt. ! \param[in] asnTs ASN of the last transmission attempt. ! */ ! void neighbors_indicateTx(open_addr_t* l2_dest, ! uint8_t numTxAttempts, ! bool was_finally_acked, ! asn_t* asnTs) { ! uint8_t i; ! // don't run through this function if packet was sent to broadcast address ! if (packetfunctions_isBroadcastMulticast(l2_dest)==TRUE) { ! return; ! } ! ! // loop through neighbor table ! for (i=0;i(0xff-numTxAttempts)) { ! neighbors_vars.neighbors[i].numWraps++; //counting the number of times that tx wraps. ! neighbors_vars.neighbors[i].numTx/=2; ! neighbors_vars.neighbors[i].numTxACK/=2; ! } ! // update statistics ! neighbors_vars.neighbors[i].numTx += numTxAttempts; ! ! if (was_finally_acked==TRUE) { ! neighbors_vars.neighbors[i].numTxACK++; ! memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t)); ! } ! break; ! } ! } ! } ! ! /** ! \brief Indicate I just received a RPL DIO from a neighbor. ! ! This function should be called for each received a DIO is received so neighbor ! routing information in the neighbor table can be updated. ! ! The fields which are updated are: ! - DAGrank ! ! \param[in] msg The received message with msg->payload pointing to the DIO ! header. ! */ ! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg) { ! uint8_t i; ! ! // take ownership over the packet ! msg->owner = COMPONENT_NEIGHBORS; ! ! // update rank of that neighbor in table ! neighbors_vars.dio = (icmpv6rpl_dio_ht*)(msg->payload); ! if (isNeighbor(&(msg->l2_nextORpreviousHop))==TRUE) { ! for (i=0;il2_nextORpreviousHop),i)) { ! if ( ! neighbors_vars.dio->rank > neighbors_vars.neighbors[i].DAGrank && ! neighbors_vars.dio->rank - neighbors_vars.neighbors[i].DAGrank >(DEFAULTLINKCOST*2*MINHOPRANKINCREASE) ! ) { ! // the new DAGrank looks suspiciously high, only increment a bit ! neighbors_vars.neighbors[i].DAGrank += (DEFAULTLINKCOST*2*MINHOPRANKINCREASE); ! openserial_printError(COMPONENT_NEIGHBORS,ERR_LARGE_DAGRANK, ! (errorparameter_t)neighbors_vars.dio->rank, ! (errorparameter_t)neighbors_vars.neighbors[i].DAGrank); ! } else { ! neighbors_vars.neighbors[i].DAGrank = neighbors_vars.dio->rank; ! } ! break; ! } ! } ! } ! // update my routing information ! neighbors_updateMyDAGrankAndNeighborPreference(); ! } ! ! //===== write addresses ! ! /** ! \brief Write the 64-bit address of some neighbor to some location. ! ! */ ! ! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index){ ! switch(addr_type) { ! case ADDR_64B: ! memcpy(&(address->addr_64b),&(neighbors_vars.neighbors[index].addr_64b.addr_64b),LENGTH_ADDR64b); ! address->type=ADDR_64B; ! break; ! default: ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)addr_type, ! (errorparameter_t)1); ! break; ! } ! } ! ! ! //===== managing routing info ! ! /** ! \brief Update my DAG rank and neighbor preference. ! ! Call this function whenever some data is changed that could cause this mote's ! routing decisions to change. Examples are: ! - I received a DIO which updated by neighbor table. If this DIO indicated a ! very low DAGrank, I may want to change by routing parent. ! - I became a DAGroot, so my DAGrank should be 0. ! */ ! void neighbors_updateMyDAGrankAndNeighborPreference(void) { ! uint8_t i; ! uint16_t rankIncrease; ! uint32_t tentativeDAGrank; // 32-bit since is used to sum ! uint8_t prefParentIdx; ! bool prefParentFound; ! ! // if I'm a DAGroot, my DAGrank is always 0 ! if ((idmanager_getIsDAGroot())==TRUE) { ! neighbors_vars.myDAGrank=0; ! return; ! } ! ! // reset my DAG rank to max value. May be lowered below. ! neighbors_vars.myDAGrank = MAXDAGRANK; ! ! // by default, I haven't found a preferred parent ! prefParentFound = FALSE; ! prefParentIdx = 0; ! ! // loop through neighbor table, update myDAGrank ! for (i=0;itype!=ADDR_64B) { ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)2); ! return; ! } ! // add this neighbor ! if (isNeighbor(address)==FALSE) { ! i=0; ! while(itype) { ! case ADDR_64B: ! return neighbors_vars.neighbors[rowNumber].used && ! packetfunctions_sameAddress(address,&neighbors_vars.neighbors[rowNumber].addr_64b); ! default: ! openserial_printCritical(COMPONENT_NEIGHBORS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)3); ! return FALSE; ! } ! } diff -crB openwsn/02b-MAChigh/neighbors.h ../../../sys/net/openwsn/02b-MAChigh/neighbors.h *** openwsn/02b-MAChigh/neighbors.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02b-MAChigh/neighbors.h Wed Jan 15 13:48:26 2014 *************** *** 1,103 **** ! #ifndef __NEIGHBORS_H ! #define __NEIGHBORS_H ! ! /** ! \addtogroup MAChigh ! \{ ! \addtogroup Neighbors ! \{ ! */ ! #include "openwsn.h" ! #include "icmpv6rpl.h" ! ! //=========================== define ========================================== ! ! #define MAXNUMNEIGHBORS 10 ! #define MAXPREFERENCE 2 ! #define BADNEIGHBORMAXRSSI -80 //dBm ! #define GOODNEIGHBORMINRSSI -90 //dBm ! #define SWITCHSTABILITYTHRESHOLD 3 ! #define DEFAULTLINKCOST 15 ! ! #define MAXDAGRANK 0xffff ! #define DEFAULTDAGRANK MAXDAGRANK ! ! //=========================== typedef ========================================= ! ! PRAGMA(pack(1)); ! typedef struct { ! bool used; ! uint8_t parentPreference; ! bool stableNeighbor; ! uint8_t switchStabilityCounter; ! open_addr_t addr_64b; ! dagrank_t DAGrank; ! int8_t rssi; ! uint8_t numRx; ! uint8_t numTx; ! uint8_t numTxACK; ! uint8_t numWraps;//number of times the tx counter wraps. can be removed if memory is a restriction. also check openvisualizer then. ! asn_t asn; ! } neighborRow_t; ! PRAGMA(pack()); ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t row; ! neighborRow_t neighborEntry; ! } debugNeighborEntry_t; ! PRAGMA(pack()); ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t last_addr_byte; // last byte of the neighbor's address ! int8_t rssi; ! uint8_t parentPreference; ! dagrank_t DAGrank; ! uint16_t asn; ! } netDebugNeigborEntry_t; ! PRAGMA(pack()); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void neighbors_init(); ! // getters ! dagrank_t neighbors_getMyDAGrank(); ! uint8_t neighbors_getNumNeighbors(); ! bool neighbors_getPreferredParentEui64(open_addr_t* addressToWrite); ! open_addr_t* neighbors_getKANeighbor(); ! // interrogators ! bool neighbors_isStableNeighbor(open_addr_t* address); ! bool neighbors_isPreferredParent(open_addr_t* address); ! bool neighbors_isNeighborWithLowerDAGrank(uint8_t index); ! bool neighbors_isNeighborWithHigherDAGrank(uint8_t index); ! ! // updating neighbor information ! void neighbors_indicateRx( ! open_addr_t* l2_src, ! int8_t rssi, ! asn_t* asnTimestamp ! ); ! void neighbors_indicateTx( ! open_addr_t* dest, ! uint8_t numTxAttempts, ! bool was_finally_acked, ! asn_t* asnTimestamp ! ); ! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg); ! // get addresses ! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index); ! // managing routing info ! void neighbors_updateMyDAGrankAndNeighborPreference(); ! // debug ! bool debugPrint_neighbors(); ! void debugNetPrint_neighbors(netDebugNeigborEntry_t* schlist); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,116 ---- ! #ifndef __NEIGHBORS_H ! #define __NEIGHBORS_H ! ! /** ! \addtogroup MAChigh ! \{ ! \addtogroup Neighbors ! \{ ! */ ! #include "openwsn.h" ! #include "icmpv6rpl.h" ! ! //=========================== define ========================================== ! ! #define MAXNUMNEIGHBORS 10 ! #define MAXPREFERENCE 2 ! #define BADNEIGHBORMAXRSSI -80 //dBm ! #define GOODNEIGHBORMINRSSI -90 //dBm ! #define SWITCHSTABILITYTHRESHOLD 3 ! #define DEFAULTLINKCOST 15 ! ! #define MAXDAGRANK 0xffff ! #define DEFAULTDAGRANK MAXDAGRANK ! #define MINHOPRANKINCREASE 256 //default value in RPL and Minimal 6TiSCH draft ! ! //=========================== typedef ========================================= ! ! //PRAGMA(pack(1)); ! typedef struct { ! bool used; ! uint8_t parentPreference; ! bool stableNeighbor; ! uint8_t switchStabilityCounter; ! open_addr_t addr_64b; ! dagrank_t DAGrank; ! int8_t rssi; ! uint8_t numRx; ! uint8_t numTx; ! uint8_t numTxACK; ! uint8_t numWraps;//number of times the tx counter wraps. can be removed if memory is a restriction. also check openvisualizer then. ! asn_t asn; ! uint8_t joinPrio; ! } neighborRow_t; ! //PRAGMA(pack()); ! ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t row; ! neighborRow_t neighborEntry; ! } debugNeighborEntry_t; ! //PRAGMA(pack()); ! ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t last_addr_byte; // last byte of the neighbor's address ! int8_t rssi; ! uint8_t parentPreference; ! dagrank_t DAGrank; ! uint16_t asn; ! } netDebugNeigborEntry_t; ! //PRAGMA(pack()); ! ! //=========================== module variables ================================ ! ! typedef struct { ! neighborRow_t neighbors[MAXNUMNEIGHBORS]; ! dagrank_t myDAGrank; ! uint8_t debugRow; ! icmpv6rpl_dio_ht* dio; //keep it global to be able to debug correctly. ! } neighbors_vars_t; ! ! //=========================== prototypes ====================================== ! ! void neighbors_init(void); ! // getters ! dagrank_t neighbors_getMyDAGrank(void); ! uint8_t neighbors_getNumNeighbors(void); ! bool neighbors_getPreferredParentEui64(open_addr_t* addressToWrite); ! open_addr_t* neighbors_getKANeighbor(void); ! ! // interrogators ! bool neighbors_isStableNeighbor(open_addr_t* address); ! bool neighbors_isPreferredParent(open_addr_t* address); ! bool neighbors_isNeighborWithLowerDAGrank(uint8_t index); ! bool neighbors_isNeighborWithHigherDAGrank(uint8_t index); ! ! // updating neighbor information ! void neighbors_indicateRx( ! open_addr_t* l2_src, ! int8_t rssi, ! asn_t* asnTimestamp, ! bool joinPrioPresent, ! uint8_t joinPrio ! ); ! ! void neighbors_indicateTx( ! open_addr_t* dest, ! uint8_t numTxAttempts, ! bool was_finally_acked, ! asn_t* asnTimestamp ! ); ! void neighbors_indicateRxDIO(OpenQueueEntry_t* msg); ! // get addresses ! void neighbors_getNeighbor(open_addr_t* address,uint8_t addr_type,uint8_t index); ! // managing routing info ! void neighbors_updateMyDAGrankAndNeighborPreference(void); ! // debug ! bool debugPrint_neighbors(void); ! void debugNetPrint_neighbors(netDebugNeigborEntry_t* schlist); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/02b-MAChigh/res.c ../../../sys/net/openwsn/02b-MAChigh/res.c *** openwsn/02b-MAChigh/res.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02b-MAChigh/res.c Wed Jan 15 13:48:26 2014 *************** *** 1,355 **** ! #include "openwsn.h" ! #include "res.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "neighbors.h" ! #include "IEEE802154E.h" ! #include "iphc.h" ! #include "packetfunctions.h" ! #include "openrandom.h" ! #include "scheduler.h" ! #include "opentimers.h" ! #include "debugpins.h" ! //=========================== variables ======================================= ! ! typedef struct { ! uint16_t periodMaintenance; ! bool busySendingKa; // TRUE when busy sending a keep-alive ! bool busySendingAdv; // TRUE when busy sending an advertisement ! uint8_t dsn; // current data sequence number ! uint8_t MacMgtTaskCounter; // counter to determine what management task to do ! opentimer_id_t timerId; ! } res_vars_t; ! ! res_vars_t res_vars; ! ! //=========================== prototypes ====================================== ! ! error_t res_send_internal(OpenQueueEntry_t* msg); ! void sendAdv(); ! void sendKa(); ! void res_timer_cb(); ! ! //=========================== public ========================================== ! ! void res_init() { ! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); // fires every 1 sec on average ! res_vars.busySendingKa = FALSE; ! res_vars.busySendingAdv = FALSE; ! res_vars.dsn = 0; ! res_vars.MacMgtTaskCounter = 0; ! res_vars.timerId = opentimers_start(res_vars.periodMaintenance, ! TIMER_PERIODIC,TIME_MS, ! res_timer_cb); ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_myDAGrank() { ! uint8_t output=0; ! output = neighbors_getMyDAGrank(); ! openserial_printStatus(STATUS_DAGRANK,(uint8_t*)&output,sizeof(uint8_t)); ! return TRUE; ! } ! ! //======= from upper layer ! ! error_t res_send(OpenQueueEntry_t *msg) { ! msg->owner = COMPONENT_RES; ! msg->l2_frameType = IEEE154_TYPE_DATA; ! return res_send_internal(msg); ! } ! ! //======= from lower layer ! ! void task_resNotifSendDone() { ! OpenQueueEntry_t* msg; ! // get recently-sent packet from openqueue ! msg = openqueue_resGetSentPacket(); ! if (msg==NULL) { ! // log the error ! openserial_printCritical(COMPONENT_RES,ERR_NO_SENT_PACKET, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! return; ! } ! // declare it as mine ! msg->owner = COMPONENT_RES; ! // indicate transmission (to update statistics) ! if (msg->l2_sendDoneError==E_SUCCESS) { ! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), ! msg->l2_numTxAttempts, ! TRUE, ! &msg->l2_asn); ! } else { ! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), ! msg->l2_numTxAttempts, ! FALSE, ! &msg->l2_asn); ! } ! // send the packet to where it belongs ! if (msg->creator == COMPONENT_RES) { ! if (msg->l2_frameType==IEEE154_TYPE_BEACON) { ! // this is a ADV ! ! // not busy sending ADV anymore ! res_vars.busySendingAdv = FALSE; ! } else { ! // this is a KA ! ! // not busy sending KA anymore ! res_vars.busySendingKa = FALSE; ! } ! // discard packets ! openqueue_freePacketBuffer(msg); ! // restart a random timer ! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); ! opentimers_setPeriod(res_vars.timerId, ! TIME_MS, ! res_vars.periodMaintenance); ! } else { ! // send the rest up the stack ! iphc_sendDone(msg,msg->l2_sendDoneError); ! } ! } ! ! void task_resNotifReceive() { ! OpenQueueEntry_t* msg; ! ! // get received packet from openqueue ! msg = openqueue_resGetReceivedPacket(); ! if (msg==NULL) { ! // log the error ! openserial_printCritical(COMPONENT_RES,ERR_NO_RECEIVED_PACKET, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! return; ! } ! ! // declare it as mine ! msg->owner = COMPONENT_RES; ! ! // indicate reception (to update statistics) ! neighbors_indicateRx(&(msg->l2_nextORpreviousHop), ! msg->l1_rssi, ! &msg->l2_asn); ! ! // send the packet up the stack, if it qualifies ! switch (msg->l2_frameType) { ! case IEEE154_TYPE_BEACON: ! case IEEE154_TYPE_DATA: ! case IEEE154_TYPE_CMD: ! if (msg->length>0) { ! // send to upper layer ! iphc_receive(msg); ! } else { ! // free up the RAM ! openqueue_freePacketBuffer(msg); ! } ! break; ! case IEEE154_TYPE_ACK: ! default: ! // free the packet's RAM memory ! openqueue_freePacketBuffer(msg); ! // log the error ! openserial_printError(COMPONENT_RES,ERR_MSG_UNKNOWN_TYPE, ! (errorparameter_t)msg->l2_frameType, ! (errorparameter_t)0); ! break; ! } ! } ! ! //======= timer ! ! /** ! \brief Timer handlers which triggers MAC management task. ! ! This function is called in task context by the scheduler after the RES timer ! has fired. This timer is set to fire every second, on average. ! ! The body of this function executes one of the MAC management task. ! */ ! void timers_res_fired() { ! res_vars.MacMgtTaskCounter = (res_vars.MacMgtTaskCounter+1)%10; ! if (res_vars.MacMgtTaskCounter==0) { ! sendAdv(); // called every 10s ! } else { ! sendKa(); // called every second, except once every 10s ! } ! } ! ! //=========================== private ========================================= ! ! /** ! \brief Transfer packet to MAC. ! ! This function adds a IEEE802.15.4 header to the packet and leaves it the ! OpenQueue buffer. The very last thing it does is assigning this packet to the ! virtual component COMPONENT_RES_TO_IEEE802154E. Whenever it gets a change, ! IEEE802154E will handle the packet. ! ! \param [in] msg The packet to the transmitted ! ! \returns E_SUCCESS iff successful. ! */ ! error_t res_send_internal(OpenQueueEntry_t* msg) { ! // assign a number of retries ! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { ! msg->l2_retriesLeft = 1; ! } else { ! msg->l2_retriesLeft = TXRETRIES; ! } ! // record this packet's dsn (for matching the ACK) ! msg->l2_dsn = res_vars.dsn++; ! // this is a new packet which I never attempted to send ! msg->l2_numTxAttempts = 0; ! // transmit with the default TX power ! msg->l1_txPower = TX_POWER; ! // record the location, in the packet, where the l2 payload starts ! msg->l2_payload = msg->payload; ! // add a IEEE802.15.4 header ! ieee802154_prependHeader(msg, ! msg->l2_frameType, ! IEEE154_SEC_NO_SECURITY, ! msg->l2_dsn, ! &(msg->l2_nextORpreviousHop) ! ); ! // reserve space for 2-byte CRC ! packetfunctions_reserveFooterSize(msg,2); ! // change owner to IEEE802154E fetches it from queue ! msg->owner = COMPONENT_RES_TO_IEEE802154E; ! return E_SUCCESS; ! } ! ! /** ! \brief Send an advertisement. ! ! This is one of the MAC managament tasks. This function inlines in the ! timers_res_fired() function, but is declared as a separate function for better ! readability of the code. ! */ ! port_INLINE void sendAdv() { ! OpenQueueEntry_t* adv; ! ! if (ieee154e_isSynch()==FALSE) { ! // I'm not sync'ed ! ! // delete packets genereted by this module (ADV and KA) from openqueue ! openqueue_removeAllCreatedBy(COMPONENT_RES); ! ! // I'm now busy sending an ADV ! res_vars.busySendingAdv = FALSE; ! ! // stop here ! return; ! } ! ! if (res_vars.busySendingAdv==TRUE) { ! // don't continue if I'm still sending a previous ADV ! } ! ! // if I get here, I will send an ADV ! ! // get a free packet buffer ! adv = openqueue_getFreePacketBuffer(COMPONENT_RES); ! if (adv==NULL) { ! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return; ! } ! ! // declare ownership over that packet ! adv->creator = COMPONENT_RES; ! adv->owner = COMPONENT_RES; ! ! // reserve space for ADV-specific header ! packetfunctions_reserveHeaderSize(adv, ADV_PAYLOAD_LENGTH); ! // the actual value of the current ASN will be written by the ! // IEEE802.15.4e when transmitting ! ! // some l2 information about this packet ! adv->l2_frameType = IEEE154_TYPE_BEACON; ! adv->l2_nextORpreviousHop.type = ADDR_16B; ! adv->l2_nextORpreviousHop.addr_16b[0] = 0xff; ! adv->l2_nextORpreviousHop.addr_16b[1] = 0xff; ! ! // put in queue for MAC to handle ! res_send_internal(adv); ! ! // I'm now busy sending an ADV ! res_vars.busySendingAdv = TRUE; ! } ! ! /** ! \brief Send an keep-alive message, if nessary. ! ! This is one of the MAC managament tasks. This function inlines in the ! timers_res_fired() function, but is declared as a separate function for better ! readability of the code. ! */ ! port_INLINE void sendKa() { ! OpenQueueEntry_t* kaPkt; ! open_addr_t* kaNeighAddr; ! ! if (ieee154e_isSynch()==FALSE) { ! // I'm not sync'ed ! ! // delete packets genereted by this module (ADV and KA) from openqueue ! openqueue_removeAllCreatedBy(COMPONENT_RES); ! ! // I'm now busy sending a KA ! res_vars.busySendingKa = FALSE; ! ! // stop here ! return; ! } ! ! if (res_vars.busySendingKa==TRUE) { ! // don't proceed if I'm still sending a KA ! return; ! } ! ! kaNeighAddr = neighbors_getKANeighbor(); ! if (kaNeighAddr==NULL) { ! // don't proceed if I have no neighbor I need to send a KA to ! return; ! } ! ! // if I get here, I will send a KA ! ! // get a free packet buffer ! kaPkt = openqueue_getFreePacketBuffer(COMPONENT_RES); ! if (kaPkt==NULL) { ! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)1, ! (errorparameter_t)0); ! return; ! } ! ! // declare ownership over that packet ! kaPkt->creator = COMPONENT_RES; ! kaPkt->owner = COMPONENT_RES; ! ! // some l2 information about this packet ! kaPkt->l2_frameType = IEEE154_TYPE_DATA; ! memcpy(&(kaPkt->l2_nextORpreviousHop),kaNeighAddr,sizeof(open_addr_t)); ! ! // put in queue for MAC to handle ! res_send_internal(kaPkt); ! ! // I'm now busy sending a KA ! res_vars.busySendingKa = TRUE; ! } ! ! void res_timer_cb() { ! scheduler_push_task(timers_res_fired,TASKPRIO_RES); } \ No newline at end of file --- 1,463 ---- ! #include "openwsn.h" ! #include "res.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "neighbors.h" ! #include "IEEE802154E.h" ! #include "iphc.h" ! #include "packetfunctions.h" ! #include "openrandom.h" ! #include "scheduler.h" ! #include "opentimers.h" ! //#include "debugpins.h" ! ! #include "thread.h" ! ! ! //=========================== variables ======================================= ! ! res_vars_t res_vars; ! //static char openwsn_res_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! ! //=========================== prototypes ====================================== ! ! owerror_t res_send_internal(OpenQueueEntry_t* msg, uint8_t iePresent,uint8_t frameVersion); ! void sendAdv(void); ! void sendKa(void); ! void res_timer_cb(void); ! uint8_t res_copySlotFrameAndLinkIE(OpenQueueEntry_t* adv);//returns reserved size ! ! //=========================== public ========================================== ! ! void res_init(void) { ! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); // fires every 1 sec on average ! res_vars.busySendingKa = FALSE; ! res_vars.busySendingAdv = FALSE; ! res_vars.dsn = 0; ! res_vars.MacMgtTaskCounter = 0; ! res_vars.timerId = opentimers_start(res_vars.periodMaintenance, ! TIMER_PERIODIC,TIME_MS, ! res_timer_cb); ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! // TODO: was bool but complained "conflicting types" ! uint8_t debugPrint_myDAGrank(void) { ! uint16_t output=0; ! output = neighbors_getMyDAGrank(); ! openserial_printStatus(STATUS_DAGRANK,(uint8_t*)&output,sizeof(uint16_t)); ! return TRUE; ! } ! ! //======= from upper layer ! ! owerror_t res_send(OpenQueueEntry_t *msg) { ! msg->owner = COMPONENT_RES; ! msg->l2_frameType = IEEE154_TYPE_DATA; ! return res_send_internal(msg,IEEE154_IELIST_NO,IEEE154_FRAMEVERSION_2006); ! } ! ! //======= from lower layer ! ! void task_resNotifSendDone(void) { ! OpenQueueEntry_t* msg; ! // get recently-sent packet from openqueue ! msg = openqueue_resGetSentPacket(); ! if (msg==NULL) { ! // log the error ! openserial_printCritical(COMPONENT_RES,ERR_NO_SENT_PACKET, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! return; ! } ! // declare it as mine ! msg->owner = COMPONENT_RES; ! // indicate transmission (to update statistics) ! if (msg->l2_sendDoneError==E_SUCCESS) { ! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), ! msg->l2_numTxAttempts, ! TRUE, ! &msg->l2_asn); ! } else { ! neighbors_indicateTx(&(msg->l2_nextORpreviousHop), ! msg->l2_numTxAttempts, ! FALSE, ! &msg->l2_asn); ! } ! // send the packet to where it belongs ! if (msg->creator == COMPONENT_RES) { ! if (msg->l2_frameType==IEEE154_TYPE_BEACON) { ! // this is a ADV ! ! // not busy sending ADV anymore ! res_vars.busySendingAdv = FALSE; ! } else { ! // this is a KA ! ! // not busy sending KA anymore ! res_vars.busySendingKa = FALSE; ! } ! // discard packets ! openqueue_freePacketBuffer(msg); ! // restart a random timer ! res_vars.periodMaintenance = 872+(openrandom_get16b()&0xff); ! opentimers_setPeriod(res_vars.timerId, ! TIME_MS, ! res_vars.periodMaintenance); ! } else { ! // send the rest up the stack ! iphc_sendDone(msg,msg->l2_sendDoneError); ! } ! } ! ! void task_resNotifReceive(void) { ! OpenQueueEntry_t* msg; ! ! // get received packet from openqueue ! msg = openqueue_resGetReceivedPacket(); ! if (msg==NULL) { ! // log the error ! openserial_printCritical(COMPONENT_RES,ERR_NO_RECEIVED_PACKET, ! (errorparameter_t)0, ! (errorparameter_t)0); ! // abort ! return; ! } ! ! // declare it as mine ! msg->owner = COMPONENT_RES; ! ! // indicate reception (to update statistics) ! neighbors_indicateRx(&(msg->l2_nextORpreviousHop), ! msg->l1_rssi, ! &msg->l2_asn, ! msg->l2_joinPriorityPresent, ! msg->l2_joinPriority); ! ! msg->l2_joinPriorityPresent=FALSE; //reset it to avoid race conditions with this var. ! ! // send the packet up the stack, if it qualifies ! switch (msg->l2_frameType) { ! case IEEE154_TYPE_BEACON: ! case IEEE154_TYPE_DATA: ! case IEEE154_TYPE_CMD: ! if (msg->length>0) { ! // send to upper layer ! iphc_receive(msg); ! } else { ! // free up the RAM ! openqueue_freePacketBuffer(msg); ! } ! break; ! case IEEE154_TYPE_ACK: ! default: ! // free the packet's RAM memory ! openqueue_freePacketBuffer(msg); ! // log the error ! openserial_printError(COMPONENT_RES,ERR_MSG_UNKNOWN_TYPE, ! (errorparameter_t)msg->l2_frameType, ! (errorparameter_t)0); ! break; ! } ! } ! ! //======= timer ! ! /** ! \brief Timer handlers which triggers MAC management task. ! ! This function is called in task context by the scheduler after the RES timer ! has fired. This timer is set to fire every second, on average. ! ! The body of this function executes one of the MAC management task. ! */ ! void timers_res_fired(void) { ! res_vars.MacMgtTaskCounter = (res_vars.MacMgtTaskCounter+1)%10; ! if (res_vars.MacMgtTaskCounter==0) { ! sendAdv(); // called every 10s ! } else { ! sendKa(); // called every second, except once every 10s ! //leds_debug_toggle(); ! } ! } ! ! //=========================== private ========================================= ! ! /** ! \brief Transfer packet to MAC. ! ! This function adds a IEEE802.15.4 header to the packet and leaves it the ! OpenQueue buffer. The very last thing it does is assigning this packet to the ! virtual component COMPONENT_RES_TO_IEEE802154E. Whenever it gets a change, ! IEEE802154E will handle the packet. ! ! \param[in] msg The packet to the transmitted ! ! \returns E_SUCCESS iff successful. ! */ ! owerror_t res_send_internal(OpenQueueEntry_t* msg, uint8_t iePresent, uint8_t frameVersion) { ! // assign a number of retries ! if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) { ! msg->l2_retriesLeft = 1; ! } else { ! msg->l2_retriesLeft = TXRETRIES; ! } ! // record this packet's dsn (for matching the ACK) ! msg->l2_dsn = res_vars.dsn++; ! // this is a new packet which I never attempted to send ! msg->l2_numTxAttempts = 0; ! // transmit with the default TX power ! msg->l1_txPower = TX_POWER; ! // record the location, in the packet, where the l2 payload starts ! msg->l2_payload = msg->payload; ! // add a IEEE802.15.4 header ! ieee802154_prependHeader(msg, ! msg->l2_frameType, ! iePresent, ! frameVersion, ! IEEE154_SEC_NO_SECURITY, ! msg->l2_dsn, ! &(msg->l2_nextORpreviousHop) ! ); ! // reserve space for 2-byte CRC ! packetfunctions_reserveFooterSize(msg,2); ! // change owner to IEEE802154E fetches it from queue ! msg->owner = COMPONENT_RES_TO_IEEE802154E; ! return E_SUCCESS; ! } ! ! /** ! \brief Send an advertisement. ! ! This is one of the MAC managament tasks. This function inlines in the ! timers_res_fired() function, but is declared as a separate function for better ! readability of the code. ! */ ! port_INLINE void sendAdv(void) { ! OpenQueueEntry_t* adv; ! payload_IE_descriptor_t payload_IE_desc; ! MLME_IE_subHeader_t mlme_subHeader; ! uint8_t slotframeIElen=0; ! ! if (ieee154e_isSynch()==FALSE) { ! // I'm not sync'ed ! ! // delete packets genereted by this module (ADV and KA) from openqueue ! openqueue_removeAllCreatedBy(COMPONENT_RES); ! ! // I'm now busy sending an ADV ! res_vars.busySendingAdv = FALSE; ! ! // stop here ! return; ! } ! ! if (res_vars.busySendingAdv==TRUE) { ! // don't continue if I'm still sending a previous ADV ! } ! ! // if I get here, I will send an ADV ! ! // get a free packet buffer ! adv = openqueue_getFreePacketBuffer(COMPONENT_RES); ! if (adv==NULL) { ! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return; ! } ! ! // declare ownership over that packet ! adv->creator = COMPONENT_RES; ! adv->owner = COMPONENT_RES; ! ! // reserve space for ADV-specific header ! // xv poipoi -- reserving for IEs -- reverse order. ! //TODO reserve here for slotframe and link IE with minimal schedule information ! slotframeIElen = res_copySlotFrameAndLinkIE(adv); ! //create Sync IE with JP and ASN ! packetfunctions_reserveHeaderSize(adv, sizeof(synch_IE_t));//the asn + jp ! adv->l2_ASNpayload = adv->payload; //keep a pointer to where the ASN should be. ! // the actual value of the current ASN and JP will be written by the ! // IEEE802.15.4e when transmitting ! packetfunctions_reserveHeaderSize(adv, sizeof(MLME_IE_subHeader_t));//the MLME header ! //copy mlme sub-header ! mlme_subHeader.length_subID_type=sizeof(synch_IE_t) << IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; ! mlme_subHeader.length_subID_type |= (IEEE802154E_MLME_SYNC_IE_SUBID << IEEE802154E_MLME_SYNC_IE_SUBID_SHIFT) | IEEE802154E_DESC_TYPE_SHORT; ! //little endian ! adv->payload[0]= mlme_subHeader.length_subID_type & 0xFF; ! adv->payload[1]= (mlme_subHeader.length_subID_type >> 8) & 0xFF; ! ! packetfunctions_reserveHeaderSize(adv, sizeof(payload_IE_descriptor_t));//the payload IE header ! //prepare IE headers and copy them to the ADV ! ! payload_IE_desc.length_groupid_type = (sizeof(MLME_IE_subHeader_t)+sizeof(synch_IE_t)+slotframeIElen)<payload[0]= payload_IE_desc.length_groupid_type & 0xFF; ! adv->payload[1]= (payload_IE_desc.length_groupid_type >> 8) & 0xFF; ! ! // some l2 information about this packet ! adv->l2_frameType = IEEE154_TYPE_BEACON; ! adv->l2_nextORpreviousHop.type = ADDR_16B; ! adv->l2_nextORpreviousHop.addr_16b[0] = 0xff; ! adv->l2_nextORpreviousHop.addr_16b[1] = 0xff; ! ! // put in queue for MAC to handle ! res_send_internal(adv,IEEE154_IELIST_YES,IEEE154_FRAMEVERSION); ! ! // I'm now busy sending an ADV ! res_vars.busySendingAdv = TRUE; ! } ! ! port_INLINE uint8_t res_copySlotFrameAndLinkIE(OpenQueueEntry_t* adv){ ! MLME_IE_subHeader_t mlme_subHeader; ! uint8_t len=0; ! uint8_t linkOption=0; ! uint16_t slot=SCHEDULE_MINIMAL_6TISCH_ACTIVE_CELLS+SCHEDULE_MINIMAL_6TISCH_EB_CELLS; ! ! //reverse order and little endian. -- ! ! //for each link in the schedule (in basic configuration) ! //copy to adv 1B linkOption bitmap ! //copy to adv 2B ch.offset ! //copy to adv 2B timeslot ! ! //shared cells ! linkOption = (1<SCHEDULE_MINIMAL_6TISCH_EB_CELLS){ ! packetfunctions_reserveHeaderSize(adv,5); ! //ts ! adv->payload[0]= slot & 0xFF; ! adv->payload[1]= (slot >> 8) & 0xFF; ! //ch.offset as minimal draft ! adv->payload[2]= 0x00; ! adv->payload[3]= 0x00; ! //linkOption ! adv->payload[4]= linkOption; ! len+=5; ! slot--; ! } ! ! //eb slot ! linkOption = (1<payload[0]= SCHEDULE_MINIMAL_6TISCH_EB_CELLS & 0xFF; ! adv->payload[1]= (SCHEDULE_MINIMAL_6TISCH_EB_CELLS >> 8) & 0xFF; ! //ch.offset as minimal draft ! adv->payload[2]= 0x00; ! adv->payload[3]= 0x00; ! ! adv->payload[4]= linkOption; ! //now slotframe ie general fields ! //1B number of links == 6 ! //Slotframe Size 2B = 101 timeslots ! //1B slotframe handle (id) ! packetfunctions_reserveHeaderSize(adv,5);// ! len+=5; ! ! adv->payload[0]= SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_NUMBER; ! adv->payload[1]= SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE; ! adv->payload[2]= SCHEDULE_MINIMAL_6TISCH_SLOTFRAME_SIZE & 0xFF; ! adv->payload[3]= (SCHEDULE_MINIMAL_6TISCH_SLOTFRAME_SIZE >> 8) & 0xFF; ! adv->payload[4]= 0x06; //number of links ! ! //MLME sub IE header ! //1b -15 short ==0x00 ! //7b -8-14 Sub-ID=0x1b ! //8b - Length = 2 mlme-header + 5 slotframe general header +(6links*5bytes each) ! packetfunctions_reserveHeaderSize(adv, sizeof(MLME_IE_subHeader_t));//the MLME header ! ! ! //copy mlme sub-header ! mlme_subHeader.length_subID_type = len << IEEE802154E_DESC_LEN_SHORT_MLME_IE_SHIFT; ! mlme_subHeader.length_subID_type |= (IEEE802154E_MLME_SLOTFRAME_LINK_IE_SUBID << IEEE802154E_MLME_SYNC_IE_SUBID_SHIFT) | IEEE802154E_DESC_TYPE_SHORT; ! ! //little endian ! adv->payload[0]= mlme_subHeader.length_subID_type & 0xFF; ! adv->payload[1]= (mlme_subHeader.length_subID_type >> 8) & 0xFF; ! len+=2;//count len of mlme header ! ! return len; ! } ! ! /** ! \brief Send an keep-alive message, if nessary. ! ! This is one of the MAC managament tasks. This function inlines in the ! timers_res_fired() function, but is declared as a separate function for better ! readability of the code. ! */ ! port_INLINE void sendKa(void) { ! OpenQueueEntry_t* kaPkt; ! open_addr_t* kaNeighAddr; ! ! if (ieee154e_isSynch()==FALSE) { ! // I'm not sync'ed ! ! // delete packets genereted by this module (ADV and KA) from openqueue ! openqueue_removeAllCreatedBy(COMPONENT_RES); ! ! // I'm now busy sending a KA ! res_vars.busySendingKa = FALSE; ! ! // stop here ! return; ! } ! ! if (res_vars.busySendingKa==TRUE) { ! // don't proceed if I'm still sending a KA ! return; ! } ! ! kaNeighAddr = neighbors_getKANeighbor(); ! if (kaNeighAddr==NULL) { ! // don't proceed if I have no neighbor I need to send a KA to ! return; ! } ! ! // if I get here, I will send a KA ! ! // get a free packet buffer ! kaPkt = openqueue_getFreePacketBuffer(COMPONENT_RES); ! if (kaPkt==NULL) { ! openserial_printError(COMPONENT_RES,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)1, ! (errorparameter_t)0); ! return; ! } ! ! // declare ownership over that packet ! kaPkt->creator = COMPONENT_RES; ! kaPkt->owner = COMPONENT_RES; ! ! // some l2 information about this packet ! kaPkt->l2_frameType = IEEE154_TYPE_DATA; ! memcpy(&(kaPkt->l2_nextORpreviousHop),kaNeighAddr,sizeof(open_addr_t)); ! ! // put in queue for MAC to handle ! res_send_internal(kaPkt,IEEE154_IELIST_NO,IEEE154_FRAMEVERSION_2006); ! ! // I'm now busy sending a KA ! res_vars.busySendingKa = TRUE; ! } ! ! void res_timer_cb(void) { ! puts(__PRETTY_FUNCTION__); ! scheduler_push_task(timers_res_fired,TASKPRIO_RES); ! /*thread_create(openwsn_res_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_RES, CREATE_STACKTEST, ! timers_res_fired, "timers res fired");*/ } \ No newline at end of file diff -crB openwsn/02b-MAChigh/res.h ../../../sys/net/openwsn/02b-MAChigh/res.h *** openwsn/02b-MAChigh/res.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02b-MAChigh/res.h Wed Jan 15 13:48:26 2014 *************** *** 1,32 **** ! #ifndef __RES_H ! #define __RES_H ! ! /** ! \addtogroup MAChigh ! \{ ! \addtogroup RES ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void res_init(); ! bool debugPrint_myDAGrank(); ! // from upper layer ! error_t res_send(OpenQueueEntry_t *msg); ! // from lower layer ! void task_resNotifSendDone(); ! void task_resNotifReceive(); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,42 ---- ! #ifndef __RES_H ! #define __RES_H ! ! /** ! \addtogroup MAChigh ! \{ ! \addtogroup RES ! \{ ! */ ! #include "opentimers.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== module variables ================================ ! ! typedef struct { ! uint16_t periodMaintenance; ! bool busySendingKa; // TRUE when busy sending a keep-alive ! bool busySendingAdv; // TRUE when busy sending an advertisement ! uint8_t dsn; // current data sequence number ! uint8_t MacMgtTaskCounter; // counter to determine what management task to do ! opentimer_id_t timerId; ! } res_vars_t; ! ! //=========================== prototypes ====================================== ! ! void res_init(void); ! uint8_t debugPrint_myDAGrank(void); // TODO: was bool but complained "conflicting types" ! // from upper layer ! owerror_t res_send(OpenQueueEntry_t *msg); ! // from lower layer ! void task_resNotifSendDone(void); ! void task_resNotifReceive(void); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/02b-MAChigh/schedule.c ../../../sys/net/openwsn/02b-MAChigh/schedule.c *** openwsn/02b-MAChigh/schedule.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02b-MAChigh/schedule.c Wed Jan 15 13:48:26 2014 *************** *** 1,476 **** ! #include "openwsn.h" ! #include "schedule.h" ! #include "openserial.h" ! #include "openrandom.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! scheduleEntry_t scheduleBuf[MAXACTIVESLOTS]; ! scheduleEntry_t* currentScheduleEntry; ! uint16_t frameLength; ! uint8_t backoffExponent; ! uint8_t backoff; ! slotOffset_t debugPrintRow; ! } schedule_vars_t; ! ! schedule_vars_t schedule_vars; ! ! typedef struct { ! uint8_t numActiveSlotsCur; ! uint8_t numActiveSlotsMax; ! } schedule_dbg_t; ! ! schedule_dbg_t schedule_dbg; ! ! //=========================== prototypes ====================================== ! ! void schedule_resetEntry(scheduleEntry_t* pScheduleEntry); ! ! //=========================== public ========================================== ! ! //=== admin ! ! void schedule_init() { ! uint8_t i; ! slotOffset_t running_slotOffset; ! open_addr_t temp_neighbor; ! ! // reset local variables ! memset(&schedule_vars,0,sizeof(schedule_vars_t)); ! for (i=0;itype!=CELLTYPE_OFF && ! slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { ! slotContainer++; ! } ! if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { ! // schedule has overflown ! openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! // fill that schedule entry with parameters passed ! slotContainer->slotOffset = slotOffset; ! slotContainer->type = type; ! slotContainer->shared = shared; ! slotContainer->channelOffset = channelOffset; ! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t)); ! ! if (schedule_vars.currentScheduleEntry==NULL) { ! // this is the first active slot added ! ! // the next slot of this slot is this slot ! slotContainer->next = slotContainer; ! ! // current slot points to this slot ! schedule_vars.currentScheduleEntry = slotContainer; ! } else { ! // this is NOT the first active slot added ! ! // find position in schedule ! previousSlotWalker = schedule_vars.currentScheduleEntry; ! while (1) { ! nextSlotWalker = previousSlotWalker->next; ! if ( ! ( ! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && ! (slotContainer->slotOffset < nextSlotWalker->slotOffset) ! ) ! || ! ( ! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && ! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) ! ) ! || ! ( ! (slotContainer->slotOffset < nextSlotWalker->slotOffset) && ! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) ! ) ! ) { ! break; ! } ! previousSlotWalker = nextSlotWalker; ! } ! // insert between previousSlotWalker and nextSlotWalker ! previousSlotWalker->next = slotContainer; ! slotContainer->next = nextSlotWalker; ! } ! ! // maintain debug stats ! schedule_dbg.numActiveSlotsCur++; ! if (schedule_dbg.numActiveSlotsCur>schedule_dbg.numActiveSlotsMax) { ! schedule_dbg.numActiveSlotsMax = schedule_dbg.numActiveSlotsCur; ! } ! ENABLE_INTERRUPTS(); ! } ! ! //=== from IEEE802154E: reading the schedule and updating statistics ! ! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! while (schedule_vars.currentScheduleEntry->slotOffset!=targetSlotOffset) { ! schedule_advanceSlot(); ! } ! ENABLE_INTERRUPTS(); ! } ! ! void schedule_advanceSlot() { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! // advance to next active slot ! schedule_vars.currentScheduleEntry = schedule_vars.currentScheduleEntry->next; ! ENABLE_INTERRUPTS(); ! } ! ! slotOffset_t schedule_getNextActiveSlotOffset() { ! slotOffset_t res; ! INTERRUPT_DECLARATION(); ! ! // return next active slot's slotOffset ! DISABLE_INTERRUPTS(); ! res = ((scheduleEntry_t*)(schedule_vars.currentScheduleEntry->next))->slotOffset; ! ENABLE_INTERRUPTS(); ! ! return res; ! } ! ! /** ! \brief Get the frame length. ! ! \returns The frame length. ! */ ! frameLength_t schedule_getFrameLength() { ! frameLength_t res; ! INTERRUPT_DECLARATION(); ! ! DISABLE_INTERRUPTS(); ! res= schedule_vars.frameLength; ! ENABLE_INTERRUPTS(); ! ! return res; ! } ! ! /** ! \brief Get the type of the current schedule entry. ! ! \returns The type of the current schedule entry. ! */ ! cellType_t schedule_getType() { ! cellType_t res; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! res= schedule_vars.currentScheduleEntry->type; ! ENABLE_INTERRUPTS(); ! return res; ! } ! ! /** ! \brief Get the neighbor associated wit the current schedule entry. ! ! \returns The neighbor associated wit the current schedule entry. ! */ ! void schedule_getNeighbor(open_addr_t* addrToWrite) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! memcpy(addrToWrite,&(schedule_vars.currentScheduleEntry->neighbor),sizeof(open_addr_t)); ! ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Get the channel offset of the current schedule entry. ! ! \returns The channel offset of the current schedule entry. ! */ ! channelOffset_t schedule_getChannelOffset() { ! channelOffset_t res; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! res= schedule_vars.currentScheduleEntry->channelOffset; ! ENABLE_INTERRUPTS(); ! return res; ! } ! ! /** ! \brief Check whether I can send on this slot. ! ! This function is called at the beginning of every TX slot. ! If the slot is *not* a shared slot, it always return TRUE. ! If the slot is a shared slot, it decrements the backoff counter and returns ! TRUE only if it hits 0. ! ! Note that the backoff counter is global, not per slot. ! ! \returns TRUE if it is OK to send on this slot, FALSE otherwise. ! */ ! bool schedule_getOkToSend() { ! bool returnVal; ! ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! ! if (schedule_vars.currentScheduleEntry->shared==FALSE) { ! // non-shared slot: backoff does not apply ! ! returnVal = TRUE; ! } else { ! // non-shared slot: check backoff before answering ! ! // decrement backoff ! if (schedule_vars.backoff>0) { ! schedule_vars.backoff--; ! } ! ! // only return TRUE if backoff hit 0 ! if (schedule_vars.backoff==0) { ! returnVal = TRUE; ! } else { ! returnVal = FALSE; ! } ! } ! ! ENABLE_INTERRUPTS(); ! return returnVal; ! } ! ! /** ! \brief Reset the backoff and backoffExponent. ! */ ! void schedule_resetBackoff() { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! ! // reset backoffExponent ! schedule_vars.backoffExponent = MINBE-1; ! // reset backoff ! schedule_vars.backoff = 0; ! ! ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Indicate the reception of a packet. ! */ ! void schedule_indicateRx(asn_t* asnTimestamp) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! // increment usage statistics ! schedule_vars.currentScheduleEntry->numRx++; ! ! // update last used timestamp ! memcpy(&(schedule_vars.currentScheduleEntry->lastUsedAsn), asnTimestamp, sizeof(asn_t)); ! ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Indicate the transmission of a packet. ! */ ! void schedule_indicateTx(asn_t* asnTimestamp, ! bool succesfullTx) { ! ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! // increment usage statistics ! if (schedule_vars.currentScheduleEntry->numTx==0xFF) { ! schedule_vars.currentScheduleEntry->numTx/=2; ! schedule_vars.currentScheduleEntry->numTxACK/=2; ! } ! schedule_vars.currentScheduleEntry->numTx++; ! if (succesfullTx==TRUE) { ! schedule_vars.currentScheduleEntry->numTxACK++; ! } ! ! // update last used timestamp ! memcpy(&schedule_vars.currentScheduleEntry->lastUsedAsn, asnTimestamp, sizeof(asn_t)); ! ! // update this backoff parameters for shared slots ! if (schedule_vars.currentScheduleEntry->shared==TRUE) { ! if (succesfullTx==TRUE) { ! // reset backoffExponent ! schedule_vars.backoffExponent = MINBE-1; ! // reset backoff ! schedule_vars.backoff = 0; ! } else { ! // increase the backoffExponent ! if (schedule_vars.backoffExponenttype = CELLTYPE_OFF; ! pScheduleEntry->shared = FALSE; ! pScheduleEntry->channelOffset = 0; ! pScheduleEntry->neighbor.type = ADDR_NONE; ! pScheduleEntry->neighbor.addr_64b[0] = 0x14; ! pScheduleEntry->neighbor.addr_64b[1] = 0x15; ! pScheduleEntry->neighbor.addr_64b[2] = 0x92; ! pScheduleEntry->neighbor.addr_64b[3] = 0x09; ! pScheduleEntry->neighbor.addr_64b[4] = 0x02; ! pScheduleEntry->neighbor.addr_64b[5] = 0x2c; ! pScheduleEntry->neighbor.addr_64b[6] = 0x00; ! pScheduleEntry->numRx = 0; ! pScheduleEntry->numTx = 0; ! pScheduleEntry->numTxACK = 0; ! pScheduleEntry->lastUsedAsn.bytes0and1 = 0; ! pScheduleEntry->lastUsedAsn.bytes2and3 = 0; ! pScheduleEntry->lastUsedAsn.byte4 = 0; ! } --- 1,621 ---- ! #include "openwsn.h" ! #include "schedule.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "packetfunctions.h" ! ! //=========================== variables ======================================= ! ! schedule_vars_t schedule_vars; ! schedule_dbg_t schedule_dbg; ! ! //=========================== prototypes ====================================== ! ! void schedule_resetEntry(scheduleEntry_t* pScheduleEntry); ! ! //=========================== public ========================================== ! ! //=== admin ! ! void schedule_init(void) { ! uint8_t i; ! slotOffset_t running_slotOffset; ! open_addr_t temp_neighbor; ! ! // reset local variables ! memset(&schedule_vars,0,sizeof(schedule_vars_t)); ! for (i=0;itype!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { ! //check that this entry for that neighbour and timeslot is not already scheduled. ! if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){ ! //it exists so this is an update. ! info->link_type = slotContainer->type; ! info->shared =slotContainer->shared; ! info->channelOffset = slotContainer->channelOffset; ! return; //as this is an update. No need to re-insert as it is in the same position on the list. ! } ! slotContainer++; ! } ! //return cell type off. ! info->link_type = CELLTYPE_OFF; ! info->shared = FALSE; ! info->channelOffset = 0;//set to zero if not set. ! } ! ! /** ! \brief Add a new active slot into the schedule. ! ! If udpate param is set then update it in case it exists. ! ! \param slotOffset ! \param type ! \param shared ! \param channelOffset ! \param neighbor ! \param isUpdate ! */ ! owerror_t schedule_addActiveSlot( ! slotOffset_t slotOffset, ! cellType_t type, ! bool shared, ! channelOffset_t channelOffset, ! open_addr_t* neighbor, ! bool isUpdate ! ) { ! ! owerror_t outcome; ! ! scheduleEntry_t* slotContainer; ! scheduleEntry_t* previousSlotWalker; ! scheduleEntry_t* nextSlotWalker; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! ! ! // find an empty schedule entry container ! slotContainer = &schedule_vars.scheduleBuf[0]; ! while (slotContainer->type!=CELLTYPE_OFF && ! slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { ! ! //check that this entry for that neighbour and timeslot is not already scheduled. ! if (type!=CELLTYPE_SERIALRX && type!=CELLTYPE_MORESERIALRX && ! (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))|| ! (slotContainer->neighbor.type==ADDR_ANYCAST && isUpdate==TRUE)) ! &&(slotContainer->slotOffset==slotOffset)){ ! //it exists so this is an update. ! slotContainer->type = type; ! slotContainer->shared = shared; ! slotContainer->channelOffset = channelOffset; ! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t));//update the address too! ! schedule_dbg.numUpdatedSlotsCur++; ! ENABLE_INTERRUPTS(); ! return E_SUCCESS; //as this is an update. No need to re-insert as it is in the same position on the list. ! } ! ! slotContainer++; ! } ! ! if (isUpdate==TRUE) { ! //we are trying to update an item that is not in the schedule list. ! ENABLE_INTERRUPTS(); ! return E_FAIL; ! } ! if (slotContainer>&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { ! // schedule has overflown ! outcome=E_FAIL; ! openserial_printCritical(COMPONENT_SCHEDULE,ERR_SCHEDULE_OVERFLOWN, ! (errorparameter_t)0, ! (errorparameter_t)0); ! ! ! } ! // fill that schedule entry with parameters passed ! slotContainer->slotOffset = slotOffset; ! slotContainer->type = type; ! slotContainer->shared = shared; ! slotContainer->channelOffset = channelOffset; ! memcpy(&slotContainer->neighbor,neighbor,sizeof(open_addr_t)); ! ! if (schedule_vars.currentScheduleEntry==NULL) { ! // this is the first active slot added ! ! // the next slot of this slot is this slot ! slotContainer->next = slotContainer; ! ! // current slot points to this slot ! schedule_vars.currentScheduleEntry = slotContainer; ! } else { ! // this is NOT the first active slot added ! ! // find position in schedule ! previousSlotWalker = schedule_vars.currentScheduleEntry; ! while (1) { ! nextSlotWalker = previousSlotWalker->next; ! if ( ! ( ! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && ! (slotContainer->slotOffset < nextSlotWalker->slotOffset) ! ) ! || ! ( ! (previousSlotWalker->slotOffset < slotContainer->slotOffset) && ! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) ! ) ! || ! ( ! (slotContainer->slotOffset < nextSlotWalker->slotOffset) && ! (nextSlotWalker->slotOffset <= previousSlotWalker->slotOffset) ! ) ! ) { ! break; ! } ! previousSlotWalker = nextSlotWalker; ! } ! // insert between previousSlotWalker and nextSlotWalker ! previousSlotWalker->next = slotContainer; ! slotContainer->next = nextSlotWalker; ! } ! ! // maintain debug stats ! schedule_dbg.numActiveSlotsCur++; ! if (schedule_dbg.numActiveSlotsCur>schedule_dbg.numActiveSlotsMax) { ! schedule_dbg.numActiveSlotsMax = schedule_dbg.numActiveSlotsCur; ! } ! outcome=E_SUCCESS; ! ENABLE_INTERRUPTS(); ! return outcome; ! } ! ! ! ! owerror_t schedule_removeActiveSlot(slotOffset_t slotOffset, open_addr_t* neighbor){ ! ! owerror_t outcome; ! ! scheduleEntry_t* slotContainer; ! scheduleEntry_t* previousSlotWalker; ! ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! ! ! // find the schedule entry ! slotContainer = &schedule_vars.scheduleBuf[0]; ! while (slotContainer->type!=CELLTYPE_OFF && slotContainer<=&schedule_vars.scheduleBuf[MAXACTIVESLOTS-1]) { ! //check that this entry for that neighbour and timeslot is not already scheduled. ! if (packetfunctions_sameAddress(neighbor,&(slotContainer->neighbor))&& (slotContainer->slotOffset==slotOffset)){ ! break; ! } ! slotContainer++; ! } ! ! if (slotContainer->next==slotContainer) { ! // this is the last active slot ! ! // the next slot of this slot is NULL ! slotContainer->next = NULL; ! ! // current slot points to this slot ! schedule_vars.currentScheduleEntry = NULL; ! } else { ! // this is NOT the last active slot ! ! // find the previous in the schedule ! previousSlotWalker = schedule_vars.currentScheduleEntry; ! ! while (1) { ! if ((previousSlotWalker->next=slotContainer)){ ! break; ! } ! previousSlotWalker = previousSlotWalker->next; ! } ! // remove this element from the linked list ! previousSlotWalker->next = slotContainer->next;//my next; ! slotContainer->next = NULL; ! } ! ! // clear that schedule entry ! slotContainer->slotOffset = 0; ! slotContainer->type = CELLTYPE_OFF; ! slotContainer->shared = FALSE; ! slotContainer->channelOffset = 0; ! memset(&slotContainer->neighbor,0,sizeof(open_addr_t)); ! ! // maintain debug stats ! schedule_dbg.numActiveSlotsCur--; ! ! outcome=E_SUCCESS; ! ENABLE_INTERRUPTS(); ! ! return outcome; ! } ! ! ! ! ! //=== from IEEE802154E: reading the schedule and updating statistics ! ! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! while (schedule_vars.currentScheduleEntry->slotOffset!=targetSlotOffset) { ! schedule_advanceSlot(); ! } ! ENABLE_INTERRUPTS(); ! } ! ! void schedule_advanceSlot(void) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! // advance to next active slot ! schedule_vars.currentScheduleEntry = schedule_vars.currentScheduleEntry->next; ! ENABLE_INTERRUPTS(); ! } ! ! slotOffset_t schedule_getNextActiveSlotOffset(void) { ! slotOffset_t res; ! INTERRUPT_DECLARATION(); ! ! // return next active slot's slotOffset ! DISABLE_INTERRUPTS(); ! res = ((scheduleEntry_t*)(schedule_vars.currentScheduleEntry->next))->slotOffset; ! ENABLE_INTERRUPTS(); ! ! return res; ! } ! ! /** ! \brief Get the frame length. ! ! \returns The frame length. ! */ ! frameLength_t schedule_getFrameLength(void) { ! frameLength_t res; ! INTERRUPT_DECLARATION(); ! ! DISABLE_INTERRUPTS(); ! res= schedule_vars.frameLength; ! ENABLE_INTERRUPTS(); ! ! return res; ! } ! ! /** ! \brief Get the type of the current schedule entry. ! ! \returns The type of the current schedule entry. ! */ ! cellType_t schedule_getType(void) { ! cellType_t res; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! res= schedule_vars.currentScheduleEntry->type; ! ENABLE_INTERRUPTS(); ! return res; ! } ! ! /** ! \brief Get the neighbor associated wit the current schedule entry. ! ! \returns The neighbor associated wit the current schedule entry. ! */ ! void schedule_getNeighbor(open_addr_t* addrToWrite) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! memcpy(addrToWrite,&(schedule_vars.currentScheduleEntry->neighbor),sizeof(open_addr_t)); ! ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Get the channel offset of the current schedule entry. ! ! \returns The channel offset of the current schedule entry. ! */ ! channelOffset_t schedule_getChannelOffset(void) { ! channelOffset_t res; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! res= schedule_vars.currentScheduleEntry->channelOffset; ! ENABLE_INTERRUPTS(); ! return res; ! } ! ! /** ! \brief Check whether I can send on this slot. ! ! This function is called at the beginning of every TX slot. ! If the slot is *not* a shared slot, it always return TRUE. ! If the slot is a shared slot, it decrements the backoff counter and returns ! TRUE only if it hits 0. ! ! Note that the backoff counter is global, not per slot. ! ! \returns TRUE if it is OK to send on this slot, FALSE otherwise. ! */ ! bool schedule_getOkToSend(void) { ! bool returnVal; ! ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! ! if (schedule_vars.currentScheduleEntry->shared==FALSE) { ! // non-shared slot: backoff does not apply ! ! returnVal = TRUE; ! } else { ! // non-shared slot: check backoff before answering ! ! // decrement backoff ! if (schedule_vars.backoff>0) { ! schedule_vars.backoff--; ! } ! ! // only return TRUE if backoff hit 0 ! if (schedule_vars.backoff==0) { ! returnVal = TRUE; ! } else { ! returnVal = FALSE; ! } ! } ! ! ENABLE_INTERRUPTS(); ! return returnVal; ! } ! ! /** ! \brief Reset the backoff and backoffExponent. ! */ ! void schedule_resetBackoff(void) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! ! // reset backoffExponent ! schedule_vars.backoffExponent = MINBE-1; ! // reset backoff ! schedule_vars.backoff = 0; ! ! ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Indicate the reception of a packet. ! */ ! void schedule_indicateRx(asn_t* asnTimestamp) { ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! // increment usage statistics ! schedule_vars.currentScheduleEntry->numRx++; ! ! // update last used timestamp ! memcpy(&(schedule_vars.currentScheduleEntry->lastUsedAsn), asnTimestamp, sizeof(asn_t)); ! ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Indicate the transmission of a packet. ! */ ! void schedule_indicateTx(asn_t* asnTimestamp, ! bool succesfullTx) { ! ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! // increment usage statistics ! if (schedule_vars.currentScheduleEntry->numTx==0xFF) { ! schedule_vars.currentScheduleEntry->numTx/=2; ! schedule_vars.currentScheduleEntry->numTxACK/=2; ! } ! schedule_vars.currentScheduleEntry->numTx++; ! if (succesfullTx==TRUE) { ! schedule_vars.currentScheduleEntry->numTxACK++; ! } ! ! // update last used timestamp ! memcpy(&schedule_vars.currentScheduleEntry->lastUsedAsn, asnTimestamp, sizeof(asn_t)); ! ! // update this backoff parameters for shared slots ! if (schedule_vars.currentScheduleEntry->shared==TRUE) { ! if (succesfullTx==TRUE) { ! // reset backoffExponent ! schedule_vars.backoffExponent = MINBE-1; ! // reset backoff ! schedule_vars.backoff = 0; ! } else { ! // increase the backoffExponent ! if (schedule_vars.backoffExponenttype = CELLTYPE_OFF; ! pScheduleEntry->shared = FALSE; ! pScheduleEntry->channelOffset = 0; ! ! pScheduleEntry->neighbor.type = ADDR_NONE; ! memset(&pScheduleEntry->neighbor.addr_64b[0], 0x00, sizeof(pScheduleEntry->neighbor.addr_64b)); ! ! pScheduleEntry->numRx = 0; ! pScheduleEntry->numTx = 0; ! pScheduleEntry->numTxACK = 0; ! pScheduleEntry->lastUsedAsn.bytes0and1 = 0; ! pScheduleEntry->lastUsedAsn.bytes2and3 = 0; ! pScheduleEntry->lastUsedAsn.byte4 = 0; ! } diff -crB openwsn/02b-MAChigh/schedule.h ../../../sys/net/openwsn/02b-MAChigh/schedule.h *** openwsn/02b-MAChigh/schedule.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/02b-MAChigh/schedule.h Wed Jan 15 13:48:26 2014 *************** *** 1,158 **** ! #ifndef __SCHEDULE_H ! #define __SCHEDULE_H ! ! /** ! \addtogroup MAChigh ! \{ ! \addtogroup Schedule ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! /** ! \brief The length of the superframe, in slots. ! ! The superframe repears over time and can be arbitrarly long. ! */ ! #define SUPERFRAME_LENGTH 9 ! ! #define NUMADVSLOTS 1 ! #define NUMSHAREDTXRX 4 ! #define NUMSERIALRX 3 ! ! /** ! \brief Maximum number of active slots in a superframe. ! ! Note that this is merely used to allocate RAM memory for the schedule. The ! schedule is represented, in RAM, by a table. There is one row per active slot ! in that table; a slot is "active" when it is not of type CELLTYPE_OFF. ! ! Set this number to the exact number of active slots you are planning on having ! in your schedule, so not to waste RAM. ! */ ! #define MAXACTIVESLOTS (NUMADVSLOTS+NUMSHAREDTXRX+NUMSERIALRX) ! ! /** ! \brief Minimum backoff exponent. ! ! Backoff is used only in slots that are marked as shared in the schedule. When ! not shared, the mote assumes that schedule is collision-free, and therefore ! does not use any backoff mechanism when a transmission fails. ! */ ! #define MINBE 2 ! ! /** ! \brief Maximum backoff exponent. ! ! See MINBE for an explanation of backoff. ! */ ! #define MAXBE 4 ! ! ! //=========================== typedef ========================================= ! ! typedef uint8_t channelOffset_t; ! typedef uint16_t slotOffset_t; ! typedef uint16_t frameLength_t; ! ! typedef enum { ! CELLTYPE_OFF = 0, ! CELLTYPE_ADV = 1, ! CELLTYPE_TX = 2, ! CELLTYPE_RX = 3, ! CELLTYPE_TXRX = 4, ! CELLTYPE_SERIALRX = 5, ! CELLTYPE_MORESERIALRX = 6 ! } cellType_t; ! ! //not packed as does not fly on the network ! //PRAGMA(pack(1)); ! typedef struct { ! slotOffset_t slotOffset; ! cellType_t type; ! bool shared; ! uint8_t channelOffset; ! open_addr_t neighbor; ! uint8_t numRx; ! uint8_t numTx; ! uint8_t numTxACK; ! asn_t lastUsedAsn; ! void* next; ! } scheduleEntry_t; ! //PRAGMA(pack()); ! ! //copy of the previous one but without the pointer and packed ! PRAGMA(pack(1)); ! typedef struct { ! slotOffset_t slotOffset; ! cellType_t type; ! bool shared; ! uint8_t channelOffset; ! open_addr_t neighbor; ! uint8_t numRx; ! uint8_t numTx; ! uint8_t numTxACK; ! asn_t lastUsedAsn; ! } scheduleEntryDebug_t; ! PRAGMA(pack()); ! ! //used to debug through ipv6 pkt. ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t last_addr_byte;//last byte of the address; poipoi could be [0]; endianness ! uint8_t slotOffset; ! uint8_t channelOffset; ! }netDebugScheduleEntry_t; ! PRAGMA(pack()); ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t row; ! scheduleEntryDebug_t scheduleEntry; ! } debugScheduleEntry_t; ! PRAGMA(pack()); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void schedule_init(); ! bool debugPrint_schedule(); ! bool debugPrint_backoff(); ! // from uRES ! void schedule_setFrameLength(frameLength_t newFrameLength); ! void schedule_addActiveSlot( ! slotOffset_t slotOffset, ! cellType_t type, ! bool shared, ! uint8_t channelOffset, ! open_addr_t* neighbor ! ); ! // from IEEE802154E ! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset); ! void schedule_advanceSlot(); ! slotOffset_t schedule_getNextActiveSlotOffset(); ! frameLength_t schedule_getFrameLength(); ! cellType_t schedule_getType(); ! void schedule_getNeighbor(open_addr_t* addrToWrite); ! channelOffset_t schedule_getChannelOffset(); ! bool schedule_getOkToSend(); ! void schedule_resetBackoff(); ! void schedule_indicateRx(asn_t* asnTimestamp); ! void schedule_indicateTx( ! asn_t* asnTimestamp, ! bool succesfullTx ! ); ! void schedule_getNetDebugInfo(netDebugScheduleEntry_t* schlist); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,189 ---- ! #ifndef __SCHEDULE_H ! #define __SCHEDULE_H ! ! /** ! \addtogroup MAChigh ! \{ ! \addtogroup Schedule ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! /** ! \brief The length of the superframe, in slots. ! ! The superframe repears over time and can be arbitrarly long. ! */ ! #define SUPERFRAME_LENGTH 11 //should be 101 ! ! #define NUMADVSLOTS 1 ! #define NUMSHAREDTXRX 5 ! #define NUMSERIALRX 3 ! ! /** ! \brief Maximum number of active slots in a superframe. ! ! Note that this is merely used to allocate RAM memory for the schedule. The ! schedule is represented, in RAM, by a table. There is one row per active slot ! in that table; a slot is "active" when it is not of type CELLTYPE_OFF. ! ! Set this number to the exact number of active slots you are planning on having ! in your schedule, so not to waste RAM. ! */ ! #define MAXACTIVESLOTS (NUMADVSLOTS+NUMSHAREDTXRX+NUMSERIALRX) ! ! /** ! \brief Minimum backoff exponent. ! ! Backoff is used only in slots that are marked as shared in the schedule. When ! not shared, the mote assumes that schedule is collision-free, and therefore ! does not use any backoff mechanism when a transmission fails. ! */ ! #define MINBE 2 ! ! /** ! \brief Maximum backoff exponent. ! ! See MINBE for an explanation of backoff. ! */ ! #define MAXBE 4 ! //6tisch minimal draft ! #define SCHEDULE_MINIMAL_6TISCH_ACTIVE_CELLS 5 ! #define SCHEDULE_MINIMAL_6TISCH_EB_CELLS 1 ! #define SCHEDULE_MINIMAL_6TISCH_SLOTFRAME_SIZE 101 ! #define SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_HANDLE 1 //id of slotframe ! #define SCHEDULE_MINIMAL_6TISCH_DEFAULT_SLOTFRAME_NUMBER 1 //1 slotframe by default. ! ! //=========================== typedef ========================================= ! ! typedef uint8_t channelOffset_t; ! typedef uint16_t slotOffset_t; ! typedef uint16_t frameLength_t; ! ! typedef enum { ! CELLTYPE_OFF = 0, ! CELLTYPE_ADV = 1, ! CELLTYPE_TX = 2, ! CELLTYPE_RX = 3, ! CELLTYPE_TXRX = 4, ! CELLTYPE_SERIALRX = 5, ! CELLTYPE_MORESERIALRX = 6 ! } cellType_t; ! ! ! //PRAGMA(pack(1)); ! typedef struct { ! slotOffset_t slotOffset; ! cellType_t type; ! bool shared; ! uint8_t channelOffset; ! open_addr_t neighbor; ! uint8_t numRx; ! uint8_t numTx; ! uint8_t numTxACK; ! asn_t lastUsedAsn; ! void* next; ! } scheduleEntry_t; ! //PRAGMA(pack()); ! ! //used to debug through ipv6 pkt. ! ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t last_addr_byte;//last byte of the address; poipoi could be [0]; endianness ! uint8_t slotOffset; ! channelOffset_t channelOffset; ! }netDebugScheduleEntry_t; ! //PRAGMA(pack()); ! ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t row; ! slotOffset_t slotOffset; ! uint8_t type; ! bool shared; ! uint8_t channelOffset; ! open_addr_t neighbor; ! uint8_t numRx; ! uint8_t numTx; ! uint8_t numTxACK; ! asn_t lastUsedAsn; ! } debugScheduleEntry_t; ! //PRAGMA(pack()); ! ! //PRAGMA(pack(1)); //elements for slot info ! typedef struct { ! uint8_t address[LENGTH_ADDR64b];// ! cellType_t link_type;// rx,tx etc... ! bool shared; ! slotOffset_t slotOffset; ! channelOffset_t channelOffset; ! }slotinfo_element_t; ! //PRAGMA(pack()); ! //=========================== variables ======================================= ! ! typedef struct { ! scheduleEntry_t scheduleBuf[MAXACTIVESLOTS]; ! scheduleEntry_t* currentScheduleEntry; ! uint16_t frameLength; ! uint8_t backoffExponent; ! uint8_t backoff; ! slotOffset_t debugPrintRow; ! } schedule_vars_t; ! ! typedef struct { ! uint8_t numActiveSlotsCur; ! uint8_t numActiveSlotsMax; ! uint8_t numUpdatedSlotsCur; ! } schedule_dbg_t; ! ! //=========================== prototypes ====================================== ! ! // admin ! void schedule_init(void); ! bool debugPrint_schedule(void); ! bool debugPrint_backoff(void); ! // from uRES ! void schedule_setFrameLength(frameLength_t newFrameLength); ! owerror_t schedule_addActiveSlot( ! slotOffset_t slotOffset, ! cellType_t type, ! bool shared, ! uint8_t channelOffset, ! open_addr_t* neighbor, ! bool isUpdate); ! ! void schedule_getSlotInfo(slotOffset_t slotOffset, ! open_addr_t* neighbor, ! slotinfo_element_t* info); ! ! owerror_t schedule_removeActiveSlot(slotOffset_t slotOffset, ! open_addr_t* neighbor); ! ! ! // from IEEE802154E ! void schedule_syncSlotOffset(slotOffset_t targetSlotOffset); ! void schedule_advanceSlot(void); ! slotOffset_t schedule_getNextActiveSlotOffset(void); ! frameLength_t schedule_getFrameLength(void); ! cellType_t schedule_getType(void); ! void schedule_getNeighbor(open_addr_t* addrToWrite); ! channelOffset_t schedule_getChannelOffset(void); ! bool schedule_getOkToSend(void); ! void schedule_resetBackoff(void); ! void schedule_indicateRx(asn_t* asnTimestamp); ! void schedule_indicateTx( ! asn_t* asnTimestamp, ! bool succesfullTx ! ); ! void schedule_getNetDebugInfo(netDebugScheduleEntry_t* schlist); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/03a-IPHC/Makefile ../../../sys/net/openwsn/03a-IPHC/Makefile *** openwsn/03a-IPHC/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/03a-IPHC/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) + $(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 + $(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 + #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) + $(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 + $(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;nbrIdxpayload)), ! &(icmpv6rpl_vars.dao_transit), ! sizeof(icmpv6rpl_dao_transit_ht) ! ); ! ! // remember I found it ! numTransitParents++; ! } ! } ! ! //target information is required. RFC 6550 page 55. ! /* ! One or more Transit Information options MUST be preceded by one or ! more RPL Target options. ! */ ! numTargetParents = 0; ! for (nbrIdx=0;nbrIdxpayload)), ! &(icmpv6rpl_vars.dao_target), ! sizeof(icmpv6rpl_dao_target_ht) ! ); ! ! // remember I found it ! numTargetParents++; ! } ! } ! ! ! // stop here if no parents found ! if (numTransitParents==0) { ! openqueue_freePacketBuffer(msg); ! return; ! } ! ! icmpv6rpl_vars.dao_transit.PathSequence++; //increment path sequence. ! // if you get here, you will send a DAO ! ! ! //=== DAO header ! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_ht)); ! memcpy( ! ((icmpv6rpl_dao_ht*)(msg->payload)), ! &(icmpv6rpl_vars.dao), ! sizeof(icmpv6rpl_dao_ht) ! ); ! ! //=== ICMPv6 header ! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); ! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; ! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DAO; ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum)); //call last ! ! //===== send ! if (icmpv6_send(msg)==E_SUCCESS) { ! icmpv6rpl_vars.busySending = TRUE; ! } else { ! openqueue_freePacketBuffer(msg); ! } ! } --- 1,561 ---- ! #include "openwsn.h" ! #include "icmpv6rpl.h" ! #include "icmpv6.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "neighbors.h" ! #include "packetfunctions.h" ! #include "openrandom.h" ! #include "scheduler.h" ! #include "idmanager.h" ! #include "opentimers.h" ! #include "IEEE802154E.h" ! ! #include "thread.h" ! ! //=========================== variables ======================================= ! ! icmpv6rpl_vars_t icmpv6rpl_vars; ! //static char openwsn_icmpv6rpl_DAO_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! //static char openwsn_icmpv6rpl_DIO_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! ! //=========================== prototypes ====================================== ! ! // DIO-related ! void icmpv6rpl_timer_DIO_cb(void); ! void icmpv6rpl_timer_DIO_task(void); ! void sendDIO(void); ! // DAO-related ! void icmpv6rpl_timer_DAO_cb(void); ! void icmpv6rpl_timer_DAO_task(void); ! void sendDAO(void); ! ! //=========================== public ========================================== ! ! /** ! \brief Initialize this module. ! */ ! void icmpv6rpl_init(void) { ! ! //===== reset local variables ! memset(&icmpv6rpl_vars,0,sizeof(icmpv6rpl_vars_t)); ! ! //=== admin ! ! icmpv6rpl_vars.busySending = FALSE; ! icmpv6rpl_vars.DODAGIDFlagSet = 0; ! ! //=== DIO-related ! ! icmpv6rpl_vars.dio.rplinstanceId = 0x00; ///< TODO: put correct value ! icmpv6rpl_vars.dio.verNumb = 0x00; ///< TODO: put correct value ! // rank: to be populated upon TX ! icmpv6rpl_vars.dio.rplOptions = MOP_DIO_A | \ ! MOP_DIO_B | \ ! MOP_DIO_C | \ ! PRF_DIO_A | \ ! PRF_DIO_B | \ ! PRF_DIO_C | \ ! G_DIO ; ! icmpv6rpl_vars.dio.DTSN = 0x33; ///< TODO: put correct value ! icmpv6rpl_vars.dio.flags = 0x00; ! icmpv6rpl_vars.dio.reserved = 0x00; ! // DODAGID: to be populated upon receiving DIO ! ! icmpv6rpl_vars.dioDestination.type = ADDR_128B; ! memcpy(&icmpv6rpl_vars.dioDestination.addr_128b[0],all_routers_multicast,sizeof(all_routers_multicast)); ! ! icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); ! icmpv6rpl_vars.timerIdDIO = opentimers_start( ! icmpv6rpl_vars.periodDIO, ! TIMER_PERIODIC, ! TIME_MS, ! icmpv6rpl_timer_DIO_cb ! ); ! ! //=== DAO-related ! ! icmpv6rpl_vars.dao.rplinstanceId = 0x00; ///< TODO: put correct value ! icmpv6rpl_vars.dao.K_D_flags = FLAG_DAO_A | \ ! FLAG_DAO_B | \ ! FLAG_DAO_C | \ ! FLAG_DAO_D | \ ! FLAG_DAO_E | \ ! PRF_DIO_C | \ ! FLAG_DAO_F | \ ! D_DAO | ! K_DAO; ! icmpv6rpl_vars.dao.reserved = 0x00; ! icmpv6rpl_vars.dao.DAOSequence = 0x00; ! // DODAGID: to be populated upon receiving DIO ! ! icmpv6rpl_vars.dao_transit.type = OPTION_TRANSIT_INFORMATION_TYPE; ! // optionLength: to be populated upon TX ! icmpv6rpl_vars.dao_transit.E_flags = E_DAO_Transit_Info; ! icmpv6rpl_vars.dao_transit.PathControl = PC1_A_DAO_Transit_Info | \ ! PC1_B_DAO_Transit_Info | \ ! PC2_A_DAO_Transit_Info | \ ! PC2_B_DAO_Transit_Info | \ ! PC3_A_DAO_Transit_Info | \ ! PC3_B_DAO_Transit_Info | \ ! PC4_A_DAO_Transit_Info | \ ! PC4_B_DAO_Transit_Info; ! icmpv6rpl_vars.dao_transit.PathSequence = 0x00; // to be incremented at each TX ! icmpv6rpl_vars.dao_transit.PathLifetime = 0xAA; ! //target information ! icmpv6rpl_vars.dao_target.type = OPTION_TARGET_INFORMATION_TYPE; ! icmpv6rpl_vars.dao_target.optionLength = 0; ! icmpv6rpl_vars.dao_target.flags = 0; ! icmpv6rpl_vars.dao_target.prefixLength = 0; ! ! icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); ! icmpv6rpl_vars.timerIdDAO = opentimers_start( ! icmpv6rpl_vars.periodDAO, ! TIMER_PERIODIC, ! TIME_MS, ! icmpv6rpl_timer_DAO_cb ! ); ! ! } ! ! uint8_t icmpv6rpl_getRPLIntanceID(void){ ! return icmpv6rpl_vars.dao.rplinstanceId; ! } ! ! /** ! \brief Called when DIO/DAO was sent. ! ! \param[in] msg Pointer to the message just sent. ! \param[in] error Outcome of the sending. ! */ ! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! ! // take ownership over that packet ! msg->owner = COMPONENT_ICMPv6RPL; ! ! // make sure I created it ! if (msg->creator!=COMPONENT_ICMPv6RPL) { ! openserial_printError(COMPONENT_ICMPv6RPL,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! ! // free packet ! openqueue_freePacketBuffer(msg); ! ! // I'm not busy sending anymore ! icmpv6rpl_vars.busySending = FALSE; ! } ! ! /** ! \brief Called when RPL message received. ! ! \param[in] msg Pointer to the received message. ! */ ! void icmpv6rpl_receive(OpenQueueEntry_t* msg) { ! uint8_t icmpv6code; ! open_addr_t myPrefix; ! ! // take ownership ! msg->owner = COMPONENT_ICMPv6RPL; ! ! // retrieve ICMPv6 code ! icmpv6code = (((ICMPv6_ht*)(msg->payload))->code); ! ! // toss ICMPv6 header ! packetfunctions_tossHeader(msg,sizeof(ICMPv6_ht)); ! ! // handle message ! switch (icmpv6code) { ! ! case IANA_ICMPv6_RPL_DIO: ! if (idmanager_getIsBridge()==TRUE) { ! // stop here if I'm in bridge mode ! break; // break, don't return ! } ! ! // update neighbor table ! neighbors_indicateRxDIO(msg); ! ! // update DODAGID in DIO/DAO ! memcpy( ! &(icmpv6rpl_vars.dio.DODAGID[0]), ! &(((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0]), ! sizeof(icmpv6rpl_vars.dio.DODAGID) ! ); ! memcpy( ! &(icmpv6rpl_vars.dao.DODAGID[0]), ! &(((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0]), ! sizeof(icmpv6rpl_vars.dao.DODAGID) ! ); ! ! // remember I got a DODAGID ! icmpv6rpl_vars.DODAGIDFlagSet=1; ! ! // update my prefix ! myPrefix.type = ADDR_PREFIX; ! memcpy( ! myPrefix.prefix, ! &((icmpv6rpl_dio_ht*)(msg->payload))->DODAGID[0], ! sizeof(myPrefix.prefix) ! ); ! idmanager_setMyID(&myPrefix); ! ! break; ! ! case IANA_ICMPv6_RPL_DAO: ! // this should never happen ! openserial_printCritical(COMPONENT_ICMPv6RPL,ERR_UNEXPECTED_DAO, ! (errorparameter_t)0, ! (errorparameter_t)0); ! break; ! ! default: ! // this should never happen ! openserial_printCritical(COMPONENT_ICMPv6RPL,ERR_MSG_UNKNOWN_TYPE, ! (errorparameter_t)icmpv6code, ! (errorparameter_t)0); ! break; ! ! } ! ! // free message ! openqueue_freePacketBuffer(msg); ! } ! ! //=========================== private ========================================= ! ! //===== DIO-related ! ! /** ! \brief DIO timer callback function. ! ! \note This function is executed in interrupt context, and should only push a ! task. ! */ ! void icmpv6rpl_timer_DIO_cb(void) { ! scheduler_push_task(icmpv6rpl_timer_DIO_task,TASKPRIO_RPL); ! /*thread_create(openwsn_icmpv6rpl_DIO_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_ICMPV6RPL, CREATE_STACKTEST, ! icmpv6rpl_timer_DIO_task, "icmpv6rpl_timer_DIO_task");*/ ! } ! ! /** ! \brief Handler for DIO timer event. ! ! \note This function is executed in task context, called by the scheduler. ! */ ! void icmpv6rpl_timer_DIO_task(void) { ! ! // update the delayDIO ! icmpv6rpl_vars.delayDIO = (icmpv6rpl_vars.delayDIO+1)%5; ! ! // check whether we need to send DIO ! if (icmpv6rpl_vars.delayDIO==0) { ! ! // send DIO ! sendDIO(); ! ! // pick a new pseudo-random periodDIO ! icmpv6rpl_vars.periodDIO = TIMER_DIO_TIMEOUT+(openrandom_get16b()&0xff); ! ! // arm the DIO timer with this new value ! opentimers_setPeriod( ! icmpv6rpl_vars.timerIdDIO, ! TIME_MS, ! icmpv6rpl_vars.periodDIO ! ); ! } ! } ! ! /** ! \brief Prepare and a send a RPL DIO. ! */ ! void sendDIO(void) { ! OpenQueueEntry_t* msg; ! ! // stop if I'm not sync'ed ! if (ieee154e_isSynch()==FALSE) { ! ! // remove packets genereted by this module (DIO and DAO) from openqueue ! openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); ! ! // I'm not busy sending a DIO/DAO ! icmpv6rpl_vars.busySending = FALSE; ! ! // stop here ! return; ! } ! ! // do not send DIO if I'm in in bridge mode ! if (idmanager_getIsBridge()==TRUE) { ! return; ! } ! ! // do not send DIO if I have the default DAG rank ! if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { ! return; ! } ! ! // do not send DIO if I'm already busy sending ! if (icmpv6rpl_vars.busySending==TRUE) { ! return; ! } ! ! // if you get here, all good to send a DIO ! ! // I'm now busy sending ! icmpv6rpl_vars.busySending = TRUE; ! ! // reserve a free packet buffer for DIO ! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); ! if (msg==NULL) { ! openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! icmpv6rpl_vars.busySending = FALSE; ! ! return; ! } ! ! // take ownership ! msg->creator = COMPONENT_ICMPv6RPL; ! msg->owner = COMPONENT_ICMPv6RPL; ! ! // set transport information ! msg->l4_protocol = IANA_ICMPv6; ! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; ! ! // set DIO destination ! memcpy(&(msg->l3_destinationAdd),&icmpv6rpl_vars.dioDestination,sizeof(open_addr_t)); ! ! //===== DIO payload ! // note: DIO is already mostly populated ! icmpv6rpl_vars.dio.rank = neighbors_getMyDAGrank(); ! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dio_ht)); ! memcpy( ! ((icmpv6rpl_dio_ht*)(msg->payload)), ! &(icmpv6rpl_vars.dio), ! sizeof(icmpv6rpl_dio_ht) ! ); ! ! //===== ICMPv6 header ! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); ! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; ! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DIO; ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum));//call last ! ! //send ! if (icmpv6_send(msg)!=E_SUCCESS) { ! icmpv6rpl_vars.busySending = FALSE; ! openqueue_freePacketBuffer(msg); ! } else { ! icmpv6rpl_vars.busySending = FALSE; ! } ! } ! ! //===== DAO-related ! ! /** ! \brief DAO timer callback function. ! ! \note This function is executed in interrupt context, and should only push a ! task. ! */ ! void icmpv6rpl_timer_DAO_cb(void) { ! scheduler_push_task(icmpv6rpl_timer_DAO_task,TASKPRIO_RPL); ! /*thread_create(openwsn_icmpv6rpl_DAO_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_ICMPV6RPL, CREATE_STACKTEST, ! icmpv6rpl_timer_DAO_task, "icmpv6rpl_timer_DAO_task");*/ ! } ! ! /** ! \brief Handler for DAO timer event. ! ! \note This function is executed in task context, called by the scheduler. ! */ ! void icmpv6rpl_timer_DAO_task(void) { ! ! // update the delayDAO ! icmpv6rpl_vars.delayDAO = (icmpv6rpl_vars.delayDAO+1)%5; ! ! // check whether we need to send DAO ! if (icmpv6rpl_vars.delayDAO==0) { ! ! // send DAO ! sendDAO(); ! ! // pick a new pseudo-random periodDAO ! icmpv6rpl_vars.periodDAO = TIMER_DAO_TIMEOUT+(openrandom_get16b()&0xff); ! ! // arm the DAO timer with this new value ! opentimers_setPeriod( ! icmpv6rpl_vars.timerIdDAO, ! TIME_MS, ! icmpv6rpl_vars.periodDAO ! ); ! } ! } ! ! /** ! \brief Prepare and a send a RPL DAO. ! */ ! void sendDAO(void) { ! OpenQueueEntry_t* msg; // pointer to DAO messages ! uint8_t nbrIdx; // running neighbor index ! uint8_t numTransitParents,numTargetParents; // the number of parents indicated in transit option ! open_addr_t address; ! open_addr_t* prefix; ! ! if (ieee154e_isSynch()==FALSE) { ! // I'm not sync'ed ! ! // delete packets genereted by this module (DIO and DAO) from openqueue ! openqueue_removeAllCreatedBy(COMPONENT_ICMPv6RPL); ! ! // I'm not busy sending a DIO/DAO ! icmpv6rpl_vars.busySending = FALSE; ! ! // stop here ! return; ! } ! ! // dont' send a DAO if you're in bridge mode ! if (idmanager_getIsBridge()==TRUE) { ! return; ! } ! ! // dont' send a DAO if you did not acquire a DAGrank ! if (neighbors_getMyDAGrank()==DEFAULTDAGRANK) { ! return; ! } ! ! // dont' send a DAO if you're still busy sending the previous one ! if (icmpv6rpl_vars.busySending==TRUE) { ! return; ! } ! ! // if you get here, you start construct DAO ! ! // reserve a free packet buffer for DAO ! msg = openqueue_getFreePacketBuffer(COMPONENT_ICMPv6RPL); ! if (msg==NULL) { ! openserial_printError(COMPONENT_ICMPv6RPL,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return; ! } ! ! // take ownership ! msg->creator = COMPONENT_ICMPv6RPL; ! msg->owner = COMPONENT_ICMPv6RPL; ! ! // set transport information ! msg->l4_protocol = IANA_ICMPv6; ! msg->l4_sourcePortORicmpv6Type = IANA_ICMPv6_RPL; ! ! // set DAO destination ! msg->l3_destinationAdd.type=ADDR_128B; ! memcpy(msg->l3_destinationAdd.addr_128b,icmpv6rpl_vars.dio.DODAGID,sizeof(icmpv6rpl_vars.dio.DODAGID)); ! ! //===== fill in packet ! ! //NOTE: limit to preferrred parent only the number of DAO transit addresses to send ! ! //=== transit option -- from RFC 6550, page 55 - 1 transit information header per parent is required. ! //getting only preferred parent as transit ! numTransitParents=0; ! neighbors_getPreferredParentEui64(&address); ! packetfunctions_writeAddress(msg,&address,OW_BIG_ENDIAN); ! prefix=idmanager_getMyID(ADDR_PREFIX); ! packetfunctions_writeAddress(msg,prefix,OW_BIG_ENDIAN); ! // update transit info fields ! // from rfc6550 p.55 -- Variable, depending on whether or not the DODAG ParentAddress subfield is present. ! // poipoi xv: it is not very clear if this includes all fields in the header. or as target info 2 bytes are removed. ! // using the same pattern as in target information. ! icmpv6rpl_vars.dao_transit.optionLength = LENGTH_ADDR128b + sizeof(icmpv6rpl_dao_transit_ht)-2; ! icmpv6rpl_vars.dao_transit.PathControl=0; //todo. this is to set the preference of this parent. ! icmpv6rpl_vars.dao_transit.type=OPTION_TRANSIT_INFORMATION_TYPE; ! ! // write transit info in packet ! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_transit_ht)); ! memcpy( ! ((icmpv6rpl_dao_transit_ht*)(msg->payload)), ! &(icmpv6rpl_vars.dao_transit), ! sizeof(icmpv6rpl_dao_transit_ht) ! ); ! numTransitParents++; ! ! //target information is required. RFC 6550 page 55. ! /* ! One or more Transit Information options MUST be preceded by one or ! more RPL Target options. ! */ ! numTargetParents = 0; ! for (nbrIdx=0;nbrIdxpayload)), ! &(icmpv6rpl_vars.dao_target), ! sizeof(icmpv6rpl_dao_target_ht) ! ); ! ! // remember I found it ! numTargetParents++; ! } ! //limit to MAX_TARGET_PARENTS the number of DAO target addresses to send ! //section 8.2.1 pag 67 RFC6550 -- using a subset ! // poipoi TODO base selection on ETX rather than first X. ! if (numTargetParents>=MAX_TARGET_PARENTS) break; ! } ! ! ! // stop here if no parents found ! if (numTransitParents==0) { ! openqueue_freePacketBuffer(msg); ! return; ! } ! ! icmpv6rpl_vars.dao_transit.PathSequence++; //increment path sequence. ! // if you get here, you will send a DAO ! ! ! //=== DAO header ! packetfunctions_reserveHeaderSize(msg,sizeof(icmpv6rpl_dao_ht)); ! memcpy( ! ((icmpv6rpl_dao_ht*)(msg->payload)), ! &(icmpv6rpl_vars.dao), ! sizeof(icmpv6rpl_dao_ht) ! ); ! ! //=== ICMPv6 header ! packetfunctions_reserveHeaderSize(msg,sizeof(ICMPv6_ht)); ! ((ICMPv6_ht*)(msg->payload))->type = msg->l4_sourcePortORicmpv6Type; ! ((ICMPv6_ht*)(msg->payload))->code = IANA_ICMPv6_RPL_DAO; ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((ICMPv6_ht*)(msg->payload))->checksum)); //call last ! ! //===== send ! if (icmpv6_send(msg)==E_SUCCESS) { ! icmpv6rpl_vars.busySending = TRUE; ! } else { ! openqueue_freePacketBuffer(msg); ! } ! } diff -crB openwsn/03b-IPv6/icmpv6rpl.h ../../../sys/net/openwsn/03b-IPv6/icmpv6rpl.h *** openwsn/03b-IPv6/icmpv6rpl.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/03b-IPv6/icmpv6rpl.h Wed Jan 15 13:48:27 2014 *************** *** 1,140 **** ! #ifndef __ICMPv6RPL_H ! #define __ICMPv6RPL_H ! ! /** ! \addtogroup IPv6 ! \{ ! \addtogroup ICMPv6RPL ! \{ ! */ ! ! //=========================== define ========================================== ! ! #define TIMER_DIO_TIMEOUT 1700 ! #define TIMER_DAO_TIMEOUT 10000 ! ! #define MOP_DIO_A 1<<5 ! #define MOP_DIO_B 1<<4 ! #define MOP_DIO_C 1<<3 ! #define PRF_DIO_A 0<<2 ! #define PRF_DIO_B 0<<1 ! #define PRF_DIO_C 0<<0 ! #define G_DIO 1<<7 ! ! #define FLAG_DAO_A 0<<0 ! #define FLAG_DAO_B 0<<1 ! #define FLAG_DAO_C 0<<2 ! #define FLAG_DAO_D 0<<3 ! #define FLAG_DAO_E 0<<4 ! #define FLAG_DAO_F 0<<5 ! #define D_DAO 1<<6 ! #define K_DAO 0<<7 ! ! #define E_DAO_Transit_Info 0<<7 ! ! #define PC1_A_DAO_Transit_Info 0<<7 ! #define PC1_B_DAO_Transit_Info 1<<6 ! ! #define PC2_A_DAO_Transit_Info 0<<5 ! #define PC2_B_DAO_Transit_Info 0<<4 ! ! #define PC3_A_DAO_Transit_Info 0<<3 ! #define PC3_B_DAO_Transit_Info 0<<2 ! ! #define PC4_A_DAO_Transit_Info 0<<1 ! #define PC4_B_DAO_Transit_Info 0<<0 ! ! #define Prf_A_dio_options 0<<4 ! #define Prf_B_dio_options 0<<3 ! ! enum{ ! OPTION_ROUTE_INFORMATION_TYPE = 0x03, ! OPTION_DODAG_CONFIGURATION_TYPE = 0x04, ! OPTION_TARGET_INFORMATION_TYPE = 0x05, ! OPTION_TRANSIT_INFORMATION_TYPE = 0x06, ! }; ! ! //=========================== static ========================================== ! ! /** ! \brief Well-known IPv6 multicast address for "all routers". ! */ ! static const uint8_t all_routers_multicast[] = { ! 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 ! }; ! ! //=========================== typedef ========================================= ! ! //===== DIO ! ! /** ! \brief Header format of a RPL DIO packet. ! */ ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t rplinstanceId; ///< set by the DODAG root. ! uint8_t verNumb; ! dagrank_t rank; ! uint8_t rplOptions; ! uint8_t DTSN; ! uint8_t flags; ! uint8_t reserved; ! uint8_t DODAGID[16]; ! } icmpv6rpl_dio_ht; ! PRAGMA(pack()); ! ! //===== DAO ! ! /** ! \brief Header format of a RPL DAO packet. ! */ ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t rplinstanceId; ///< set by the DODAG root. ! uint8_t K_D_flags; ! uint8_t reserved; ! uint8_t DAOSequance; ! uint8_t DODAGID[16]; ! } icmpv6rpl_dao_ht; ! PRAGMA(pack()); ! ! /** ! \brief Header format of a RPL DAO "Transit Information" option. ! */ ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t type; ///< set by the DODAG root. ! uint8_t optionLength; ! uint8_t E_flags; ! uint8_t PathControl; ! uint8_t PathSequence; ! uint8_t PathLifetime; ! } icmpv6rpl_dao_transit_ht; ! PRAGMA(pack()); ! ! /** ! \brief Header format of a RPL DAO "Target" option. ! */ ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t type; ///< set by the DODAG root. ! uint8_t optionLength; ! uint8_t flags; ! uint8_t prefixLength; ! } icmpv6rpl_dao_target_ht; ! PRAGMA(pack()); ! ! ! //=========================== prototypes ====================================== ! ! void icmpv6rpl_init(); ! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, error_t error); ! void icmpv6rpl_receive(OpenQueueEntry_t* msg); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,167 ---- ! #ifndef __ICMPv6RPL_H ! #define __ICMPv6RPL_H ! ! /** ! \addtogroup IPv6 ! \{ ! \addtogroup ICMPv6RPL ! \{ ! */ ! ! #include "opentimers.h" ! ! //=========================== define ========================================== ! ! #define TIMER_DIO_TIMEOUT 1700 ! #define TIMER_DAO_TIMEOUT 10000 ! ! #define MOP_DIO_A 1<<5 ! #define MOP_DIO_B 1<<4 ! #define MOP_DIO_C 1<<3 ! #define PRF_DIO_A 0<<2 ! #define PRF_DIO_B 0<<1 ! #define PRF_DIO_C 0<<0 ! #define G_DIO 1<<7 ! ! #define FLAG_DAO_A 0<<0 ! #define FLAG_DAO_B 0<<1 ! #define FLAG_DAO_C 0<<2 ! #define FLAG_DAO_D 0<<3 ! #define FLAG_DAO_E 0<<4 ! #define FLAG_DAO_F 0<<5 ! #define D_DAO 1<<6 ! #define K_DAO 0<<7 ! ! #define E_DAO_Transit_Info 0<<7 ! ! #define PC1_A_DAO_Transit_Info 0<<7 ! #define PC1_B_DAO_Transit_Info 1<<6 ! ! #define PC2_A_DAO_Transit_Info 0<<5 ! #define PC2_B_DAO_Transit_Info 0<<4 ! ! #define PC3_A_DAO_Transit_Info 0<<3 ! #define PC3_B_DAO_Transit_Info 0<<2 ! ! #define PC4_A_DAO_Transit_Info 0<<1 ! #define PC4_B_DAO_Transit_Info 0<<0 ! ! #define Prf_A_dio_options 0<<4 ! #define Prf_B_dio_options 0<<3 ! ! // max number of parents and children to send in DAO ! //section 8.2.1 pag 67 RFC6550 -- using a subset ! #define MAX_TARGET_PARENTS 0x01 ! ! enum{ ! OPTION_ROUTE_INFORMATION_TYPE = 0x03, ! OPTION_DODAG_CONFIGURATION_TYPE = 0x04, ! OPTION_TARGET_INFORMATION_TYPE = 0x05, ! OPTION_TRANSIT_INFORMATION_TYPE = 0x06, ! }; ! ! //=========================== static ========================================== ! ! /** ! \brief Well-known IPv6 multicast address for "all routers". ! */ ! static const uint8_t all_routers_multicast[] = { ! 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 ! }; ! ! //=========================== typedef ========================================= ! ! //===== DIO ! ! /** ! \brief Header format of a RPL DIO packet. ! */ ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t rplinstanceId; ///< set by the DODAG root. ! uint8_t verNumb; ! dagrank_t rank; ! uint8_t rplOptions; ! uint8_t DTSN; ! uint8_t flags; ! uint8_t reserved; ! uint8_t DODAGID[16]; ! } icmpv6rpl_dio_ht; ! //PRAGMA(pack()); ! ! //===== DAO ! ! /** ! \brief Header format of a RPL DAO packet. ! */ ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t rplinstanceId; ///< set by the DODAG root. ! uint8_t K_D_flags; ! uint8_t reserved; ! uint8_t DAOSequence; ! uint8_t DODAGID[16]; ! } icmpv6rpl_dao_ht; ! //PRAGMA(pack()); ! ! /** ! \brief Header format of a RPL DAO "Transit Information" option. ! */ ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t type; ///< set by the DODAG root. ! uint8_t optionLength; ! uint8_t E_flags; ! uint8_t PathControl; ! uint8_t PathSequence; ! uint8_t PathLifetime; ! } icmpv6rpl_dao_transit_ht; ! //PRAGMA(pack()); ! ! /** ! \brief Header format of a RPL DAO "Target" option. ! */ ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t type; ///< set by the DODAG root. ! uint8_t optionLength; ! uint8_t flags; ! uint8_t prefixLength; ! } icmpv6rpl_dao_target_ht; ! //PRAGMA(pack()); ! ! //=========================== module variables ================================ ! ! typedef struct { ! // admin ! bool busySending; ///< currently sending DIO/DAO. ! uint8_t DODAGIDFlagSet; ///< is DODAGID set already? ! // DIO-related ! icmpv6rpl_dio_ht dio; ///< pre-populated DIO packet. ! open_addr_t dioDestination; ///< IPv6 destination address for DIOs. ! uint16_t periodDIO; ///< duration, in ms, of a timerIdDIO timeout. ! opentimer_id_t timerIdDIO; ///< ID of the timer used to send DIOs. ! uint8_t delayDIO; ///< number of timerIdDIO events before actually sending a DIO. ! // DAO-related ! icmpv6rpl_dao_ht dao; ///< pre-populated DAO packet. ! icmpv6rpl_dao_transit_ht dao_transit; ///< pre-populated DAO "Transit Info" option header. ! icmpv6rpl_dao_target_ht dao_target; ///< pre-populated DAO "Transit Info" option header. ! opentimer_id_t timerIdDAO; ///< ID of the timer used to send DAOs. ! uint16_t periodDAO; ///< duration, in ms, of a timerIdDAO timeout. ! uint8_t delayDAO; ///< number of timerIdDIO events before actually sending a DAO. ! } icmpv6rpl_vars_t; ! ! //=========================== prototypes ====================================== ! ! void icmpv6rpl_init(void); ! void icmpv6rpl_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! void icmpv6rpl_receive(OpenQueueEntry_t* msg); ! uint8_t icmpv6rpl_getRPLIntanceID(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/04-TRAN/Makefile ../../../sys/net/openwsn/04-TRAN/Makefile *** openwsn/04-TRAN/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/04-TRAN/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,42 ---- + SUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/07-App/ohlone + INCLUDES += -I$(CURDIR)/07-App/tcpecho + INCLUDES += -I$(CURDIR)/07-App/tcpinject + INCLUDES += -I$(CURDIR)/07-App/tcpprint + INCLUDES += -I$(CURDIR)/07-App/udpecho + INCLUDES += -I$(CURDIR)/07-App/udpinject + INCLUDES += -I$(CURDIR)/07-App/udplatency + INCLUDES += -I$(CURDIR)/07-App/udpprint + INCLUDES += -I$(CURDIR)/07-App/udprand + INCLUDES += -I$(CURDIR)/07-App/udpstorm + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) + $(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 + $(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;ipayload[index] & 0xf0) >> 4)); ! last_option = coap_options[i].type; ! coap_options[i].length = (msg->payload[index] & 0x0f); ! index++; ! coap_options[i].pValue = &(msg->payload[index]); ! index += coap_options[i].length; ! } ! // remove the CoAP header+options ! packetfunctions_tossHeader(msg,index); ! ! //=== step 2. find the resource to handle the packet ! ! // find the resource this applies to ! found = FALSE; ! if (coap_header.Code>=COAP_CODE_REQ_GET && ! coap_header.Code<=COAP_CODE_REQ_DELETE) { ! // this is a request: target resource is indicated as COAP_OPTION_LOCATIONPATH option(s) ! ! // find the resource which matches ! temp_desc = opencoap_vars.resources; ! while (found==FALSE) { ! if ( ! coap_options[0].type==COAP_OPTION_URIPATH && ! coap_options[1].type==COAP_OPTION_URIPATH && ! temp_desc->path0len>0 && ! temp_desc->path0val!=NULL && ! temp_desc->path1len>0 && ! temp_desc->path1val!=NULL ! ) { ! // resource has a path of form path0/path1 ! ! if ( ! coap_options[0].length==temp_desc->path0len && ! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 && ! coap_options[1].length==temp_desc->path1len && ! memcmp(coap_options[1].pValue,temp_desc->path1val,temp_desc->path1len)==0 ! ) { ! found = TRUE; ! }; ! } else if ( ! coap_options[0].type==COAP_OPTION_URIPATH && ! temp_desc->path0len>0 && ! temp_desc->path0val!=NULL ! ) { ! // resource has a path of form path0 ! ! if ( ! coap_options[0].length==temp_desc->path0len && ! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 ! ) { ! found = TRUE; ! }; ! }; ! // iterate to next resource ! if (found==FALSE) { ! if (temp_desc->next!=NULL) { ! temp_desc = temp_desc->next; ! } else { ! break; ! } ! } ! }; ! } else { ! // this is a response: target resource is indicated by message ID ! ! // find the resource which matches ! temp_desc = opencoap_vars.resources; ! while (found==FALSE) { ! if (coap_header.messageID==temp_desc->messageID) { ! found=TRUE; ! if (temp_desc->callbackRx!=NULL) { ! temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); ! } ! } ! // iterate to next resource ! if (found==FALSE) { ! if (temp_desc->next!=NULL) { ! temp_desc = temp_desc->next; ! } else { ! break; ! } ! } ! }; ! openqueue_freePacketBuffer(msg); ! // stop here: will will not respond to a response ! return; ! } ! ! //=== step 3. ask the resource to prepare response ! ! if (found==TRUE) { ! outcome = temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); ! } else { ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! // set the CoAP header ! coap_header.OC = 0; ! coap_header.Code = COAP_CODE_RESP_NOTFOUND; ! } ! ! if (outcome==E_FAIL) { ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! // set the CoAP header ! coap_header.OC = 0; ! coap_header.Code = COAP_CODE_RESP_METHODNOTALLOWED; ! } ! ! //=== step 4. send that packet back ! ! // fill in packet metadata ! if (found==TRUE) { ! msg->creator = temp_desc->componentID; ! } else { ! msg->creator = COMPONENT_OPENCOAP; ! } ! msg->l4_protocol = IANA_UDP; ! temp_l4_destination_port = msg->l4_destination_port; ! msg->l4_destination_port = msg->l4_sourcePortORicmpv6Type; ! msg->l4_sourcePortORicmpv6Type = temp_l4_destination_port; ! ! // fill in CoAP header ! packetfunctions_reserveHeaderSize(msg,4); ! msg->payload[0] = (COAP_VERSION << 6) | ! (COAP_TYPE_ACK << 4) | ! (coap_header.OC << 0); ! msg->payload[1] = coap_header.Code; ! msg->payload[2] = coap_header.messageID/256; ! msg->payload[3] = coap_header.messageID%256; ! ! if ((openudp_send(msg))==E_FAIL) { ! openqueue_freePacketBuffer(msg); ! } ! } ! ! void opencoap_sendDone(OpenQueueEntry_t* msg, error_t error) { ! coap_resource_desc_t* temp_resource; ! ! // take ownership over that packet ! msg->owner = COMPONENT_OPENCOAP; ! ! // indicate sendDone to creator of that packet ! //=== mine ! if (msg->creator==COMPONENT_OPENCOAP) { ! openqueue_freePacketBuffer(msg); ! return; ! } ! //=== someone else's ! temp_resource = opencoap_vars.resources; ! while (temp_resource!=NULL) { ! if (temp_resource->componentID==msg->creator && ! temp_resource->callbackSendDone!=NULL) { ! temp_resource->callbackSendDone(msg,error); ! return; ! } ! temp_resource = temp_resource->next; ! } ! ! openserial_printError(COMPONENT_OPENCOAP,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! } ! ! void timers_coap_fired() { ! //do something here if necessary ! } ! ! //===== from CoAP resources ! ! void opencoap_writeLinks(OpenQueueEntry_t* msg) { ! coap_resource_desc_t* temp_resource; ! ! temp_resource = opencoap_vars.resources; ! while (temp_resource!=NULL) { ! packetfunctions_reserveHeaderSize(msg,1); ! msg->payload[0] = '>'; ! if (temp_resource->path1len>0) { ! packetfunctions_reserveHeaderSize(msg,temp_resource->path1len); ! memcpy(&msg->payload[0],temp_resource->path1val,temp_resource->path1len); ! packetfunctions_reserveHeaderSize(msg,1); ! msg->payload[0] = '/'; ! } ! packetfunctions_reserveHeaderSize(msg,temp_resource->path0len); ! memcpy(msg->payload,temp_resource->path0val,temp_resource->path0len); ! packetfunctions_reserveHeaderSize(msg,2); ! msg->payload[1] = '/'; ! msg->payload[0] = '<'; ! if (temp_resource->next!=NULL) { ! packetfunctions_reserveHeaderSize(msg,1); ! msg->payload[0] = ','; ! } ! temp_resource = temp_resource->next; ! } ! } ! ! void opencoap_register(coap_resource_desc_t* desc) { ! coap_resource_desc_t* last_elem; ! ! if (opencoap_vars.resources==NULL) { ! opencoap_vars.resources = desc; ! return; ! } ! ! // add to the end of the resource linked list ! last_elem = opencoap_vars.resources; ! while (last_elem->next!=NULL) { ! last_elem = last_elem->next; ! } ! last_elem->next = desc; ! } ! ! error_t opencoap_send(OpenQueueEntry_t* msg, ! coap_type_t type, ! coap_code_t code, ! uint8_t numOptions, ! coap_resource_desc_t* descSender) { ! // change the global messageID ! opencoap_vars.messageID = openrandom_get16b(); ! // take ownership ! msg->owner = COMPONENT_OPENCOAP; ! // metadata ! msg->l4_sourcePortORicmpv6Type = WKP_UDP_COAP; ! // fill in CoAP header ! packetfunctions_reserveHeaderSize(msg,4); ! msg->payload[0] = (COAP_VERSION << 6) | ! (type << 4) | ! (numOptions << 0); ! msg->payload[1] = code; ! msg->payload[2] = (opencoap_vars.messageID>>8) & 0xff; ! msg->payload[3] = (opencoap_vars.messageID>>0) & 0xff; ! // record the messageID with this sender ! descSender->messageID = opencoap_vars.messageID; ! return openudp_send(msg); ! } ! ! //=========================== private ========================================= ! ! void icmpv6coap_timer_cb() { ! scheduler_push_task(timers_coap_fired,TASKPRIO_COAP); } \ No newline at end of file --- 1,364 ---- ! #include "openwsn.h" ! #include "opencoap.h" ! #include "openudp.h" ! #include "openqueue.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "packetfunctions.h" ! #include "idmanager.h" ! #include "opentimers.h" ! #include "scheduler.h" ! ! #include "thread.h" ! ! //=========================== variables ======================================= ! ! opencoap_vars_t opencoap_vars; ! //static char openwsn_coap_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! ! //=========================== prototype ======================================= ! ! void icmpv6coap_timer_cb(void); ! ! //=========================== public ========================================== ! ! //===== from stack ! ! void opencoap_init(void) { ! // initialize the resource linked list ! opencoap_vars.resources = NULL; ! ! // initialize the messageID ! opencoap_vars.messageID = openrandom_get16b(); ! ! // start the timer ! if (idmanager_getIsDAGroot()==FALSE) { ! opencoap_vars.timerId = opentimers_start(1000, ! TIMER_PERIODIC,TIME_MS, ! icmpv6coap_timer_cb); ! } ! } ! ! void opencoap_receive(OpenQueueEntry_t* msg) { ! uint16_t temp_l4_destination_port; ! uint8_t i; ! uint8_t index; ! coap_option_t last_option; ! coap_resource_desc_t* temp_desc; ! bool found; ! owerror_t outcome = 0; ! // local variables passed to the handlers (with msg) ! coap_header_iht coap_header; ! coap_option_iht coap_options[MAX_COAP_OPTIONS]; ! ! // take ownership over the received packet ! msg->owner = COMPONENT_OPENCOAP; ! ! //=== step 1. parse the packet ! ! // parse the CoAP header and remove from packet ! index = 0; ! coap_header.Ver = (msg->payload[index] & 0xc0) >> 6; ! coap_header.T = (coap_type_t)((msg->payload[index] & 0x30) >> 4); ! coap_header.TKL = (msg->payload[index] & 0x0f); ! index++; ! coap_header.Code = (coap_code_t)(msg->payload[index]); ! index++; ! coap_header.messageID = msg->payload[index]*256+msg->payload[index+1]; ! index+=2; ! ! //poipoi xv. TKL tells us the length of the token. If we want to support tokens longer ! //than one token needs to be converted to an array and memcopy here for the length of TKL ! coap_header.token = (msg->payload[index]); ! index+=coap_header.TKL; ! ! ! // reject unsupported header ! if (coap_header.Ver!=COAP_VERSION || coap_header.TKL>8) { ! openserial_printError(COMPONENT_OPENCOAP,ERR_WRONG_TRAN_PROTOCOL, ! (errorparameter_t)0, ! (errorparameter_t)coap_header.Ver); ! openqueue_freePacketBuffer(msg); ! return; ! } ! // initialize the coap_options ! for (i=0;ipayload[index]==0xFF){ ! //found the payload spacer, options are already parsed. ! index++; //skip it and break. ! break; ! } ! coap_options[i].type = (coap_option_t)((uint8_t)last_option+(uint8_t)((msg->payload[index] & 0xf0) >> 4)); ! last_option = coap_options[i].type; ! coap_options[i].length = (msg->payload[index] & 0x0f); ! index++; ! coap_options[i].pValue = &(msg->payload[index]); ! index += coap_options[i].length; //includes length as well ! } ! ! // remove the CoAP header+options ! packetfunctions_tossHeader(msg,index); ! ! //=== step 2. find the resource to handle the packet ! ! // find the resource this applies to ! found = FALSE; ! if (coap_header.Code>=COAP_CODE_REQ_GET && ! coap_header.Code<=COAP_CODE_REQ_DELETE) { ! // this is a request: target resource is indicated as COAP_OPTION_LOCATIONPATH option(s) ! ! // find the resource which matches ! temp_desc = opencoap_vars.resources; ! while (found==FALSE) { ! if ( ! coap_options[0].type==COAP_OPTION_NUM_URIPATH && ! coap_options[1].type==COAP_OPTION_NUM_URIPATH && ! temp_desc->path0len>0 && ! temp_desc->path0val!=NULL && ! temp_desc->path1len>0 && ! temp_desc->path1val!=NULL ! ) { ! // resource has a path of form path0/path1 ! ! if ( ! coap_options[0].length==temp_desc->path0len && ! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 && ! coap_options[1].length==temp_desc->path1len && ! memcmp(coap_options[1].pValue,temp_desc->path1val,temp_desc->path1len)==0 ! ) { ! found = TRUE; ! }; ! } else if ( ! coap_options[0].type==COAP_OPTION_NUM_URIPATH && ! temp_desc->path0len>0 && ! temp_desc->path0val!=NULL ! ) { ! // resource has a path of form path0 ! ! if ( ! coap_options[0].length==temp_desc->path0len && ! memcmp(coap_options[0].pValue,temp_desc->path0val,temp_desc->path0len)==0 ! ) { ! found = TRUE; ! }; ! }; ! // iterate to next resource ! if (found==FALSE) { ! if (temp_desc->next!=NULL) { ! temp_desc = temp_desc->next; ! } else { ! break; ! } ! } ! }; ! } else { ! // this is a response: target resource is indicated by message ID ! ! // find the resource which matches ! temp_desc = opencoap_vars.resources; ! while (found==FALSE) { ! if (coap_header.messageID==temp_desc->messageID) { ! found=TRUE; ! if (temp_desc->callbackRx!=NULL) { ! temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); ! } ! } ! // iterate to next resource ! if (found==FALSE) { ! if (temp_desc->next!=NULL) { ! temp_desc = temp_desc->next; ! } else { ! break; ! } ! } ! }; ! openqueue_freePacketBuffer(msg); ! // stop here: will will not respond to a response ! return; ! } ! ! //=== step 3. ask the resource to prepare response ! ! if (found==TRUE) { ! outcome = temp_desc->callbackRx(msg,&coap_header,&coap_options[0]); ! } else { ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! // set the CoAP header ! coap_header.TKL = 0; ! coap_header.Code = COAP_CODE_RESP_NOTFOUND; ! } ! ! if (outcome==E_FAIL) { ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! // set the CoAP header ! coap_header.TKL = 0; ! coap_header.Code = COAP_CODE_RESP_METHODNOTALLOWED; ! } ! ! //=== step 4. send that packet back ! ! // fill in packet metadata ! if (found==TRUE) { ! msg->creator = temp_desc->componentID; ! } else { ! msg->creator = COMPONENT_OPENCOAP; ! } ! msg->l4_protocol = IANA_UDP; ! temp_l4_destination_port = msg->l4_destination_port; ! msg->l4_destination_port = msg->l4_sourcePortORicmpv6Type; ! msg->l4_sourcePortORicmpv6Type = temp_l4_destination_port; ! ! //set destination address as the current source. ! msg->l3_destinationAdd.type = ADDR_128B; ! memcpy(&msg->l3_destinationAdd.addr_128b[0],&msg->l3_sourceAdd.addr_128b[0],LENGTH_ADDR128b); ! ! ! // fill in CoAP header ! packetfunctions_reserveHeaderSize(msg,5); ! msg->payload[0] = (COAP_VERSION << 6) | ! (COAP_TYPE_ACK << 4) | ! (coap_header.TKL << 0); ! msg->payload[1] = coap_header.Code; ! msg->payload[2] = coap_header.messageID/256; ! msg->payload[3] = coap_header.messageID%256; ! msg->payload[4] = coap_header.token; //this will be a memcopy for TKL size ! ! if ((openudp_send(msg))==E_FAIL) { ! openqueue_freePacketBuffer(msg); ! } ! } ! ! void opencoap_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! coap_resource_desc_t* temp_resource; ! ! // take ownership over that packet ! msg->owner = COMPONENT_OPENCOAP; ! ! // indicate sendDone to creator of that packet ! //=== mine ! if (msg->creator==COMPONENT_OPENCOAP) { ! openqueue_freePacketBuffer(msg); ! return; ! } ! //=== someone else's ! temp_resource = opencoap_vars.resources; ! while (temp_resource!=NULL) { ! if (temp_resource->componentID==msg->creator && ! temp_resource->callbackSendDone!=NULL) { ! temp_resource->callbackSendDone(msg,error); ! return; ! } ! temp_resource = temp_resource->next; ! } ! ! openserial_printError(COMPONENT_OPENCOAP,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! } ! ! void timers_coap_fired(void) { ! //do something here if necessary ! } ! ! //===== from CoAP resources ! ! void opencoap_writeLinks(OpenQueueEntry_t* msg) { ! coap_resource_desc_t* temp_resource; ! ! temp_resource = opencoap_vars.resources; ! while (temp_resource!=NULL) { ! packetfunctions_reserveHeaderSize(msg,1); ! msg->payload[0] = '>'; ! if (temp_resource->path1len>0) { ! packetfunctions_reserveHeaderSize(msg,temp_resource->path1len); ! memcpy(&msg->payload[0],temp_resource->path1val,temp_resource->path1len); ! packetfunctions_reserveHeaderSize(msg,1); ! msg->payload[0] = '/'; ! } ! packetfunctions_reserveHeaderSize(msg,temp_resource->path0len); ! memcpy(msg->payload,temp_resource->path0val,temp_resource->path0len); ! packetfunctions_reserveHeaderSize(msg,2); ! msg->payload[1] = '/'; ! msg->payload[0] = '<'; ! if (temp_resource->next!=NULL) { ! packetfunctions_reserveHeaderSize(msg,1); ! msg->payload[0] = ','; ! } ! temp_resource = temp_resource->next; ! } ! } ! ! /** ! \brief Register a new CoAP resource. ! ! Registration consists in adding a new resource at the end of the linked list ! of resources. ! */ ! void opencoap_register(coap_resource_desc_t* desc) { ! coap_resource_desc_t* last_elem; ! ! // since this CoAP resource will be at the end of the list, its next element ! // should point to NULL, indicating the end of the linked list. ! desc->next = NULL; ! ! if (opencoap_vars.resources==NULL) { ! opencoap_vars.resources = desc; ! return; ! } ! ! // add to the end of the resource linked list ! last_elem = opencoap_vars.resources; ! while (last_elem->next!=NULL) { ! last_elem = last_elem->next; ! } ! last_elem->next = desc; ! } ! ! owerror_t opencoap_send(OpenQueueEntry_t* msg, ! coap_type_t type, ! coap_code_t code, ! uint8_t TKL, ! coap_resource_desc_t* descSender) { ! // change the global messageID ! opencoap_vars.messageID = openrandom_get16b(); ! // take ownership ! msg->owner = COMPONENT_OPENCOAP; ! // metadata ! msg->l4_sourcePortORicmpv6Type = WKP_UDP_COAP; ! // fill in CoAP header ! packetfunctions_reserveHeaderSize(msg,5); ! msg->payload[0] = (COAP_VERSION << 6) | ! (type << 4) | ! (TKL << 0); ! msg->payload[1] = code; ! msg->payload[2] = (opencoap_vars.messageID>>8) & 0xff; ! msg->payload[3] = (opencoap_vars.messageID>>0) & 0xff; ! //poipoi xv token needs to be defined by the app or here ! #define TOKEN 123 ! msg->payload[4] = TOKEN; //this will be a memcopy for TKL size ! ! // record the messageID with this sender ! descSender->messageID = opencoap_vars.messageID; ! descSender->token = TOKEN; ! ! return openudp_send(msg); ! } ! ! //=========================== private ========================================= ! ! void icmpv6coap_timer_cb(void) { ! scheduler_push_task(timers_coap_fired,TASKPRIO_COAP); ! /*thread_create(openwsn_coap_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_COAP, CREATE_STACKTEST, ! timers_coap_fired, "timers coap fired");*/ } \ No newline at end of file diff -crB openwsn/04-TRAN/opencoap.h ../../../sys/net/openwsn/04-TRAN/opencoap.h *** openwsn/04-TRAN/opencoap.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/opencoap.h Wed Jan 15 13:48:27 2014 *************** *** 1,161 **** ! #ifndef __OPENCOAP_H ! #define __OPENCOAP_H ! ! /** ! \addtogroup Transport ! \{ ! \addtogroup openCoap ! \{ ! */ ! ! //=========================== define ========================================== ! ! // IPv6 addresses of servers on the Internet ! static const uint8_t ipAddr_ipsoRD[] = {0x26, 0x07, 0xf7, 0x40, 0x00, 0x00, 0x00, 0x3f, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x29}; ! static const uint8_t ipAddr_motesEecs[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x19, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; ! //static const uint8_t ipAddr_local[] = {0x20, 0x02, 0x80, 0x20, 0x21, 0x47, 0x00, 0x0c, \ ! 0x10, 0xcb, 0xc6, 0x52, 0x44, 0x17, 0xd4, 0x18}; ! // 2607:f140:400:1036:688e:fa3b:444:6211 ! //static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ ! // 0x68, 0x8e, 0xfa, 0x3b, 0x04, 0x44, 0x62, 0x11}; ! ! static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ ! 0x4d, 0xcd, 0xab, 0x54, 0x81, 0x99, 0xc1, 0xf7}; ! ! static const uint8_t ipAddr_motedata[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x17, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; ! ! /// the maximum number of options in a RX'ed CoAP message ! #define MAX_COAP_OPTIONS 3 ! ! #define COAP_VERSION 1 ! ! typedef enum { ! COAP_TYPE_CON = 0, ! COAP_TYPE_NON = 1, ! COAP_TYPE_ACK = 2, ! COAP_TYPE_RES = 3, ! } coap_type_t; ! ! typedef enum { ! COAP_CODE_EMPTY = 0, ! // request ! COAP_CODE_REQ_GET = 1, ! COAP_CODE_REQ_POST = 2, ! COAP_CODE_REQ_PUT = 3, ! COAP_CODE_REQ_DELETE = 4, ! // response ! // - OK ! COAP_CODE_RESP_CREATED = 65, ! COAP_CODE_RESP_DELETED = 66, ! COAP_CODE_RESP_VALID = 67, ! COAP_CODE_RESP_CHANGED = 68, ! COAP_CODE_RESP_CONTENT = 69, ! // - not OK ! COAP_CODE_RESP_BADREQ = 128, ! COAP_CODE_RESP_UNAUTHORIZED = 129, ! COAP_CODE_RESP_BADOPTION = 130, ! COAP_CODE_RESP_FORBIDDEN = 131, ! COAP_CODE_RESP_NOTFOUND = 132, ! COAP_CODE_RESP_METHODNOTALLOWED = 133, ! COAP_CODE_RESP_PRECONDFAILED = 140, ! COAP_CODE_RESP_REQTOOLARGE = 141, ! COAP_CODE_RESP_UNSUPPMEDIATYPE = 143, ! // - error ! COAP_CODE_RESP_SERVERERROR = 160, ! COAP_CODE_RESP_NOTIMPLEMENTED = 161, ! COAP_CODE_RESP_BADGATEWAY = 162, ! COAP_CODE_RESP_UNAVAILABLE = 163, ! COAP_CODE_RESP_GWTIMEOUT = 164, ! COAP_CODE_RESP_PROXYINGNOTSUPP = 165, ! } coap_code_t; ! ! typedef enum { ! COAP_OPTION_NONE = 0, ! COAP_OPTION_CONTENTTYPE = 1, ! COAP_OPTION_MAXAGE = 2, ! COAP_OPTION_PROXYURI = 3, ! COAP_OPTION_ETAG = 4, ! COAP_OPTION_URIHOST = 5, ! COAP_OPTION_LOCATIONPATH = 6, ! COAP_OPTION_URIPORT = 7, ! COAP_OPTION_LOCATIONQUERY = 8, ! COAP_OPTION_URIPATH = 9, ! COAP_OPTION_TOKEN = 11, ! COAP_OPTION_ACCEPT = 12, ! COAP_OPTION_IFMATCH = 13, ! COAP_OPTION_URIQUERY = 15, ! COAP_OPTION_IFNONEMATCH = 21, ! } coap_option_t; ! ! typedef enum { ! COAP_MEDTYPE_TEXTPLAIN = 0, ! COAP_MEDTYPE_APPLINKFORMAT = 40, ! COAP_MEDTYPE_APPXML = 41, ! COAP_MEDTYPE_APPOCTETSTREAM = 42, ! COAP_MEDTYPE_APPEXI = 47, ! COAP_MEDTYPE_APPJSON = 50, ! } coap_media_type_t; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint8_t Ver; ! coap_type_t T; ! uint8_t OC; ! coap_code_t Code; ! uint16_t messageID; ! } coap_header_iht; ! ! typedef struct { ! coap_option_t type; ! uint8_t length; ! uint8_t* pValue; ! } coap_option_iht; ! ! typedef error_t (*callbackRx_t)(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! typedef void (*callbackTimer_t)(void); ! typedef void (*callbackSendDone_t)(OpenQueueEntry_t* msg, error_t error); ! ! typedef struct coap_resource_desc_t coap_resource_desc_t; ! ! struct coap_resource_desc_t { ! uint8_t path0len; ! uint8_t* path0val; ! uint8_t path1len; ! uint8_t* path1val; ! uint8_t componentID; ! uint16_t messageID; ! callbackRx_t callbackRx; ! callbackSendDone_t callbackSendDone; ! coap_resource_desc_t* next; ! }; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // from stack ! void opencoap_init(); ! void opencoap_receive(OpenQueueEntry_t* msg); ! void opencoap_sendDone(OpenQueueEntry_t* msg, error_t error); ! ! // from CoAP resources ! void opencoap_writeLinks(OpenQueueEntry_t* msg); ! void opencoap_register(coap_resource_desc_t* desc); ! error_t opencoap_send(OpenQueueEntry_t* msg, ! coap_type_t type, ! coap_code_t code, ! uint8_t numOptions, ! coap_resource_desc_t* descSender); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,175 ---- ! #ifndef __OPENCOAP_H ! #define __OPENCOAP_H ! ! /** ! \addtogroup Transport ! \{ ! \addtogroup openCoap ! \{ ! */ ! ! #include "opentimers.h" ! ! //=========================== define ========================================== ! ! // IPv6 addresses of servers on the Internet ! static const uint8_t ipAddr_ipsoRD[] = {0x26, 0x07, 0xf7, 0x40, 0x00, 0x00, 0x00, 0x3f, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x29}; ! static const uint8_t ipAddr_motesEecs[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x19, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; ! /*static const uint8_t ipAddr_local[] = {0x20, 0x02, 0x80, 0x20, 0x21, 0x47, 0x00, 0x0c, \ ! 0x10, 0xcb, 0xc6, 0x52, 0x44, 0x17, 0xd4, 0x18}; ! // 2607:f140:400:1036:688e:fa3b:444:6211 ! //static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ ! // 0x68, 0x8e, 0xfa, 0x3b, 0x04, 0x44, 0x62, 0x11}; ! */ ! static const uint8_t ipAddr_local[] = {0x26, 0x07, 0xf1, 0x40, 0x04, 0x00, 0x10, 0x36, \ ! 0x4d, 0xcd, 0xab, 0x54, 0x81, 0x99, 0xc1, 0xf7}; ! ! static const uint8_t ipAddr_motedata[] = {0x20, 0x01, 0x04, 0x70, 0x00, 0x66, 0x00, 0x17, \ ! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; ! ! /// the maximum number of options in a RX'ed CoAP message ! #define MAX_COAP_OPTIONS 10 //3 before but we want gets with more options ! ! #define COAP_VERSION 1 ! ! typedef enum { ! COAP_TYPE_CON = 0, ! COAP_TYPE_NON = 1, ! COAP_TYPE_ACK = 2, ! COAP_TYPE_RES = 3, ! } coap_type_t; ! ! typedef enum { ! COAP_CODE_EMPTY = 0, ! // request ! COAP_CODE_REQ_GET = 1, ! COAP_CODE_REQ_POST = 2, ! COAP_CODE_REQ_PUT = 3, ! COAP_CODE_REQ_DELETE = 4, ! // response ! // - OK ! COAP_CODE_RESP_CREATED = 65, ! COAP_CODE_RESP_DELETED = 66, ! COAP_CODE_RESP_VALID = 67, ! COAP_CODE_RESP_CHANGED = 68, ! COAP_CODE_RESP_CONTENT = 69, ! // - not OK ! COAP_CODE_RESP_BADREQ = 128, ! COAP_CODE_RESP_UNAUTHORIZED = 129, ! COAP_CODE_RESP_BADOPTION = 130, ! COAP_CODE_RESP_FORBIDDEN = 131, ! COAP_CODE_RESP_NOTFOUND = 132, ! COAP_CODE_RESP_METHODNOTALLOWED = 133, ! COAP_CODE_RESP_PRECONDFAILED = 140, ! COAP_CODE_RESP_REQTOOLARGE = 141, ! COAP_CODE_RESP_UNSUPPMEDIATYPE = 143, ! // - error ! COAP_CODE_RESP_SERVERERROR = 160, ! COAP_CODE_RESP_NOTIMPLEMENTED = 161, ! COAP_CODE_RESP_BADGATEWAY = 162, ! COAP_CODE_RESP_UNAVAILABLE = 163, ! COAP_CODE_RESP_GWTIMEOUT = 164, ! COAP_CODE_RESP_PROXYINGNOTSUPP = 165, ! } coap_code_t; ! ! typedef enum { ! COAP_OPTION_NONE = 0, ! COAP_OPTION_NUM_IFMATCH = 1, ! COAP_OPTION_NUM_URIHOST = 3, ! COAP_OPTION_NUM_ETAG = 4, ! COAP_OPTION_NUM_IFNONEMATCH = 5, ! COAP_OPTION_NUM_URIPORT = 7, ! COAP_OPTION_NUM_LOCATIONPATH = 8, ! COAP_OPTION_NUM_URIPATH = 11, ! COAP_OPTION_NUM_CONTENTFORMAT = 12, ! COAP_OPTION_NUM_MAXAGE = 14, ! COAP_OPTION_NUM_URIQUERY = 15, ! COAP_OPTION_NUM_ACCEPT = 16, ! COAP_OPTION_NUM_LOCATIONQUERY = 20, ! COAP_OPTION_NUM_PROXYURI = 35, ! COAP_OPTION_NUM_PROXYSCHEME = 39, ! } coap_option_t; ! ! ! ! typedef enum { ! COAP_MEDTYPE_TEXTPLAIN = 0, ! COAP_MEDTYPE_APPLINKFORMAT = 40, ! COAP_MEDTYPE_APPXML = 41, ! COAP_MEDTYPE_APPOCTETSTREAM = 42, ! COAP_MEDTYPE_APPEXI = 47, ! COAP_MEDTYPE_APPJSON = 50, ! } coap_media_type_t; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint8_t Ver; ! coap_type_t T; ! uint8_t TKL; ! coap_code_t Code; ! uint16_t messageID; ! uint8_t token; //this might be an array of 8 as tkl can be 8 ! } coap_header_iht; ! ! typedef struct { ! coap_option_t type; ! uint8_t length; ! uint8_t* pValue; ! } coap_option_iht; ! ! typedef owerror_t (*callbackRx_cbt)(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! typedef void (*callbackSendDone_cbt)(OpenQueueEntry_t* msg, ! owerror_t error); ! ! typedef struct coap_resource_desc_t coap_resource_desc_t; ! ! struct coap_resource_desc_t { ! uint8_t path0len; ! uint8_t* path0val; ! uint8_t path1len; ! uint8_t* path1val; ! uint8_t componentID; ! uint16_t messageID; ! uint8_t token; //should be 8bytes ! callbackRx_cbt callbackRx; ! callbackSendDone_cbt callbackSendDone; ! coap_resource_desc_t* next; ! }; ! ! //=========================== module variables ================================ ! ! typedef struct { ! coap_resource_desc_t* resources; ! bool busySending; ! uint8_t delayCounter; ! uint16_t messageID; ! opentimer_id_t timerId; ! } opencoap_vars_t; ! ! //=========================== prototypes ====================================== ! ! // from stack ! void opencoap_init(void); ! void opencoap_receive(OpenQueueEntry_t* msg); ! void opencoap_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! ! // from CoAP resources ! void opencoap_writeLinks(OpenQueueEntry_t* msg); ! void opencoap_register(coap_resource_desc_t* desc); ! owerror_t opencoap_send(OpenQueueEntry_t* msg, ! coap_type_t type, ! coap_code_t code, ! uint8_t numOptions, ! coap_resource_desc_t* descSender); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/04-TRAN/opentcp.c ../../../sys/net/openwsn/04-TRAN/opentcp.c *** openwsn/04-TRAN/opentcp.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/opentcp.c Wed Jan 15 13:48:27 2014 *************** *** 1,760 **** ! #include "openwsn.h" ! #include "opentcp.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "forwarding.h" ! #include "packetfunctions.h" ! #include "bsp_timer.h" ! #include "scheduler.h" ! #include "opentimers.h" ! //TCP applications ! #include "ohlone.h" ! #include "tcpecho.h" ! #include "tcpinject.h" ! #include "tcpprint.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! uint8_t state; ! uint32_t mySeqNum; ! uint16_t myPort; ! uint32_t hisNextSeqNum; ! uint16_t hisPort; ! open_addr_t hisIPv6Address; ! OpenQueueEntry_t* dataToSend; ! OpenQueueEntry_t* dataReceived; ! bool timerStarted; ! opentimer_id_t timerId; ! } tcp_vars_t; ! ! tcp_vars_t tcp_vars; ! ! //=========================== prototypes ====================================== ! ! void prependTCPHeader(OpenQueueEntry_t* msg, bool ack, bool push, bool rst, bool syn, bool fin); ! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin); ! void tcp_change_state(uint8_t new_state); ! void reset(); ! void opentcp_timer_cb(); ! ! //=========================== public ========================================== ! ! void opentcp_init() { ! // reset local variables ! memset(&tcp_vars,0,sizeof(tcp_vars_t)); ! // reset state machine ! reset(); ! } ! ! error_t opentcp_connect(open_addr_t* dest, uint16_t param_tcp_hisPort, uint16_t param_tcp_myPort) { ! //[command] establishment ! OpenQueueEntry_t* tempPkt; ! if (tcp_vars.state!=TCP_STATE_CLOSED) { ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)0); ! return E_FAIL; ! } ! tcp_vars.myPort = param_tcp_myPort; ! tcp_vars.hisPort = param_tcp_hisPort; ! memcpy(&tcp_vars.hisIPv6Address,dest,sizeof(open_addr_t)); ! //I receive command 'connect', I send SYNC ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return E_FAIL; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; ! prependTCPHeader(tempPkt, ! TCP_ACK_NO, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_YES, ! TCP_FIN_NO); ! tcp_change_state(TCP_STATE_ALMOST_SYN_SENT); ! return forwarding_send(tempPkt); ! } ! ! error_t opentcp_send(OpenQueueEntry_t* msg) { //[command] data ! msg->owner = COMPONENT_OPENTCP; ! if (tcp_vars.state!=TCP_STATE_ESTABLISHED) { ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)2); ! return E_FAIL; ! } ! if (tcp_vars.dataToSend!=NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_BUSY_SENDING, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return E_FAIL; ! } ! //I receive command 'send', I send data ! msg->l4_protocol = IANA_TCP; ! msg->l4_sourcePortORicmpv6Type = tcp_vars.myPort; ! msg->l4_destination_port = tcp_vars.hisPort; ! msg->l4_payload = msg->payload; ! msg->l4_length = msg->length; ! memcpy(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! tcp_vars.dataToSend = msg; ! prependTCPHeader(tcp_vars.dataToSend, ! TCP_ACK_YES, ! TCP_PSH_YES, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! tcp_vars.mySeqNum += tcp_vars.dataToSend->l4_length; ! tcp_change_state(TCP_STATE_ALMOST_DATA_SENT); ! return forwarding_send(tcp_vars.dataToSend); ! } ! ! void opentcp_sendDone(OpenQueueEntry_t* msg, error_t error) { ! OpenQueueEntry_t* tempPkt; ! msg->owner = COMPONENT_OPENTCP; ! switch (tcp_vars.state) { ! case TCP_STATE_ALMOST_SYN_SENT: //[sendDone] establishement ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_SYN_SENT); ! break; ! ! case TCP_STATE_ALMOST_SYN_RECEIVED: //[sendDone] establishement ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_SYN_RECEIVED); ! break; ! ! case TCP_STATE_ALMOST_ESTABLISHED: //[sendDone] establishement ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_ESTABLISHED); ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_connectDone(E_SUCCESS); ! break; ! case WKP_TCP_ECHO: ! tcpecho_connectDone(E_SUCCESS); ! break; ! case WKP_TCP_INJECT: ! tcpinject_connectDone(E_SUCCESS); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_connectDone(E_SUCCESS); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)0); ! break; ! } ! break; ! ! case TCP_STATE_ALMOST_DATA_SENT: //[sendDone] data ! tcp_change_state(TCP_STATE_DATA_SENT); ! break; ! ! case TCP_STATE_ALMOST_DATA_RECEIVED: //[sendDone] data ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_ESTABLISHED); ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_receive(tcp_vars.dataReceived); ! break; ! case WKP_TCP_ECHO: ! tcpecho_receive(tcp_vars.dataReceived); ! break; ! case WKP_TCP_INJECT: ! tcpinject_receive(tcp_vars.dataReceived); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_receive(tcp_vars.dataReceived); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)1); ! openqueue_freePacketBuffer(msg); ! tcp_vars.dataReceived = NULL; ! break; ! } ! break; ! ! case TCP_STATE_ALMOST_FIN_WAIT_1: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_FIN_WAIT_1); ! break; ! ! case TCP_STATE_ALMOST_CLOSING: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_CLOSING); ! break; ! ! case TCP_STATE_ALMOST_TIME_WAIT: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_TIME_WAIT); ! //TODO implement waiting timer ! reset(); ! break; ! ! case TCP_STATE_ALMOST_CLOSE_WAIT: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_CLOSE_WAIT); ! //I send FIN+ACK ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_YES); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_LAST_ACK); ! break; ! ! case TCP_STATE_ALMOST_LAST_ACK: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_LAST_ACK); ! break; ! ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)3); ! break; ! } ! } ! ! void opentcp_receive(OpenQueueEntry_t* msg) { ! OpenQueueEntry_t* tempPkt; ! bool shouldIlisten; ! msg->owner = COMPONENT_OPENTCP; ! msg->l4_protocol = IANA_TCP; ! msg->l4_payload = msg->payload; ! msg->l4_length = msg->length; ! msg->l4_sourcePortORicmpv6Type = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); ! msg->l4_destination_port = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); ! if ( ! tcp_vars.state!=TCP_STATE_CLOSED && ! ( ! msg->l4_destination_port != tcp_vars.myPort || ! msg->l4_sourcePortORicmpv6Type != tcp_vars.hisPort || ! packetfunctions_sameAddress(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address)==FALSE ! ) ! ) { ! openqueue_freePacketBuffer(msg); ! return; ! } ! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_YES,TCP_SYN_WHATEVER,TCP_FIN_WHATEVER)) { ! //I receive RST[+*], I reset ! reset(); ! openqueue_freePacketBuffer(msg); ! } ! switch (tcp_vars.state) { ! case TCP_STATE_CLOSED: //[receive] establishement ! switch(msg->l4_destination_port) { ! case WKP_TCP_HTTP: ! shouldIlisten = ohlone_shouldIlisten(); ! break; ! case WKP_TCP_ECHO: ! shouldIlisten = tcpecho_shouldIlisten(); ! break; ! case WKP_TCP_INJECT: ! shouldIlisten = tcpinject_shouldIlisten(); ! break; ! case WKP_TCP_DISCARD: ! shouldIlisten = tcpprint_shouldIlisten(); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, ! (errorparameter_t)2); ! shouldIlisten = FALSE; ! break; ! } ! if ( containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO) && shouldIlisten==TRUE ) { ! tcp_vars.myPort = msg->l4_destination_port; ! //I receive SYN, I send SYN+ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tcp_vars.hisPort = msg->l4_sourcePortORicmpv6Type; ! memcpy(&tcp_vars.hisIPv6Address,&(msg->l3_destinationAdd),sizeof(open_addr_t)); ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_YES, ! TCP_FIN_NO); ! tcp_vars.mySeqNum++; ! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); ! forwarding_send(tempPkt); ! } else { ! reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)0); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_SYN_SENT: //[receive] establishement ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { ! //I receive SYN+ACK, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! tcp_change_state(TCP_STATE_ALMOST_ESTABLISHED); ! forwarding_send(tempPkt); ! } else if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { ! //I receive SYN, I send SYN+ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_YES, ! TCP_FIN_NO); ! tcp_vars.mySeqNum++; ! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); ! forwarding_send(tempPkt); ! } else { ! reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)1); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_SYN_RECEIVED: //[receive] establishement ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, the virtual circuit is established ! tcp_change_state(TCP_STATE_ESTABLISHED); ! } else { ! reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)2); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_ESTABLISHED: //[receive] data/teardown ! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN[+ACK], I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); ! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive data, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht); ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! packetfunctions_tossHeader(msg,sizeof(tcp_ht)); ! tcp_vars.dataReceived = msg; ! tcp_change_state(TCP_STATE_ALMOST_DATA_RECEIVED); ! } else { ! reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)3); ! openqueue_freePacketBuffer(msg); ! } ! break; ! ! case TCP_STATE_DATA_SENT: //[receive] data ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, data message sent ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_ECHO: ! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_INJECT: ! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)3); ! break; ! } ! tcp_vars.dataToSend = NULL; ! tcp_change_state(TCP_STATE_ESTABLISHED); ! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN[+ACK], I send ACK ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_ECHO: ! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_INJECT: ! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)4); ! break; ! } ! tcp_vars.dataToSend = NULL; ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); ! } else { ! reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)4); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_FIN_WAIT_1: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_CLOSING); ! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN+ACK, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); ! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, I will receive FIN later ! tcp_change_state(TCP_STATE_FIN_WAIT_2); ! } else { ! reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)5); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_FIN_WAIT_2: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN[+ACK], I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_CLOSING: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, I do nothing ! tcp_change_state(TCP_STATE_TIME_WAIT); ! //TODO implement waiting timer ! reset(); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_LAST_ACK: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, I reset ! reset(); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)4); ! break; ! } ! } ! ! error_t opentcp_close() { //[command] teardown ! OpenQueueEntry_t* tempPkt; ! if ( tcp_vars.state==TCP_STATE_ALMOST_CLOSE_WAIT || ! tcp_vars.state==TCP_STATE_CLOSE_WAIT || ! tcp_vars.state==TCP_STATE_ALMOST_LAST_ACK || ! tcp_vars.state==TCP_STATE_LAST_ACK || ! tcp_vars.state==TCP_STATE_CLOSED) { ! //not an error, can happen when distant node has already started tearing down ! return E_SUCCESS; ! } ! //I receive command 'close', I send FIN+ACK ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return E_FAIL; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_YES); ! tcp_vars.mySeqNum++; ! tcp_change_state(TCP_STATE_ALMOST_FIN_WAIT_1); ! return forwarding_send(tempPkt); ! } ! ! bool tcp_debugPrint() { ! return FALSE; ! } ! ! //======= timer ! ! //timer used to reset state when TCP state machine is stuck ! void timers_tcp_fired() { ! reset(); ! } ! ! //=========================== private ========================================= ! ! void prependTCPHeader(OpenQueueEntry_t* msg, ! bool ack, ! bool push, ! bool rst, ! bool syn, ! bool fin) { ! msg->l4_protocol = IANA_TCP; ! packetfunctions_reserveHeaderSize(msg,sizeof(tcp_ht)); ! packetfunctions_htons(tcp_vars.myPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); ! packetfunctions_htons(tcp_vars.hisPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); ! packetfunctions_htonl(tcp_vars.mySeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)); ! packetfunctions_htonl(tcp_vars.hisNextSeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); ! ((tcp_ht*)msg->payload)->data_offset = TCP_DEFAULT_DATA_OFFSET; ! ((tcp_ht*)msg->payload)->control_bits = 0; ! if (ack==TCP_ACK_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_ACK; ! } else { ! packetfunctions_htonl(0,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); ! } ! if (push==TCP_PSH_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_PSH; ! } ! if (rst==TCP_RST_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_RST; ! } ! if (syn==TCP_SYN_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_SYN; ! } ! if (fin==TCP_FIN_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_FIN; ! } ! packetfunctions_htons(TCP_DEFAULT_WINDOW_SIZE ,(uint8_t*)&(((tcp_ht*)msg->payload)->window_size)); ! packetfunctions_htons(TCP_DEFAULT_URGENT_POINTER ,(uint8_t*)&(((tcp_ht*)msg->payload)->urgent_pointer)); ! //calculate checksum last to take all header fields into account ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((tcp_ht*)msg->payload)->checksum)); ! } ! ! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin) { ! bool return_value = TRUE; ! if (ack!=TCP_ACK_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_ACK) & 0x01) == ack); ! } ! if (rst!=TCP_RST_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_RST) & 0x01) == rst); ! } ! if (syn!=TCP_SYN_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_SYN) & 0x01) == syn); ! } ! if (fin!=TCP_FIN_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_FIN) & 0x01) == fin); ! } ! return return_value; ! } ! ! void reset() { ! tcp_change_state(TCP_STATE_CLOSED); ! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; ! tcp_vars.hisNextSeqNum = 0; ! tcp_vars.hisPort = 0; ! tcp_vars.hisIPv6Address.type = ADDR_NONE; ! tcp_vars.dataToSend = NULL; ! tcp_vars.dataReceived = NULL; ! openqueue_removeAllOwnedBy(COMPONENT_OPENTCP); ! } ! ! void tcp_change_state(uint8_t new_tcp_state) { ! tcp_vars.state = new_tcp_state; ! if (tcp_vars.state==TCP_STATE_CLOSED) { ! if (tcp_vars.timerStarted==TRUE) { ! opentimers_stop(tcp_vars.timerId); ! } ! } else { ! if (tcp_vars.timerStarted==FALSE) { ! tcp_vars.timerId = opentimers_start(TCP_TIMEOUT, ! TIMER_ONESHOT,TIME_MS, ! opentcp_timer_cb); ! tcp_vars.timerStarted=TRUE; ! } ! ! } ! } ! ! void opentcp_timer_cb() { ! scheduler_push_task(timers_tcp_fired,TASKPRIO_TCP_TIMEOUT); } \ No newline at end of file --- 1,753 ---- ! #include "openwsn.h" ! #include "opentcp.h" ! #include "openserial.h" ! #include "openqueue.h" ! #include "forwarding.h" ! #include "packetfunctions.h" ! //#include "bsp_timer.h" ! #include "scheduler.h" ! #include "opentimers.h" ! //TCP applications ! #include "ohlone.h" ! #include "tcpecho.h" ! #include "tcpinject.h" ! #include "tcpprint.h" ! ! #include "thread.h" ! ! //=========================== variables ======================================= ! ! tcp_vars_t tcp_vars; ! //static char openwsn_opentcp_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! ! //=========================== prototypes ====================================== ! ! void prependTCPHeader(OpenQueueEntry_t* msg, bool ack, bool push, bool rst, bool syn, bool fin); ! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin); ! void tcp_change_state(uint8_t new_state); ! void opentcp_reset(void); ! void opentcp_timer_cb(void); ! ! //=========================== public ========================================== ! ! void opentcp_init(void) { ! // reset local variables ! memset(&tcp_vars,0,sizeof(tcp_vars_t)); ! // reset state machine ! opentcp_reset(); ! } ! ! owerror_t opentcp_connect(open_addr_t* dest, uint16_t param_tcp_hisPort, uint16_t param_tcp_myPort) { ! //[command] establishment ! OpenQueueEntry_t* tempPkt; ! if (tcp_vars.state!=TCP_STATE_CLOSED) { ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)0); ! return E_FAIL; ! } ! tcp_vars.myPort = param_tcp_myPort; ! tcp_vars.hisPort = param_tcp_hisPort; ! memcpy(&tcp_vars.hisIPv6Address,dest,sizeof(open_addr_t)); ! //I receive command 'connect', I send SYNC ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return E_FAIL; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; ! prependTCPHeader(tempPkt, ! TCP_ACK_NO, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_YES, ! TCP_FIN_NO); ! tcp_change_state(TCP_STATE_ALMOST_SYN_SENT); ! return forwarding_send(tempPkt); ! } ! ! owerror_t opentcp_send(OpenQueueEntry_t* msg) { //[command] data ! msg->owner = COMPONENT_OPENTCP; ! if (tcp_vars.state!=TCP_STATE_ESTABLISHED) { ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)2); ! return E_FAIL; ! } ! if (tcp_vars.dataToSend!=NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_BUSY_SENDING, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return E_FAIL; ! } ! //I receive command 'send', I send data ! msg->l4_protocol = IANA_TCP; ! msg->l4_sourcePortORicmpv6Type = tcp_vars.myPort; ! msg->l4_destination_port = tcp_vars.hisPort; ! msg->l4_payload = msg->payload; ! msg->l4_length = msg->length; ! memcpy(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! tcp_vars.dataToSend = msg; ! prependTCPHeader(tcp_vars.dataToSend, ! TCP_ACK_YES, ! TCP_PSH_YES, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! tcp_vars.mySeqNum += tcp_vars.dataToSend->l4_length; ! tcp_change_state(TCP_STATE_ALMOST_DATA_SENT); ! return forwarding_send(tcp_vars.dataToSend); ! } ! ! void opentcp_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! OpenQueueEntry_t* tempPkt; ! msg->owner = COMPONENT_OPENTCP; ! switch (tcp_vars.state) { ! case TCP_STATE_ALMOST_SYN_SENT: //[sendDone] establishement ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_SYN_SENT); ! break; ! ! case TCP_STATE_ALMOST_SYN_RECEIVED: //[sendDone] establishement ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_SYN_RECEIVED); ! break; ! ! case TCP_STATE_ALMOST_ESTABLISHED: //[sendDone] establishement ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_ESTABLISHED); ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_connectDone(E_SUCCESS); ! break; ! case WKP_TCP_ECHO: ! tcpecho_connectDone(E_SUCCESS); ! break; ! case WKP_TCP_INJECT: ! tcpinject_connectDone(E_SUCCESS); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_connectDone(E_SUCCESS); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)0); ! break; ! } ! break; ! ! case TCP_STATE_ALMOST_DATA_SENT: //[sendDone] data ! tcp_change_state(TCP_STATE_DATA_SENT); ! break; ! ! case TCP_STATE_ALMOST_DATA_RECEIVED: //[sendDone] data ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_ESTABLISHED); ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_receive(tcp_vars.dataReceived); ! break; ! case WKP_TCP_ECHO: ! tcpecho_receive(tcp_vars.dataReceived); ! break; ! case WKP_TCP_INJECT: ! tcpinject_receive(tcp_vars.dataReceived); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_receive(tcp_vars.dataReceived); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)1); ! openqueue_freePacketBuffer(msg); ! tcp_vars.dataReceived = NULL; ! break; ! } ! break; ! ! case TCP_STATE_ALMOST_FIN_WAIT_1: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_FIN_WAIT_1); ! break; ! ! case TCP_STATE_ALMOST_CLOSING: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_CLOSING); ! break; ! ! case TCP_STATE_ALMOST_TIME_WAIT: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_TIME_WAIT); ! //TODO implement waiting timer ! opentcp_reset(); ! break; ! ! case TCP_STATE_ALMOST_CLOSE_WAIT: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_CLOSE_WAIT); ! //I send FIN+ACK ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_YES); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_LAST_ACK); ! break; ! ! case TCP_STATE_ALMOST_LAST_ACK: //[sendDone] teardown ! openqueue_freePacketBuffer(msg); ! tcp_change_state(TCP_STATE_LAST_ACK); ! break; ! ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)3); ! break; ! } ! } ! ! void opentcp_receive(OpenQueueEntry_t* msg) { ! OpenQueueEntry_t* tempPkt; ! bool shouldIlisten; ! msg->owner = COMPONENT_OPENTCP; ! msg->l4_protocol = IANA_TCP; ! msg->l4_payload = msg->payload; ! msg->l4_length = msg->length; ! msg->l4_sourcePortORicmpv6Type = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); ! msg->l4_destination_port = packetfunctions_ntohs((uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); ! if ( ! tcp_vars.state!=TCP_STATE_CLOSED && ! ( ! msg->l4_destination_port != tcp_vars.myPort || ! msg->l4_sourcePortORicmpv6Type != tcp_vars.hisPort || ! packetfunctions_sameAddress(&(msg->l3_destinationAdd),&tcp_vars.hisIPv6Address)==FALSE ! ) ! ) { ! openqueue_freePacketBuffer(msg); ! return; ! } ! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_YES,TCP_SYN_WHATEVER,TCP_FIN_WHATEVER)) { ! //I receive RST[+*], I reset ! opentcp_reset(); ! openqueue_freePacketBuffer(msg); ! } ! switch (tcp_vars.state) { ! case TCP_STATE_CLOSED: //[receive] establishement ! switch(msg->l4_destination_port) { ! case WKP_TCP_HTTP: ! shouldIlisten = ohlone_shouldIlisten(); ! break; ! case WKP_TCP_ECHO: ! shouldIlisten = tcpecho_shouldIlisten(); ! break; ! case WKP_TCP_INJECT: ! shouldIlisten = tcpinject_shouldIlisten(); ! break; ! case WKP_TCP_DISCARD: ! shouldIlisten = tcpprint_shouldIlisten(); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, ! (errorparameter_t)2); ! shouldIlisten = FALSE; ! break; ! } ! if ( containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO) && shouldIlisten==TRUE ) { ! tcp_vars.myPort = msg->l4_destination_port; ! //I receive SYN, I send SYN+ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tcp_vars.hisPort = msg->l4_sourcePortORicmpv6Type; ! memcpy(&tcp_vars.hisIPv6Address,&(msg->l3_destinationAdd),sizeof(open_addr_t)); ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_YES, ! TCP_FIN_NO); ! tcp_vars.mySeqNum++; ! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); ! forwarding_send(tempPkt); ! } else { ! opentcp_reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)0); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_SYN_SENT: //[receive] establishement ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { ! //I receive SYN+ACK, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! tcp_change_state(TCP_STATE_ALMOST_ESTABLISHED); ! forwarding_send(tempPkt); ! } else if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_YES,TCP_FIN_NO)) { ! //I receive SYN, I send SYN+ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_YES, ! TCP_FIN_NO); ! tcp_vars.mySeqNum++; ! tcp_change_state(TCP_STATE_ALMOST_SYN_RECEIVED); ! forwarding_send(tempPkt); ! } else { ! opentcp_reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)1); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_SYN_RECEIVED: //[receive] establishement ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, the virtual circuit is established ! tcp_change_state(TCP_STATE_ESTABLISHED); ! } else { ! opentcp_reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)2); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_ESTABLISHED: //[receive] data/teardown ! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN[+ACK], I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); ! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive data, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht); ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! packetfunctions_tossHeader(msg,sizeof(tcp_ht)); ! tcp_vars.dataReceived = msg; ! tcp_change_state(TCP_STATE_ALMOST_DATA_RECEIVED); ! } else { ! opentcp_reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)3); ! openqueue_freePacketBuffer(msg); ! } ! break; ! ! case TCP_STATE_DATA_SENT: //[receive] data ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, data message sent ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_ECHO: ! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_INJECT: ! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)3); ! break; ! } ! tcp_vars.dataToSend = NULL; ! tcp_change_state(TCP_STATE_ESTABLISHED); ! } else if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN[+ACK], I send ACK ! switch(tcp_vars.myPort) { ! case WKP_TCP_HTTP: ! ohlone_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_ECHO: ! tcpecho_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_INJECT: ! tcpinject_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! case WKP_TCP_DISCARD: ! tcpprint_sendDone(tcp_vars.dataToSend,E_SUCCESS); ! break; ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)tcp_vars.myPort, ! (errorparameter_t)4); ! break; ! } ! tcp_vars.dataToSend = NULL; ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+msg->length-sizeof(tcp_ht)+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_CLOSE_WAIT); ! } else { ! opentcp_reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)4); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_FIN_WAIT_1: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_NO,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_CLOSING); ! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN+ACK, I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); ! } else if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, I will receive FIN later ! tcp_change_state(TCP_STATE_FIN_WAIT_2); ! } else { ! opentcp_reset(); ! openserial_printError(COMPONENT_OPENTCP,ERR_TCP_RESET, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)5); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_FIN_WAIT_2: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_WHATEVER,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_YES)) { ! //I receive FIN[+ACK], I send ACK ! tcp_vars.hisNextSeqNum = (packetfunctions_ntohl((uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)))+1; ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(msg); ! return; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_NO); ! forwarding_send(tempPkt); ! tcp_change_state(TCP_STATE_ALMOST_TIME_WAIT); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_CLOSING: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, I do nothing ! tcp_change_state(TCP_STATE_TIME_WAIT); ! //TODO implement waiting timer ! opentcp_reset(); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! case TCP_STATE_LAST_ACK: //[receive] teardown ! if (containsControlBits(msg,TCP_ACK_YES,TCP_RST_NO,TCP_SYN_NO,TCP_FIN_NO)) { ! //I receive ACK, I reset ! opentcp_reset(); ! } ! openqueue_freePacketBuffer(msg); ! break; ! ! default: ! openserial_printError(COMPONENT_OPENTCP,ERR_WRONG_TCP_STATE, ! (errorparameter_t)tcp_vars.state, ! (errorparameter_t)4); ! break; ! } ! } ! ! owerror_t opentcp_close(void) { //[command] teardown ! OpenQueueEntry_t* tempPkt; ! if ( tcp_vars.state==TCP_STATE_ALMOST_CLOSE_WAIT || ! tcp_vars.state==TCP_STATE_CLOSE_WAIT || ! tcp_vars.state==TCP_STATE_ALMOST_LAST_ACK || ! tcp_vars.state==TCP_STATE_LAST_ACK || ! tcp_vars.state==TCP_STATE_CLOSED) { ! //not an error, can happen when distant node has already started tearing down ! return E_SUCCESS; ! } ! //I receive command 'close', I send FIN+ACK ! tempPkt = openqueue_getFreePacketBuffer(COMPONENT_OPENTCP); ! if (tempPkt==NULL) { ! openserial_printError(COMPONENT_OPENTCP,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! return E_FAIL; ! } ! tempPkt->creator = COMPONENT_OPENTCP; ! tempPkt->owner = COMPONENT_OPENTCP; ! memcpy(&(tempPkt->l3_destinationAdd),&tcp_vars.hisIPv6Address,sizeof(open_addr_t)); ! prependTCPHeader(tempPkt, ! TCP_ACK_YES, ! TCP_PSH_NO, ! TCP_RST_NO, ! TCP_SYN_NO, ! TCP_FIN_YES); ! tcp_vars.mySeqNum++; ! tcp_change_state(TCP_STATE_ALMOST_FIN_WAIT_1); ! return forwarding_send(tempPkt); ! } ! ! bool tcp_debugPrint(void) { ! return FALSE; ! } ! ! //======= timer ! ! //timer used to reset state when TCP state machine is stuck ! void timers_tcp_fired(void) { ! opentcp_reset(); ! } ! ! //=========================== private ========================================= ! ! void prependTCPHeader(OpenQueueEntry_t* msg, ! bool ack, ! bool push, ! bool rst, ! bool syn, ! bool fin) { ! msg->l4_protocol = IANA_TCP; ! packetfunctions_reserveHeaderSize(msg,sizeof(tcp_ht)); ! packetfunctions_htons(tcp_vars.myPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->source_port)); ! packetfunctions_htons(tcp_vars.hisPort ,(uint8_t*)&(((tcp_ht*)msg->payload)->destination_port)); ! packetfunctions_htonl(tcp_vars.mySeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->sequence_number)); ! packetfunctions_htonl(tcp_vars.hisNextSeqNum ,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); ! ((tcp_ht*)msg->payload)->data_offset = TCP_DEFAULT_DATA_OFFSET; ! ((tcp_ht*)msg->payload)->control_bits = 0; ! if (ack==TCP_ACK_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_ACK; ! } else { ! packetfunctions_htonl(0,(uint8_t*)&(((tcp_ht*)msg->payload)->ack_number)); ! } ! if (push==TCP_PSH_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_PSH; ! } ! if (rst==TCP_RST_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_RST; ! } ! if (syn==TCP_SYN_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_SYN; ! } ! if (fin==TCP_FIN_YES) { ! ((tcp_ht*)msg->payload)->control_bits |= 1 << TCP_FIN; ! } ! packetfunctions_htons(TCP_DEFAULT_WINDOW_SIZE ,(uint8_t*)&(((tcp_ht*)msg->payload)->window_size)); ! packetfunctions_htons(TCP_DEFAULT_URGENT_POINTER ,(uint8_t*)&(((tcp_ht*)msg->payload)->urgent_pointer)); ! //calculate checksum last to take all header fields into account ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((tcp_ht*)msg->payload)->checksum)); ! } ! ! bool containsControlBits(OpenQueueEntry_t* msg, uint8_t ack, uint8_t rst, uint8_t syn, uint8_t fin) { ! bool return_value = TRUE; ! if (ack!=TCP_ACK_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_ACK) & 0x01) == ack); ! } ! if (rst!=TCP_RST_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_RST) & 0x01) == rst); ! } ! if (syn!=TCP_SYN_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_SYN) & 0x01) == syn); ! } ! if (fin!=TCP_FIN_WHATEVER){ ! return_value = return_value && ((bool)( (((tcp_ht*)msg->payload)->control_bits >> TCP_FIN) & 0x01) == fin); ! } ! return return_value; ! } ! ! void opentcp_reset(void) { ! tcp_change_state(TCP_STATE_CLOSED); ! tcp_vars.mySeqNum = TCP_INITIAL_SEQNUM; ! tcp_vars.hisNextSeqNum = 0; ! tcp_vars.hisPort = 0; ! tcp_vars.hisIPv6Address.type = ADDR_NONE; ! tcp_vars.dataToSend = NULL; ! tcp_vars.dataReceived = NULL; ! openqueue_removeAllOwnedBy(COMPONENT_OPENTCP); ! } ! ! void tcp_change_state(uint8_t new_tcp_state) { ! tcp_vars.state = new_tcp_state; ! if (tcp_vars.state==TCP_STATE_CLOSED) { ! if (tcp_vars.timerStarted==TRUE) { ! opentimers_stop(tcp_vars.timerId); ! } ! } else { ! if (tcp_vars.timerStarted==FALSE) { ! tcp_vars.timerId = opentimers_start(TCP_TIMEOUT, ! TIMER_ONESHOT,TIME_MS, ! opentcp_timer_cb); ! tcp_vars.timerStarted=TRUE; ! } ! ! } ! } ! ! void opentcp_timer_cb(void) { ! scheduler_push_task(timers_tcp_fired,TASKPRIO_TCP_TIMEOUT); ! /*thread_create(openwsn_opentcp_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN_OPENTCP, CREATE_STACKTEST, ! timers_tcp_fired, "timers tcp fired");*/ } \ No newline at end of file diff -crB openwsn/04-TRAN/opentcp.h ../../../sys/net/openwsn/04-TRAN/opentcp.h *** openwsn/04-TRAN/opentcp.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/opentcp.h Wed Jan 15 13:48:27 2014 *************** *** 1,118 **** ! #ifndef __OPENTCP_H ! #define __OPENTCP_H ! ! /** ! \addtogroup Transport ! \{ ! \addtogroup TCP ! \{ ! */ ! ! //=========================== define ========================================== ! ! enum { ! TCP_INITIAL_SEQNUM = 100, ! TCP_TIMEOUT = 1500, //in ms ! }; ! ! enum TCP_STATE_enums { ! //listen state is not declared but emulated by a closed state with shouldIlisten==TRUE ! TCP_STATE_CLOSED = 0, ! TCP_STATE_ALMOST_SYN_RECEIVED = 1, ! TCP_STATE_SYN_RECEIVED = 2, ! TCP_STATE_ALMOST_SYN_SENT = 3, ! TCP_STATE_SYN_SENT = 4, ! TCP_STATE_ALMOST_ESTABLISHED = 5, ! TCP_STATE_ESTABLISHED = 6, ! TCP_STATE_ALMOST_DATA_SENT = 7, ! TCP_STATE_DATA_SENT = 8, ! TCP_STATE_ALMOST_DATA_RECEIVED = 9, ! TCP_STATE_ALMOST_FIN_WAIT_1 = 10, ! TCP_STATE_FIN_WAIT_1 = 11, ! TCP_STATE_ALMOST_CLOSING = 12, ! TCP_STATE_CLOSING = 13, ! TCP_STATE_FIN_WAIT_2 = 14, ! TCP_STATE_ALMOST_TIME_WAIT = 15, ! TCP_STATE_TIME_WAIT = 16, ! TCP_STATE_ALMOST_CLOSE_WAIT = 17, ! TCP_STATE_CLOSE_WAIT = 18, ! TCP_STATE_ALMOST_LAST_ACK = 19, ! TCP_STATE_LAST_ACK = 20, ! }; ! ! enum TCP_DEFAULTS_enum{ ! TCP_DEFAULT_DATA_OFFSET = 0x50, ! TCP_DEFAULT_WINDOW_SIZE = 48, ! TCP_DEFAULT_URGENT_POINTER = 0x0000, ! }; ! ! enum TCP_ACK_FLAG_enum { ! TCP_ACK_WHATEVER = 2, ! TCP_ACK_YES = 1, ! TCP_ACK_NO = 0, ! }; ! ! enum TCP_PSH_FLAG_enum { ! TCP_PSH_WHATEVER = 2, ! TCP_PSH_YES = 1, ! TCP_PSH_NO = 0, ! }; ! ! enum TCP_RST_FLAG_enum { ! TCP_RST_WHATEVER = 2, ! TCP_RST_YES = 1, ! TCP_RST_NO = 0, ! }; ! ! enum TCP_SYN_FLAG_enum { ! TCP_SYN_WHATEVER = 2, ! TCP_SYN_YES = 1, ! TCP_SYN_NO = 0, ! }; ! ! enum TCP_FIN_FLAG_enum { ! TCP_FIN_WHATEVER = 2, ! TCP_FIN_YES = 1, ! TCP_FIN_NO = 0, ! }; ! ! enum TCP_FLAG_POSITIONS_enum { ! TCP_ACK = 4, ! TCP_PSH = 3, ! TCP_RST = 2, ! TCP_SYN = 1, ! TCP_FIN = 0, ! }; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint16_t source_port; ! uint16_t destination_port; ! uint32_t sequence_number; ! uint32_t ack_number; ! uint8_t data_offset; ! uint8_t control_bits; ! uint16_t window_size; ! uint16_t checksum; ! uint16_t urgent_pointer; ! } tcp_ht; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void opentcp_init(); ! error_t opentcp_connect(open_addr_t* dest, uint16_t param_hisPort, uint16_t param_myPort); ! error_t opentcp_send(OpenQueueEntry_t* msg); ! void opentcp_sendDone(OpenQueueEntry_t* msg, error_t error); ! void opentcp_receive(OpenQueueEntry_t* msg); ! error_t opentcp_close(); ! bool opentcp_debugPrint(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,133 ---- ! #ifndef __OPENTCP_H ! #define __OPENTCP_H ! ! /** ! \addtogroup Transport ! \{ ! \addtogroup OpenTcp ! \{ ! */ ! ! #include "opentimers.h" ! ! //=========================== define ========================================== ! ! enum { ! TCP_INITIAL_SEQNUM = 100, ! TCP_TIMEOUT = 1500, //in ms ! }; ! ! enum TCP_STATE_enums { ! //listen state is not declared but emulated by a closed state with shouldIlisten==TRUE ! TCP_STATE_CLOSED = 0, ! TCP_STATE_ALMOST_SYN_RECEIVED = 1, ! TCP_STATE_SYN_RECEIVED = 2, ! TCP_STATE_ALMOST_SYN_SENT = 3, ! TCP_STATE_SYN_SENT = 4, ! TCP_STATE_ALMOST_ESTABLISHED = 5, ! TCP_STATE_ESTABLISHED = 6, ! TCP_STATE_ALMOST_DATA_SENT = 7, ! TCP_STATE_DATA_SENT = 8, ! TCP_STATE_ALMOST_DATA_RECEIVED = 9, ! TCP_STATE_ALMOST_FIN_WAIT_1 = 10, ! TCP_STATE_FIN_WAIT_1 = 11, ! TCP_STATE_ALMOST_CLOSING = 12, ! TCP_STATE_CLOSING = 13, ! TCP_STATE_FIN_WAIT_2 = 14, ! TCP_STATE_ALMOST_TIME_WAIT = 15, ! TCP_STATE_TIME_WAIT = 16, ! TCP_STATE_ALMOST_CLOSE_WAIT = 17, ! TCP_STATE_CLOSE_WAIT = 18, ! TCP_STATE_ALMOST_LAST_ACK = 19, ! TCP_STATE_LAST_ACK = 20, ! }; ! ! enum TCP_DEFAULTS_enum{ ! TCP_DEFAULT_DATA_OFFSET = 0x50, ! TCP_DEFAULT_WINDOW_SIZE = 48, ! TCP_DEFAULT_URGENT_POINTER = 0x0000, ! }; ! ! enum TCP_ACK_FLAG_enum { ! TCP_ACK_WHATEVER = 2, ! TCP_ACK_YES = 1, ! TCP_ACK_NO = 0, ! }; ! ! enum TCP_PSH_FLAG_enum { ! TCP_PSH_WHATEVER = 2, ! TCP_PSH_YES = 1, ! TCP_PSH_NO = 0, ! }; ! ! enum TCP_RST_FLAG_enum { ! TCP_RST_WHATEVER = 2, ! TCP_RST_YES = 1, ! TCP_RST_NO = 0, ! }; ! ! enum TCP_SYN_FLAG_enum { ! TCP_SYN_WHATEVER = 2, ! TCP_SYN_YES = 1, ! TCP_SYN_NO = 0, ! }; ! ! enum TCP_FIN_FLAG_enum { ! TCP_FIN_WHATEVER = 2, ! TCP_FIN_YES = 1, ! TCP_FIN_NO = 0, ! }; ! ! enum TCP_FLAG_POSITIONS_enum { ! TCP_ACK = 4, ! TCP_PSH = 3, ! TCP_RST = 2, ! TCP_SYN = 1, ! TCP_FIN = 0, ! }; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint16_t source_port; ! uint16_t destination_port; ! uint32_t sequence_number; ! uint32_t ack_number; ! uint8_t data_offset; ! uint8_t control_bits; ! uint16_t window_size; ! uint16_t checksum; ! uint16_t urgent_pointer; ! } tcp_ht; ! ! //=========================== module variables ================================ ! ! typedef struct { ! uint8_t state; ! uint32_t mySeqNum; ! uint16_t myPort; ! uint32_t hisNextSeqNum; ! uint16_t hisPort; ! open_addr_t hisIPv6Address; ! OpenQueueEntry_t* dataToSend; ! OpenQueueEntry_t* dataReceived; ! bool timerStarted; ! opentimer_id_t timerId; ! } tcp_vars_t; ! ! //=========================== prototypes ====================================== ! ! void opentcp_init(void); ! owerror_t opentcp_connect(open_addr_t* dest, uint16_t param_hisPort, uint16_t param_myPort); ! owerror_t opentcp_send(OpenQueueEntry_t* msg); ! void opentcp_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! void opentcp_receive(OpenQueueEntry_t* msg); ! owerror_t opentcp_close(void); ! bool opentcp_debugPrint(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/04-TRAN/openudp.c ../../../sys/net/openwsn/04-TRAN/openudp.c *** openwsn/04-TRAN/openudp.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/openudp.c Wed Jan 15 13:48:27 2014 *************** *** 1,158 **** ! #include "openwsn.h" ! #include "openudp.h" ! #include "openserial.h" ! #include "packetfunctions.h" ! #include "forwarding.h" ! #include "openqueue.h" ! //UDP applications ! #include "opencoap.h" ! #include "udpecho.h" ! #include "udpinject.h" ! #include "udpprint.h" ! #include "udprand.h" ! #include "udpstorm.h" ! #include "udplatency.h" ! //#include "heli.h" ! //#include "imu.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void openudp_init() { ! } ! ! error_t openudp_send(OpenQueueEntry_t* msg) { ! msg->owner = COMPONENT_OPENUDP; ! msg->l4_protocol = IANA_UDP; ! msg->l4_payload = msg->payload; ! msg->l4_length = msg->length; ! packetfunctions_reserveHeaderSize(msg,sizeof(udp_ht)); ! packetfunctions_htons(msg->l4_sourcePortORicmpv6Type,&(msg->payload[0])); ! packetfunctions_htons(msg->l4_destination_port,&(msg->payload[2])); ! packetfunctions_htons(msg->length,&(msg->payload[4])); ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((udp_ht*)msg->payload)->checksum)); ! return forwarding_send(msg); ! } ! ! void openudp_sendDone(OpenQueueEntry_t* msg, error_t error) { ! msg->owner = COMPONENT_OPENUDP; ! switch(msg->l4_sourcePortORicmpv6Type) { ! case WKP_UDP_COAP: ! opencoap_sendDone(msg,error); ! break; ! /* ! case WKP_UDP_HELI: ! appudpheli_sendDone(msg,error); ! break; ! case WKP_UDP_IMU: ! appudpgina_sendDone(msg,error); ! break; ! */ ! case WKP_UDP_ECHO: ! udpecho_sendDone(msg,error); ! break; ! case WKP_UDP_INJECT: ! udpinject_sendDone(msg,error); ! break; ! case WKP_UDP_DISCARD: ! udpprint_sendDone(msg,error); ! break; ! case WKP_UDP_RAND: ! udprand_sendDone(msg,error); ! break; ! case WKP_UDP_LATENCY: ! udplatency_sendDone(msg,error); ! break; ! ! default: ! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, ! (errorparameter_t)5); ! openqueue_freePacketBuffer(msg); ! } ! } ! ! void openudp_receive(OpenQueueEntry_t* msg) { ! uint8_t temp_8b; ! ! msg->owner = COMPONENT_OPENUDP; ! if (msg->l4_protocol_compressed==TRUE) { ! // get the UDP header encoding byte ! temp_8b = *((uint8_t*)(msg->payload)); ! packetfunctions_tossHeader(msg,sizeof(temp_8b)); ! switch (temp_8b & NHC_UDP_PORTS_MASK) { ! case NHC_UDP_PORTS_INLINE: ! // source port: 16 bits in-line ! // dest port: 16 bits in-line ! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; ! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; ! packetfunctions_tossHeader(msg,2+2); ! break; ! case NHC_UDP_PORTS_16S_8D: ! // source port: 16 bits in-line ! // dest port: 0xf0 + 8 bits in-line ! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; ! msg->l4_destination_port = 0xf000 + msg->payload[2]; ! packetfunctions_tossHeader(msg,2+1); ! break; ! case NHC_UDP_PORTS_8S_8D: ! // source port: 0xf0 + 8 bits in-line ! // dest port: 0xf0 + 8 bits in-line ! msg->l4_sourcePortORicmpv6Type = 0xf000 + msg->payload[0]; ! msg->l4_destination_port = 0xf000 + msg->payload[1]; ! packetfunctions_tossHeader(msg,1+1); ! break; ! case NHC_UDP_PORTS_4S_4D: ! // source port: 0xf0b + 4 bits in-line ! // dest port: 0xf0b + 4 bits in-line ! msg->l4_sourcePortORicmpv6Type = 0xf0b0 + (msg->payload[0] >> 4) & 0x0f; ! msg->l4_destination_port = 0xf0b0 + (msg->payload[0] >> 0) & 0x0f; ! packetfunctions_tossHeader(msg,1); ! break; ! } ! } else { ! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; ! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; ! packetfunctions_tossHeader(msg,sizeof(udp_ht)); ! } ! ! switch(msg->l4_destination_port) { ! case WKP_UDP_COAP: ! opencoap_receive(msg); ! break; ! /* ! case WKP_UDP_HELI: ! appudpheli_receive(msg); ! break; ! case WKP_UDP_IMU: ! imu_receive(msg); ! break; ! */ ! case WKP_UDP_ECHO: ! udpecho_receive(msg); ! break; ! case WKP_UDP_INJECT: ! udpinject_receive(msg); ! break; ! case WKP_UDP_DISCARD: ! udpprint_receive(msg); ! break; ! case WKP_UDP_RAND: ! udprand_receive(msg); ! break; ! default: ! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)msg->l4_destination_port, ! (errorparameter_t)6); ! openqueue_freePacketBuffer(msg); ! } ! } ! ! bool openudp_debugPrint() { ! return FALSE; ! } ! ! //=========================== private ========================================= --- 1,158 ---- ! #include "openwsn.h" ! #include "openudp.h" ! #include "openserial.h" ! #include "packetfunctions.h" ! #include "forwarding.h" ! #include "openqueue.h" ! //UDP applications ! #include "opencoap.h" ! #include "udpecho.h" ! #include "udpinject.h" ! #include "udpprint.h" ! #include "udprand.h" ! #include "udpstorm.h" ! #include "udplatency.h" ! //#include "heli.h" ! //#include "imu.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void openudp_init(void) { ! } ! ! owerror_t openudp_send(OpenQueueEntry_t* msg) { ! msg->owner = COMPONENT_OPENUDP; ! msg->l4_protocol = IANA_UDP; ! msg->l4_payload = msg->payload; ! msg->l4_length = msg->length; ! packetfunctions_reserveHeaderSize(msg,sizeof(udp_ht)); ! packetfunctions_htons(msg->l4_sourcePortORicmpv6Type,&(msg->payload[0])); ! packetfunctions_htons(msg->l4_destination_port,&(msg->payload[2])); ! packetfunctions_htons(msg->length,&(msg->payload[4])); ! packetfunctions_calculateChecksum(msg,(uint8_t*)&(((udp_ht*)msg->payload)->checksum)); ! return forwarding_send(msg); ! } ! ! void openudp_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! msg->owner = COMPONENT_OPENUDP; ! switch(msg->l4_sourcePortORicmpv6Type) { ! case WKP_UDP_COAP: ! opencoap_sendDone(msg,error); ! break; ! /* ! case WKP_UDP_HELI: ! appudpheli_sendDone(msg,error); ! break; ! case WKP_UDP_IMU: ! appudpgina_sendDone(msg,error); ! break; ! */ ! case WKP_UDP_ECHO: ! udpecho_sendDone(msg,error); ! break; ! case WKP_UDP_INJECT: ! udpinject_sendDone(msg,error); ! break; ! case WKP_UDP_DISCARD: ! udpprint_sendDone(msg,error); ! break; ! case WKP_UDP_RAND: ! udprand_sendDone(msg,error); ! break; ! case WKP_UDP_LATENCY: ! udplatency_sendDone(msg,error); ! break; ! ! default: ! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)msg->l4_sourcePortORicmpv6Type, ! (errorparameter_t)5); ! openqueue_freePacketBuffer(msg); ! } ! } ! ! void openudp_receive(OpenQueueEntry_t* msg) { ! uint8_t temp_8b; ! ! msg->owner = COMPONENT_OPENUDP; ! if (msg->l4_protocol_compressed==TRUE) { ! // get the UDP header encoding byte ! temp_8b = *((uint8_t*)(msg->payload)); ! packetfunctions_tossHeader(msg,sizeof(temp_8b)); ! switch (temp_8b & NHC_UDP_PORTS_MASK) { ! case NHC_UDP_PORTS_INLINE: ! // source port: 16 bits in-line ! // dest port: 16 bits in-line ! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; ! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; ! packetfunctions_tossHeader(msg,2+2); ! break; ! case NHC_UDP_PORTS_16S_8D: ! // source port: 16 bits in-line ! // dest port: 0xf0 + 8 bits in-line ! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; ! msg->l4_destination_port = 0xf000 + msg->payload[2]; ! packetfunctions_tossHeader(msg,2+1); ! break; ! case NHC_UDP_PORTS_8S_8D: ! // source port: 0xf0 + 8 bits in-line ! // dest port: 0xf0 + 8 bits in-line ! msg->l4_sourcePortORicmpv6Type = 0xf000 + msg->payload[0]; ! msg->l4_destination_port = 0xf000 + msg->payload[1]; ! packetfunctions_tossHeader(msg,1+1); ! break; ! case NHC_UDP_PORTS_4S_4D: ! // source port: 0xf0b + 4 bits in-line ! // dest port: 0xf0b + 4 bits in-line ! msg->l4_sourcePortORicmpv6Type = 0xf0b0 + ((msg->payload[0] >> 4) & 0x0f); ! msg->l4_destination_port = 0xf0b0 + ((msg->payload[0] >> 0) & 0x0f); ! packetfunctions_tossHeader(msg,1); ! break; ! } ! } else { ! msg->l4_sourcePortORicmpv6Type = msg->payload[0]*256+msg->payload[1]; ! msg->l4_destination_port = msg->payload[2]*256+msg->payload[3]; ! packetfunctions_tossHeader(msg,sizeof(udp_ht)); ! } ! ! switch(msg->l4_destination_port) { ! case WKP_UDP_COAP: ! opencoap_receive(msg); ! break; ! /* ! case WKP_UDP_HELI: ! appudpheli_receive(msg); ! break; ! case WKP_UDP_IMU: ! imu_receive(msg); ! break; ! */ ! case WKP_UDP_ECHO: ! udpecho_receive(msg); ! break; ! case WKP_UDP_INJECT: ! udpinject_receive(msg); ! break; ! case WKP_UDP_DISCARD: ! udpprint_receive(msg); ! break; ! case WKP_UDP_RAND: ! udprand_receive(msg); ! break; ! default: ! openserial_printError(COMPONENT_OPENUDP,ERR_UNSUPPORTED_PORT_NUMBER, ! (errorparameter_t)msg->l4_destination_port, ! (errorparameter_t)6); ! openqueue_freePacketBuffer(msg); ! } ! } ! ! bool openudp_debugPrint(void) { ! return FALSE; ! } ! ! //=========================== private ========================================= diff -crB openwsn/04-TRAN/openudp.h ../../../sys/net/openwsn/04-TRAN/openudp.h *** openwsn/04-TRAN/openudp.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/openudp.h Wed Jan 15 13:48:27 2014 *************** *** 1,59 **** ! #ifndef __OPENUDP_H ! #define __OPENUDP_H ! ! /** ! \addtogroup Transport ! \{ ! \addtogroup UDP ! \{ ! */ ! ! //=========================== define ========================================== ! ! enum UDP_enums { ! UDP_ID = 3, ! UDP_CHECKSUM = 2, ! UDP_PORTS = 0, ! }; ! ! enum UDP_ID_enums { ! UDP_ID_DEFAULT = 0x1E, ! }; ! ! enum UDP_CHECKSUM_enums { ! UDP_CHECKSUM_INLINE = 0, ! UDP_CHECKSUM_ELIDED = 1, ! }; ! ! enum UDP_PORTS_enums { ! UDP_PORTS_16b_SRC_16b_DEST_INLINE = 0, ! UDP_PORTS_16b_SRC_8b_DEST_INLINE = 1, ! UDP_PORTS_8b_SRC_16b_DEST_INLINE = 2, ! UDP_PORTS_4b_SRC_4b_DEST_INLINE = 3, ! }; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint16_t port_src; ! uint16_t port_dest; ! uint16_t length; ! uint16_t checksum; ! } udp_ht; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void openudp_init(); ! error_t openudp_send(OpenQueueEntry_t* msg); ! void openudp_sendDone(OpenQueueEntry_t* msg, error_t error); ! void openudp_receive(OpenQueueEntry_t* msg); ! bool openudp_debugPrint(); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,59 ---- ! #ifndef __OPENUDP_H ! #define __OPENUDP_H ! ! /** ! \addtogroup Transport ! \{ ! \addtogroup OpenUdp ! \{ ! */ ! ! //=========================== define ========================================== ! ! enum UDP_enums { ! UDP_ID = 3, ! UDP_CHECKSUM = 2, ! UDP_PORTS = 0, ! }; ! ! enum UDP_ID_enums { ! UDP_ID_DEFAULT = 0x1E, ! }; ! ! enum UDP_CHECKSUM_enums { ! UDP_CHECKSUM_INLINE = 0, ! UDP_CHECKSUM_ELIDED = 1, ! }; ! ! enum UDP_PORTS_enums { ! UDP_PORTS_16b_SRC_16b_DEST_INLINE = 0, ! UDP_PORTS_16b_SRC_8b_DEST_INLINE = 1, ! UDP_PORTS_8b_SRC_16b_DEST_INLINE = 2, ! UDP_PORTS_4b_SRC_4b_DEST_INLINE = 3, ! }; ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint16_t port_src; ! uint16_t port_dest; ! uint16_t length; ! uint16_t checksum; ! } udp_ht; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void openudp_init(void); ! owerror_t openudp_send(OpenQueueEntry_t* msg); ! void openudp_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! void openudp_receive(OpenQueueEntry_t* msg); ! bool openudp_debugPrint(void); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/04-TRAN/rsvp.c ../../../sys/net/openwsn/04-TRAN/rsvp.c *** openwsn/04-TRAN/rsvp.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/rsvp.c Wed Jan 15 13:48:27 2014 *************** *** 17,27 **** uint8_t rsvp_timer_id; }rsvp_vars_t; ! void rsvp_timer_cb(); rsvp_vars_t rsvp_vars; ! void rsvp_init(){ rsvp_vars.rsvp_period = 0; rsvp_vars.rsvp_timer_id = 0; } --- 17,27 ---- uint8_t rsvp_timer_id; }rsvp_vars_t; ! void rsvp_timer_cb(void); rsvp_vars_t rsvp_vars; ! void rsvp_init(void){ rsvp_vars.rsvp_period = 0; rsvp_vars.rsvp_timer_id = 0; } *************** *** 35,42 **** void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period, open_addr_t dest){ OpenQueueEntry_t* pkt; ! error_t outcome; uint8_t i,j; pkt = openqueue_getFreePacketBuffer(COMPONENT_RSVP); if (pkt==NULL) { --- 35,46 ---- void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period, open_addr_t dest){ OpenQueueEntry_t* pkt; ! owerror_t outcome; uint8_t i,j; + + (void)outcome; + (void)i; + (void)j; pkt = openqueue_getFreePacketBuffer(COMPONENT_RSVP); if (pkt==NULL) { diff -crB openwsn/04-TRAN/rsvp.h ../../../sys/net/openwsn/04-TRAN/rsvp.h *** openwsn/04-TRAN/rsvp.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/04-TRAN/rsvp.h Wed Jan 15 13:48:27 2014 *************** *** 157,163 **** ! void rsvp_init(); void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period,open_addr_t dest); #endif --- 157,163 ---- ! void rsvp_init(void); void rsvp_qos_request(uint8_t bandwith, uint16_t refresh_period,open_addr_t dest); #endif diff -crB openwsn/07-App/Makefile ../../../sys/net/openwsn/07-App/Makefile *** openwsn/07-App/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/07-App/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,49 ---- + SUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/07-App/ohlone + INCLUDES += -I$(CURDIR)/07-App/tcpecho + INCLUDES += -I$(CURDIR)/07-App/tcpinject + INCLUDES += -I$(CURDIR)/07-App/tcpprint + INCLUDES += -I$(CURDIR)/cross-layers + + DIRS += rinfo + DIRS += rwellknown + DIRS += ohlone + DIRS += tcpecho + DIRS += tcpinject + DIRS += tcpprint + DIRS += udpecho + DIRS += udpinject + DIRS += udplatency + DIRS += udpprint + DIRS += udprand + DIRS += udpstorm + + all: $(BINDIR)$(SUBMOD) + @for i in $(DIRS) ; do "$(MAKE)" -C $$i || exit 1; done ; + + $(BINDIR)$(SUBMOD): $(OBJ) + $(AD)$(AR) rcs $(BINDIR)$(MODULE) $(OBJ) + + # pull in dependency info for *existing* .o files + -include $(OBJ:.o=.d) + + # compile and generate dependency info + $(BINDIR)%.o: %.c + mkdir -p $(BINDIR) + $(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_pressed) ! ! addressText = Tkinter.Text(root,width=50,height=1) ! #displayElements[motePort]["cellTable"]["TextField"].delete("1.0",Tkinter.END) ! addressText.insert(Tkinter.END,'2001:470:1f05:dff:1415:9209:22b:51') ! addressText.grid(row=0,column=0) ! ! buttonCanvas=Tkinter.Canvas(root,width=300,height=400) ! buttonCanvas.bind("",gui_clicked) ! buttonCanvas.bind("",gui_clicked) ! buttonCanvas.bind("",gui_clicked) ! buttonCanvas.create_rectangle(100, 0,200,100,fill="blue") ! buttonCanvas.create_text(150,50,text="up ") ! buttonCanvas.create_rectangle( 0,100,100,200,fill="blue") ! buttonCanvas.create_text(50,150,text="left ") ! buttonCanvas.create_rectangle(200,100,300,200,fill="blue") ! buttonCanvas.create_text(250,150,text="right ") ! buttonCanvas.create_rectangle(100,200,200,300,fill="blue") ! buttonCanvas.create_text(150,250,text="down ") ! buttonCanvas.create_oval(120,120,180,180,fill="red") ! buttonCanvas.create_text(150,150,text="stop!\n") ! buttonCanvas.create_oval(220, 20,280, 80,fill="green") ! buttonCanvas.create_text(250, 50,text="takeoff ") ! buttonCanvas.create_oval(220,220,280,280,fill="green") ! buttonCanvas.create_text(250,250,text="land ") ! ! buttonCanvas.create_rectangle(0 ,310,300,340) ! buttonCanvas.create_text(150,325,text="motor 1") ! buttonCanvas.create_rectangle(0 ,360,300,390) ! buttonCanvas.create_text(150,375,text="motor 2") ! buttonCanvas.grid(row=1,column=0) ! ! #================================= main ============================= ! ! root.mainloop() --- 1,185 ---- ! import socket ! import binascii ! import time ! import os ! import Tkinter ! import sys ! ! MOTOR_MAX = 800 ! MOTOR_MIN = 0 ! MOTOR_STEP = 10 ! ! myAddress = '' # means 'any suitable interface' ! myPort = 2158 ! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' ! hisPort = 2192 ! ! motor1_command = 0 ! motor2_command = 0 ! ! print "Testing heli..." ! ! def heli_up(): ! global motor1_command, motor2_command ! if (motor1_command+MOTOR_STEP<=MOTOR_MAX and motor2_command+MOTOR_STEP<=MOTOR_MAX): ! motor1_command += MOTOR_STEP ! motor2_command += MOTOR_STEP ! sendCommand() ! ! def heli_down(): ! global motor1_command, motor2_command ! if (motor1_command-MOTOR_STEP>=MOTOR_MIN and motor2_command-MOTOR_STEP>=MOTOR_MIN): ! motor1_command -= MOTOR_STEP ! motor2_command -= MOTOR_STEP ! sendCommand() ! ! def heli_left(): ! global motor1_command ! if (motor1_command+MOTOR_STEP<=MOTOR_MAX): ! motor1_command += MOTOR_STEP ! sendCommand() ! ! def heli_right(): ! global motor1_command ! if (motor1_command-MOTOR_STEP>=MOTOR_MIN): ! motor1_command -= MOTOR_STEP ! sendCommand() ! ! def heli_stop(): ! global motor1_command, motor2_command ! motor1_command = 0 ! motor2_command = 0 ! sendCommand() ! ! def heli_takeoff(): ! global motor1_command, motor2_command ! motor1_command = 0x0260 ! motor2_command = 0x0260 ! sendCommand() ! ! def heli_land(): ! global motor1_command, motor2_command ! motor1_command = 0x0200 ! motor2_command = 0x0200 ! sendCommand() ! ! def key_pressed(event): ! if (event.char=='i'): ! heli_up() ! if (event.char=='j'): ! heli_left() ! if (event.char=='l'): ! heli_right() ! if (event.char=='k'): ! heli_down() ! if (event.char==' '): ! heli_stop() ! if (event.char=='a'): ! heli_takeoff() ! if (event.char=='q'): ! heli_land() ! ! def gui_clicked(event): ! global motor1_command, motor2_command ! if (event.x>100 and event.x<200 and event.y>0 and event.y<100): ! heli_up() ! if (event.x>0 and event.x<100 and event.y>100 and event.y<200): ! heli_left() ! if (event.x>200 and event.x<300 and event.y>100 and event.y<200): ! heli_right() ! if (event.x>100 and event.x<200 and event.y>200 and event.y<300): ! heli_down() ! if (event.x>100 and event.x<200 and event.y>100 and event.y<200): ! heli_stop() ! if (event.x>200 and event.x<300 and event.y>0 and event.y<100): ! heli_takeoff() ! if (event.x>200 and event.x<300 and event.y>200 and event.y<300): ! heli_land() ! if (event.y>310 and event.y<340): ! motor1_command = event.x/300.0*800.0 ! sendCommand() ! if (event.y>340 and event.y<360): ! motor_diff = motor1_command-motor2_command ! motor1_command = (event.x/300.0*800.0)+(motor_diff/2.0) ! if motor1_command>800: ! motor1_command=800 ! motor2_command = (event.x/300.0*800.0)-(motor_diff/2.0) ! if motor2_command>800: ! motor2_command=800 ! sendCommand() ! if (event.y>360 and event.y<390): ! motor2_command = event.x/300.0*800.0 ! sendCommand() ! ! def sendCommand(): ! #update the sliders ! buttonCanvas.delete("temp_slider") ! buttonCanvas.create_rectangle(0 ,310,(motor1_command/800.0)*300.0,340,fill="yellow",tag="temp_slider") ! buttonCanvas.create_rectangle(0 ,360,(motor2_command/800.0)*300.0,390,fill="yellow",tag="temp_slider") ! #send the command over UDP ! request = [] ! request.append(chr(int(motor1_command/256))) ! request.append(chr(int(motor1_command%256))) ! request.append(chr(int(motor2_command/256))) ! request.append(chr(int(motor2_command%256))) ! request = ''.join(request) ! hisAddress = addressText.get(1.0,Tkinter.END) ! hisAddress = hisAddress[0:len(hisAddress)-1] ! try: ! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) ! socket_handler.settimeout(5) ! socket_handler.bind((myAddress,myPort)) ! socket_handler.sendto(request,(hisAddress,hisPort)) ! except: ! addressText.config(background="red") ! else: ! addressText.config(background="green") ! ! #================================= GUI functions ==================== ! ! def releaseAndQuit(): ! root.quit() ! sys.exit() ! ! #================================= GUI definition =================== ! ! root=Tkinter.Tk() ! root.title("OpenHelicopter") ! root.protocol("WM_DELETE_WINDOW",releaseAndQuit) ! root.resizable(0,0) ! ! root.bind("",key_pressed) ! ! addressText = Tkinter.Text(root,width=50,height=1) ! #displayElements[motePort]["cellTable"]["TextField"].delete("1.0",Tkinter.END) ! addressText.insert(Tkinter.END,'2001:470:1f05:dff:1415:9209:22b:51') ! addressText.grid(row=0,column=0) ! ! buttonCanvas=Tkinter.Canvas(root,width=300,height=400) ! buttonCanvas.bind("",gui_clicked) ! buttonCanvas.bind("",gui_clicked) ! buttonCanvas.bind("",gui_clicked) ! buttonCanvas.create_rectangle(100, 0,200,100,fill="blue") ! buttonCanvas.create_text(150,50,text="up ") ! buttonCanvas.create_rectangle( 0,100,100,200,fill="blue") ! buttonCanvas.create_text(50,150,text="left ") ! buttonCanvas.create_rectangle(200,100,300,200,fill="blue") ! buttonCanvas.create_text(250,150,text="right ") ! buttonCanvas.create_rectangle(100,200,200,300,fill="blue") ! buttonCanvas.create_text(150,250,text="down ") ! buttonCanvas.create_oval(120,120,180,180,fill="red") ! buttonCanvas.create_text(150,150,text="stop!\n") ! buttonCanvas.create_oval(220, 20,280, 80,fill="green") ! buttonCanvas.create_text(250, 50,text="takeoff ") ! buttonCanvas.create_oval(220,220,280,280,fill="green") ! buttonCanvas.create_text(250,250,text="land ") ! ! buttonCanvas.create_rectangle(0 ,310,300,340) ! buttonCanvas.create_text(150,325,text="motor 1") ! buttonCanvas.create_rectangle(0 ,360,300,390) ! buttonCanvas.create_text(150,375,text="motor 2") ! buttonCanvas.grid(row=1,column=0) ! ! #================================= main ============================= ! ! root.mainloop() diff -crB openwsn/07-App/imu/imu.c ../../../sys/net/openwsn/07-App/imu/imu.c *** openwsn/07-App/imu/imu.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/imu/imu.c Wed Jan 15 13:48:27 2014 *************** *** 1,123 **** ! #include "openwsn.h" ! #include "imu.h" ! //drivers ! #include "gyro.h" ! #include "large_range_accel.h" ! #include "magnetometer.h" ! #include "sensitive_accel_temperature.h" ! //openwsn stack ! #include "openudp.h" ! #include "openqueue.h" ! #include "openserial.h" ! #include "packetfunctions.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! uint8_t mesurements_left; ! OpenQueueEntry_t* pktReceived; ! } imu_vars_t; ! ! imu_vars_t imu_vars; ! ! //=========================== prototypes ====================================== ! ! void imu_send(); ! void imu_reset(); ! ! //=========================== public ========================================== ! ! void imu_init() { ! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) ! gyro_init(); ! large_range_accel_init(); ! magnetometer_init(); ! sensitive_accel_temperature_init(); ! } ! imu_vars.mesurements_left = 0; ! } ! ! //this is called when the UdpGina button is pressed on the OpenVisualizer interface ! void imu_trigger() { ! } ! ! //I just received a request, send a packet with IMU data ! void imu_receive(OpenQueueEntry_t* msg) { ! msg->owner = COMPONENT_IMU; ! if (imu_vars.pktReceived==NULL) { ! imu_vars.pktReceived = msg; ! imu_vars.mesurements_left = imu_vars.pktReceived->payload[0]; ! imu_send(); ! } else { ! openqueue_freePacketBuffer(msg); ! } ! } ! ! //I just sent a IMU packet, check I need to resend one ! void imu_sendDone(OpenQueueEntry_t* msg, error_t error) { ! msg->owner = COMPONENT_IMU; ! if (msg->creator!=COMPONENT_IMU) { ! openserial_printError(COMPONENT_IMU,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! openqueue_freePacketBuffer(msg); ! if (imu_vars.mesurements_left>0) { ! imu_send(); ! } else { ! imu_reset(); ! } ! } ! ! bool imu_debugPrint() { ! return FALSE; ! } ! ! //=========================== private ========================================= ! ! void imu_send() { ! OpenQueueEntry_t* packetToSend; ! packetToSend = openqueue_getFreePacketBuffer(); ! if (packetToSend==NULL) { ! openserial_printError(COMPONENT_IMU,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! imu_reset(); ! return; ! } ! packetToSend->creator = COMPONENT_IMU; ! packetToSend->owner = COMPONENT_IMU; ! packetToSend->l4_protocol = IANA_UDP; ! packetToSend->l4_sourcePortORicmpv6Type = imu_vars.pktReceived->l4_destination_port; ! packetToSend->l4_destination_port = imu_vars.pktReceived->l4_sourcePortORicmpv6Type; ! packetToSend->l3_destinationORsource.type = ADDR_128B; ! memcpy(&(packetToSend->l3_destinationORsource.addr_128b[0]), ! &(imu_vars.pktReceived->l3_destinationORsource.addr_128b[0]), ! 16); ! //payload, gyro data ! packetfunctions_reserveHeaderSize(packetToSend,8); ! gyro_get_measurement(&(packetToSend->payload[0])); ! //payload, large_range_accel data ! packetfunctions_reserveHeaderSize(packetToSend,6); ! large_range_accel_get_measurement(&(packetToSend->payload[0])); ! //payload, magnetometer data ! packetfunctions_reserveHeaderSize(packetToSend,6); ! magnetometer_get_measurement(&(packetToSend->payload[0])); ! //payload, sensitive_accel_temperature data ! packetfunctions_reserveHeaderSize(packetToSend,10); ! sensitive_accel_temperature_get_measurement(&(packetToSend->payload[0])); ! //send packet ! if ((openudp_send(packetToSend))==E_FAIL) { ! openqueue_freePacketBuffer(packetToSend); ! imu_reset(); ! } ! imu_vars.mesurements_left--; ! } ! ! void imu_reset() { ! imu_vars.mesurements_left=0; ! if (imu_vars.pktReceived!=NULL) { ! openqueue_freePacketBuffer(imu_vars.pktReceived); ! imu_vars.pktReceived = NULL; ! } ! } --- 1,123 ---- ! #include "openwsn.h" ! #include "imu.h" ! //drivers ! #include "gyro.h" ! #include "large_range_accel.h" ! #include "magnetometer.h" ! #include "sensitive_accel_temperature.h" ! //openwsn stack ! #include "openudp.h" ! #include "openqueue.h" ! #include "openserial.h" ! #include "packetfunctions.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! uint8_t mesurements_left; ! OpenQueueEntry_t* pktReceived; ! } imu_vars_t; ! ! imu_vars_t imu_vars; ! ! //=========================== prototypes ====================================== ! ! void imu_send(); ! void imu_reset(); ! ! //=========================== public ========================================== ! ! void imu_init() { ! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) ! gyro_init(); ! large_range_accel_init(); ! magnetometer_init(); ! sensitive_accel_temperature_init(); ! } ! imu_vars.mesurements_left = 0; ! } ! ! //this is called when the UdpGina button is pressed on the OpenVisualizer interface ! void imu_trigger() { ! } ! ! //I just received a request, send a packet with IMU data ! void imu_receive(OpenQueueEntry_t* msg) { ! msg->owner = COMPONENT_IMU; ! if (imu_vars.pktReceived==NULL) { ! imu_vars.pktReceived = msg; ! imu_vars.mesurements_left = imu_vars.pktReceived->payload[0]; ! imu_send(); ! } else { ! openqueue_freePacketBuffer(msg); ! } ! } ! ! //I just sent a IMU packet, check I need to resend one ! void imu_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! msg->owner = COMPONENT_IMU; ! if (msg->creator!=COMPONENT_IMU) { ! openserial_printError(COMPONENT_IMU,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! openqueue_freePacketBuffer(msg); ! if (imu_vars.mesurements_left>0) { ! imu_send(); ! } else { ! imu_reset(); ! } ! } ! ! bool imu_debugPrint() { ! return FALSE; ! } ! ! //=========================== private ========================================= ! ! void imu_send() { ! OpenQueueEntry_t* packetToSend; ! packetToSend = openqueue_getFreePacketBuffer(); ! if (packetToSend==NULL) { ! openserial_printError(COMPONENT_IMU,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! imu_reset(); ! return; ! } ! packetToSend->creator = COMPONENT_IMU; ! packetToSend->owner = COMPONENT_IMU; ! packetToSend->l4_protocol = IANA_UDP; ! packetToSend->l4_sourcePortORicmpv6Type = imu_vars.pktReceived->l4_destination_port; ! packetToSend->l4_destination_port = imu_vars.pktReceived->l4_sourcePortORicmpv6Type; ! packetToSend->l3_destinationORsource.type = ADDR_128B; ! memcpy(&(packetToSend->l3_destinationORsource.addr_128b[0]), ! &(imu_vars.pktReceived->l3_destinationORsource.addr_128b[0]), ! 16); ! //payload, gyro data ! packetfunctions_reserveHeaderSize(packetToSend,8); ! gyro_get_measurement(&(packetToSend->payload[0])); ! //payload, large_range_accel data ! packetfunctions_reserveHeaderSize(packetToSend,6); ! large_range_accel_get_measurement(&(packetToSend->payload[0])); ! //payload, magnetometer data ! packetfunctions_reserveHeaderSize(packetToSend,6); ! magnetometer_get_measurement(&(packetToSend->payload[0])); ! //payload, sensitive_accel_temperature data ! packetfunctions_reserveHeaderSize(packetToSend,10); ! sensitive_accel_temperature_get_measurement(&(packetToSend->payload[0])); ! //send packet ! if ((openudp_send(packetToSend))==E_FAIL) { ! openqueue_freePacketBuffer(packetToSend); ! imu_reset(); ! } ! imu_vars.mesurements_left--; ! } ! ! void imu_reset() { ! imu_vars.mesurements_left=0; ! if (imu_vars.pktReceived!=NULL) { ! openqueue_freePacketBuffer(imu_vars.pktReceived); ! imu_vars.pktReceived = NULL; ! } ! } diff -crB openwsn/07-App/imu/imu.h ../../../sys/net/openwsn/07-App/imu/imu.h *** openwsn/07-App/imu/imu.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/imu/imu.h Wed Jan 15 13:48:27 2014 *************** *** 1,30 **** ! #ifndef __IMU_H ! #define __IMU_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup imu ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void imu_init(); ! void imu_trigger(); ! void imu_sendDone(OpenQueueEntry_t* msg, error_t error); ! void imu_receive(OpenQueueEntry_t* msg); ! bool imu_debugPrint(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,30 ---- ! #ifndef __IMU_H ! #define __IMU_H ! ! /** ! \addtogroup AppUdp ! \{ ! \addtogroup imu ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void imu_init(); ! void imu_trigger(); ! void imu_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! void imu_receive(OpenQueueEntry_t* msg); ! bool imu_debugPrint(); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/imu/imu.py ../../../sys/net/openwsn/07-App/imu/imu.py *** openwsn/07-App/imu/imu.py Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/imu/imu.py Wed Jan 15 13:48:27 2014 *************** *** 1,62 **** ! import socket ! import binascii ! import time ! import os ! ! num_measurements = str(chr(0x64)) # (100)d ! myAddress = '' # means 'any suitable interface' ! myPort = 2158 ! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' ! hisPort = 2190 ! ! print "Testing imu..." ! ! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) ! socket_handler.settimeout(5) ! socket_handler.bind((myAddress,myPort)) ! socket_handler.sendto(num_measurements,(hisAddress,hisPort)) ! print "\nrequest "+myAddress+"%"+str(myPort)+" -> "+hisAddress+"%"+str(hisPort) ! print num_measurements+" ("+str(len(num_measurements))+" bytes)" ! ! time_first = time.time() ! replycounter = 0 ! while (1): ! try: ! reply,dist_addr = socket_handler.recvfrom(1024) ! except socket.timeout: ! print "\nno further replies, it seems\n" ! break ! else: ! time_last = time.time() ! os.system("CLS") ! print "\nreply "+str(replycounter)+": "+str(dist_addr[0])+"%"+str(dist_addr[1])+" -> "+myAddress+"%"+str(myPort)+" ("+str(len(reply))+" bytes)\n" ! replycounter += 1 ! ! print "sensitive_accel X : "+str(ord(reply[0])) ! print " Y : "+binascii.hexlify(reply[ 2: 4]) ! print " Z1 : "+binascii.hexlify(reply[ 4: 6]) ! print " Z3 : "+binascii.hexlify(reply[ 6: 8])+"\n" ! ! print "temperature : "+binascii.hexlify(reply[ 8:10])+"\n" ! ! print "magnetometer X : "+binascii.hexlify(reply[10:12]) ! print " Y : "+binascii.hexlify(reply[12:14]) ! print " Z : "+binascii.hexlify(reply[14:16])+"\n" ! ! print "large_range_accel X : "+binascii.hexlify(reply[16:18]) ! print " Y : "+binascii.hexlify(reply[18:20]) ! print " Z : "+binascii.hexlify(reply[20:22])+"\n" ! ! print "gyro_temperature : "+binascii.hexlify(reply[22:24]) ! print "gyro X : "+binascii.hexlify(reply[24:26]) ! print " Y : "+binascii.hexlify(reply[26:28]) ! print " Z : "+binascii.hexlify(reply[28:30]) ! ! socket_handler.close() ! ! try: ! print str(replycounter)+" replies in "+str(time_last-time_first)+"s (one every "+str((time_last-time_first)/(replycounter-1))+"s)" ! except: ! pass ! ! raw_input("\nPress return to close this window...") --- 1,62 ---- ! import socket ! import binascii ! import time ! import os ! ! num_measurements = str(chr(0x64)) # (100)d ! myAddress = '' # means 'any suitable interface' ! myPort = 2158 ! hisAddress = '2001:470:1f05:dff:1415:9209:22b:51' ! hisPort = 2190 ! ! print "Testing imu..." ! ! socket_handler = socket.socket(socket.AF_INET6,socket.SOCK_DGRAM) ! socket_handler.settimeout(5) ! socket_handler.bind((myAddress,myPort)) ! socket_handler.sendto(num_measurements,(hisAddress,hisPort)) ! print "\nrequest "+myAddress+"%"+str(myPort)+" -> "+hisAddress+"%"+str(hisPort) ! print num_measurements+" ("+str(len(num_measurements))+" bytes)" ! ! time_first = time.time() ! replycounter = 0 ! while (1): ! try: ! reply,dist_addr = socket_handler.recvfrom(1024) ! except socket.timeout: ! print "\nno further replies, it seems\n" ! break ! else: ! time_last = time.time() ! os.system("CLS") ! print "\nreply "+str(replycounter)+": "+str(dist_addr[0])+"%"+str(dist_addr[1])+" -> "+myAddress+"%"+str(myPort)+" ("+str(len(reply))+" bytes)\n" ! replycounter += 1 ! ! print "sensitive_accel X : "+str(ord(reply[0])) ! print " Y : "+binascii.hexlify(reply[ 2: 4]) ! print " Z1 : "+binascii.hexlify(reply[ 4: 6]) ! print " Z3 : "+binascii.hexlify(reply[ 6: 8])+"\n" ! ! print "temperature : "+binascii.hexlify(reply[ 8:10])+"\n" ! ! print "magnetometer X : "+binascii.hexlify(reply[10:12]) ! print " Y : "+binascii.hexlify(reply[12:14]) ! print " Z : "+binascii.hexlify(reply[14:16])+"\n" ! ! print "large_range_accel X : "+binascii.hexlify(reply[16:18]) ! print " Y : "+binascii.hexlify(reply[18:20]) ! print " Z : "+binascii.hexlify(reply[20:22])+"\n" ! ! print "gyro_temperature : "+binascii.hexlify(reply[22:24]) ! print "gyro X : "+binascii.hexlify(reply[24:26]) ! print " Y : "+binascii.hexlify(reply[26:28]) ! print " Z : "+binascii.hexlify(reply[28:30]) ! ! socket_handler.close() ! ! try: ! print str(replycounter)+" replies in "+str(time_last-time_first)+"s (one every "+str((time_last-time_first)/(replycounter-1))+"s)" ! except: ! pass ! ! raw_input("\nPress return to close this window...") diff -crB openwsn/07-App/layerdebug/layerdebug.c ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.c *** openwsn/07-App/layerdebug/layerdebug.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.c Wed Jan 15 13:48:27 2014 *************** *** 1,301 **** ! #include "openwsn.h" ! #include "layerdebug.h" ! #include "opencoap.h" ! #include "opentimers.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "scheduler.h" ! ! ! // include layer files to debug ! #include "neighbors.h" ! #include "schedule.h" ! //=========================== defines ========================================= ! ! /// inter-packet period (in ms) ! #define DEBUGPERIODNBS 11000 ! #define DEBUGPERIODSCH 7000 ! ! const uint8_t schedule_layerdebug_path0[] = "d_s"; // debug/scheduling ! const uint8_t neighbors_layerdebug_path0[] = "d_n"; // debug/neighbours ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t schdesc; ///< descriptor for shedule table ! coap_resource_desc_t nbsdesc; ///< descriptor for neigbour table ! opentimer_id_t schtimerId; ///< schedule timer ! opentimer_id_t nbstimerId; ///< neigbour timer ! } layerdebug_vars_t; ! ! layerdebug_vars_t layerdebug_vars; ! ! //=========================== prototypes ====================================== ! ! error_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! ! ! error_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! ! void layerdebug_timer_schedule_cb(); ! void layerdebug_timer_neighbors_cb(); ! ! void layerdebug_task_schedule_cb(); ! void layerdebug_task_neighbors_cb(); ! ! void layerdebug_sendDone(OpenQueueEntry_t* msg, ! error_t error); ! ! //=========================== public ========================================== ! ! void layerdebug_init() { ! ! // prepare the resource descriptor for the scheduling path ! layerdebug_vars.schdesc.path0len = sizeof(schedule_layerdebug_path0)-1; ! layerdebug_vars.schdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); ! layerdebug_vars.schdesc.path1len = 0; ! layerdebug_vars.schdesc.path1val = NULL; ! layerdebug_vars.schdesc.componentID = COMPONENT_LAYERDEBUG; ! layerdebug_vars.schdesc.callbackRx = &layerdebug_schedule_receive; ! layerdebug_vars.schdesc.callbackSendDone = &layerdebug_sendDone; ! opencoap_register(&layerdebug_vars.schdesc); ! ! layerdebug_vars.schtimerId = opentimers_start(DEBUGPERIODSCH, ! TIMER_PERIODIC,TIME_MS, ! layerdebug_timer_schedule_cb); ! ! // prepare the resource descriptor for the neighbors path ! layerdebug_vars.nbsdesc.path0len = sizeof(schedule_layerdebug_path0)-1; ! layerdebug_vars.nbsdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); ! layerdebug_vars.nbsdesc.path1len = 0; ! layerdebug_vars.nbsdesc.path1val = NULL; ! layerdebug_vars.nbsdesc.componentID = COMPONENT_LAYERDEBUG; ! layerdebug_vars.nbsdesc.callbackRx = &layerdebug_neighbors_receive; ! layerdebug_vars.nbsdesc.callbackSendDone = &layerdebug_sendDone; ! opencoap_register(&layerdebug_vars.nbsdesc); ! ! layerdebug_vars.nbstimerId = opentimers_start(DEBUGPERIODNBS, ! TIMER_PERIODIC,TIME_MS, ! layerdebug_timer_neighbors_cb); ! } ! ! //=========================== private ========================================= ! ! //timer fired, but we don't want to execute task in ISR mode ! //instead, push task to scheduler with COAP priority, and let scheduler take care of it ! void layerdebug_timer_schedule_cb(){ ! scheduler_push_task(layerdebug_task_schedule_cb,TASKPRIO_COAP); ! } ! ! void layerdebug_timer_neighbors_cb(){ ! scheduler_push_task(layerdebug_task_neighbors_cb,TASKPRIO_COAP); ! } ! ! //schedule stats ! void layerdebug_task_schedule_cb() { ! OpenQueueEntry_t* pkt; ! error_t outcome; ! uint8_t numOptions; ! uint8_t size; ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_LAYERDEBUG; ! pkt->owner = COMPONENT_LAYERDEBUG; ! // CoAP payload ! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; ! packetfunctions_reserveHeaderSize(pkt,size);//reserve for some schedule entries ! //get the schedule information from the mac layer ! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)pkt->payload); ! ! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of schedule entries ! pkt->payload[0] = MAXACTIVESLOTS; ! ! ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(schedule_layerdebug_path0)-1); ! memcpy(&pkt->payload[0],&schedule_layerdebug_path0,sizeof(schedule_layerdebug_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | ! sizeof(schedule_layerdebug_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &layerdebug_vars.schdesc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! return; ! } ! ! //neighbours stats ! void layerdebug_task_neighbors_cb() { ! ! OpenQueueEntry_t* pkt; ! error_t outcome; ! uint8_t numOptions; ! uint8_t size; ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_LAYERDEBUG; ! pkt->owner = COMPONENT_LAYERDEBUG; ! // CoAP payload ! ! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent ! packetfunctions_reserveHeaderSize(pkt,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries ! ! debugNetPrint_neighbors((netDebugNeigborEntry_t*) pkt->payload); ! ! //now we know the size of the neihbours. Put it on the packet. ! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of neighbours entries ! pkt->payload[0] = size; ! ! //coap options ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(neighbors_layerdebug_path0)-1); ! memcpy(&pkt->payload[0],&neighbors_layerdebug_path0,sizeof(neighbors_layerdebug_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | ! sizeof(neighbors_layerdebug_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &layerdebug_vars.nbsdesc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! return; ! } ! ! void layerdebug_sendDone(OpenQueueEntry_t* msg, error_t error) { ! openqueue_freePacketBuffer(msg); ! } ! ! ! error_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! error_t outcome; ! uint8_t size; ! ! ! if (coap_header->Code==COAP_CODE_REQ_GET) { ! // return current schedule value ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; ! packetfunctions_reserveHeaderSize(msg,size);//reserve for some schedule entries ! //get the schedule information from the mac layer ! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)msg->payload); ! ! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of schedule entries ! msg->payload[0] = MAXACTIVESLOTS; ! ! // set the CoAP header ! coap_header->OC = 0; ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! ! } else { ! // return an error message ! outcome = E_FAIL; ! } ! ! return outcome; ! } ! ! error_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! error_t outcome; ! uint8_t size; ! ! ! if (coap_header->Code==COAP_CODE_REQ_GET) { ! // return current schedule value ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent ! packetfunctions_reserveHeaderSize(msg,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries ! ! debugNetPrint_neighbors((netDebugNeigborEntry_t*)msg->payload); ! ! //now we know the size of the neihbours. Put it on the packet. ! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of neighbours entries ! msg->payload[0] = size; ! ! // set the CoAP header ! coap_header->OC = 0; ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! ! } else { ! // return an error message ! outcome = E_FAIL; ! } ! ! return outcome; } \ No newline at end of file --- 1,310 ---- ! #include "openwsn.h" ! #include "layerdebug.h" ! #include "opencoap.h" ! #include "opentimers.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "scheduler.h" ! #include "IEEE802154E.h" ! #include "idmanager.h" ! ! // include layer files to debug ! #include "neighbors.h" ! #include "schedule.h" ! //=========================== defines ========================================= ! ! /// inter-packet period (in ms) ! #define DEBUGPERIODNBS 11000 ! #define DEBUGPERIODSCH 7000 ! ! const uint8_t schedule_layerdebug_path0[] = "d_s"; // debug/scheduling ! const uint8_t neighbors_layerdebug_path0[] = "d_n"; // debug/neighbours ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t schdesc; ///< descriptor for shedule table ! coap_resource_desc_t nbsdesc; ///< descriptor for neigbour table ! opentimer_id_t schtimerId; ///< schedule timer ! opentimer_id_t nbstimerId; ///< neigbour timer ! } layerdebug_vars_t; ! ! layerdebug_vars_t layerdebug_vars; ! ! //=========================== prototypes ====================================== ! ! owerror_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! ! ! owerror_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! ! void layerdebug_timer_schedule_cb(); ! void layerdebug_timer_neighbors_cb(); ! ! void layerdebug_task_schedule_cb(); ! void layerdebug_task_neighbors_cb(); ! ! void layerdebug_sendDone(OpenQueueEntry_t* msg, ! owerror_t error); ! ! //=========================== public ========================================== ! ! void layerdebug_init() { ! ! // prepare the resource descriptor for the scheduling path ! layerdebug_vars.schdesc.path0len = sizeof(schedule_layerdebug_path0)-1; ! layerdebug_vars.schdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); ! layerdebug_vars.schdesc.path1len = 0; ! layerdebug_vars.schdesc.path1val = NULL; ! layerdebug_vars.schdesc.componentID = COMPONENT_LAYERDEBUG; ! layerdebug_vars.schdesc.callbackRx = &layerdebug_schedule_receive; ! layerdebug_vars.schdesc.callbackSendDone = &layerdebug_sendDone; ! opencoap_register(&layerdebug_vars.schdesc); ! ! layerdebug_vars.schtimerId = opentimers_start(DEBUGPERIODSCH, ! TIMER_PERIODIC,TIME_MS, ! layerdebug_timer_schedule_cb); ! ! // prepare the resource descriptor for the neighbors path ! layerdebug_vars.nbsdesc.path0len = sizeof(schedule_layerdebug_path0)-1; ! layerdebug_vars.nbsdesc.path0val = (uint8_t*)(&schedule_layerdebug_path0); ! layerdebug_vars.nbsdesc.path1len = 0; ! layerdebug_vars.nbsdesc.path1val = NULL; ! layerdebug_vars.nbsdesc.componentID = COMPONENT_LAYERDEBUG; ! layerdebug_vars.nbsdesc.callbackRx = &layerdebug_neighbors_receive; ! layerdebug_vars.nbsdesc.callbackSendDone = &layerdebug_sendDone; ! opencoap_register(&layerdebug_vars.nbsdesc); ! ! layerdebug_vars.nbstimerId = opentimers_start(DEBUGPERIODNBS, ! TIMER_PERIODIC,TIME_MS, ! layerdebug_timer_neighbors_cb); ! } ! ! //=========================== private ========================================= ! ! //timer fired, but we don't want to execute task in ISR mode ! //instead, push task to scheduler with COAP priority, and let scheduler take care of it ! void layerdebug_timer_schedule_cb(){ ! scheduler_push_task(layerdebug_task_schedule_cb,TASKPRIO_COAP); ! } ! ! void layerdebug_timer_neighbors_cb(){ ! scheduler_push_task(layerdebug_task_neighbors_cb,TASKPRIO_COAP); ! } ! ! //schedule stats ! void layerdebug_task_schedule_cb() { ! OpenQueueEntry_t* pkt; ! owerror_t outcome; ! uint8_t numOptions; ! uint8_t size; ! ! // don't run if not synch ! if (ieee154e_isSynch() == FALSE) return; ! ! // don't run on dagroot ! if (idmanager_getIsDAGroot()) { ! opentimers_stop( layerdebug_vars.schtimerId); ! opentimers_stop( layerdebug_vars.nbstimerId); ! return; ! } ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_LAYERDEBUG; ! pkt->owner = COMPONENT_LAYERDEBUG; ! // CoAP payload ! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; ! packetfunctions_reserveHeaderSize(pkt,size);//reserve for some schedule entries ! //get the schedule information from the mac layer ! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)pkt->payload); ! ! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of schedule entries ! pkt->payload[0] = MAXACTIVESLOTS; ! ! ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(schedule_layerdebug_path0)-1); ! memcpy(&pkt->payload[0],&schedule_layerdebug_path0,sizeof(schedule_layerdebug_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | ! sizeof(schedule_layerdebug_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &layerdebug_vars.schdesc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! return; ! } ! ! //neighbours stats ! void layerdebug_task_neighbors_cb() { ! ! OpenQueueEntry_t* pkt; ! owerror_t outcome; ! uint8_t numOptions; ! uint8_t size; ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_LAYERDEBUG); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_LAYERDEBUG,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_LAYERDEBUG; ! pkt->owner = COMPONENT_LAYERDEBUG; ! // CoAP payload ! ! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent ! packetfunctions_reserveHeaderSize(pkt,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries ! ! debugNetPrint_neighbors((netDebugNeigborEntry_t*) pkt->payload); ! ! //now we know the size of the neihbours. Put it on the packet. ! packetfunctions_reserveHeaderSize(pkt,1);//reserve for the size of neighbours entries ! pkt->payload[0] = size; ! ! //coap options ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(neighbors_layerdebug_path0)-1); ! memcpy(&pkt->payload[0],&neighbors_layerdebug_path0,sizeof(neighbors_layerdebug_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | ! sizeof(neighbors_layerdebug_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_local,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &layerdebug_vars.nbsdesc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! return; ! } ! ! void layerdebug_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! openqueue_freePacketBuffer(msg); ! } ! ! ! owerror_t layerdebug_schedule_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! owerror_t outcome; ! uint8_t size; ! ! ! if (coap_header->Code==COAP_CODE_REQ_GET) { ! // return current schedule value ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! size=sizeof(netDebugScheduleEntry_t)*MAXACTIVESLOTS; ! packetfunctions_reserveHeaderSize(msg,size);//reserve for some schedule entries ! //get the schedule information from the mac layer ! schedule_getNetDebugInfo((netDebugScheduleEntry_t*)msg->payload); ! ! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of schedule entries ! msg->payload[0] = MAXACTIVESLOTS; ! ! // set the CoAP header ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! ! } else { ! // return an error message ! outcome = E_FAIL; ! } ! ! return outcome; ! } ! ! owerror_t layerdebug_neighbors_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! owerror_t outcome; ! uint8_t size; ! ! ! if (coap_header->Code==COAP_CODE_REQ_GET) { ! // return current schedule value ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! size=neighbors_getNumNeighbors(); //compute the number of neigbours sent ! packetfunctions_reserveHeaderSize(msg,size*sizeof(netDebugNeigborEntry_t));//reserve for the size of schedule entries ! ! debugNetPrint_neighbors((netDebugNeigborEntry_t*)msg->payload); ! ! //now we know the size of the neihbours. Put it on the packet. ! packetfunctions_reserveHeaderSize(msg,1);//reserve for the size of neighbours entries ! msg->payload[0] = size; ! ! // set the CoAP header ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! ! } else { ! // return an error message ! outcome = E_FAIL; ! } ! ! return outcome; } \ No newline at end of file diff -crB openwsn/07-App/layerdebug/layerdebug.h ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.h *** openwsn/07-App/layerdebug/layerdebug.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/layerdebug/layerdebug.h Wed Jan 15 13:48:27 2014 *************** *** 1,26 **** ! #ifndef __LAYERDEBUG_H ! #define __LAYERDEBUG_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup rT ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void layerdebug_init(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,26 ---- ! #ifndef __LAYERDEBUG_H ! #define __LAYERDEBUG_H ! ! /** ! \addtogroup AppCoAP ! \{ ! \addtogroup rT ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void layerdebug_init(); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/ohlone/Makefile ../../../sys/net/openwsn/07-App/ohlone/Makefile *** openwsn/07-App/ohlone/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/07-App/ohlone/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) + $(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 + $(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_indexlength-3;payload_index++) { ! if (ohlone_check4chars(msg->payload+payload_index,(unsigned char *) "GET ")) ! memcpy(ohlone_vars.getRequest, ! msg->payload + payload_index + 4, ! msg->length - payload_index - 4); ! ! if (ohlone_check4chars(msg->payload+payload_index, (unsigned char *)"\r\n\r\n")) { ! ohlone_vars.httpChunk = 0; ! ohlone_sendpkt(); ! return; ! } ! } ! openserial_printData((uint8_t*)(msg->payload),msg->length); ! openqueue_freePacketBuffer(msg); ! } ! ! void ohlone_sendDone(OpenQueueEntry_t* msg, error_t error) { ! msg->owner = COMPONENT_OHLONE; ! if (msg->creator!=COMPONENT_OHLONE) { ! openserial_printError(COMPONENT_OHLONE,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! ! ohlone_sendpkt(); ! openqueue_freePacketBuffer(msg); ! } ! ! void ohlone_connectDone(error_t error) { ! } ! ! bool ohlone_debugPrint() { ! return FALSE; ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,113 ---- ! #include "openwsn.h" ! #include "ohlone.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "opentcp.h" ! ! #include "ohlone_webpages.h" ! ! //=========================== variables ======================================= ! ! ohlone_vars_t ohlone_vars; ! ! //=========================== prototypes ====================================== ! ! void ohlone_sendpkt(void); ! bool ohlone_check4chars(uint8_t c1[4], uint8_t c2[4]); ! ! //=========================== public ========================================== ! ! void ohlone_init(void) { ! ohlone_vars.httpChunk = 0; ! ohlone_vars.getRequest[0] = '/'; ! ohlone_vars.getRequest[1] = ' '; ! ohlone_webpages_init(); ! } ! ! bool ohlone_shouldIlisten(void) { ! return TRUE; ! } ! ! void ohlone_sendpkt(void) { ! uint8_t buffer[TCP_DEFAULT_WINDOW_SIZE]; ! uint8_t buffer_len; ! ! buffer_len = ohlone_webpage(ohlone_vars.getRequest, ohlone_vars.httpChunk++, buffer); ! ! if (buffer_len == 0) { ! // No more to send ! // close TCP session, but keep listening ! ohlone_vars.getRequest[0] = '/'; ! ohlone_vars.getRequest[1] = ' '; ! opentcp_close(); ! return; ! } ! ! ohlone_vars.pkt = openqueue_getFreePacketBuffer(COMPONENT_OHLONE); ! if (ohlone_vars.pkt==NULL) { ! openserial_printError(COMPONENT_OHLONE,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! opentcp_close(); ! return; ! } ! ohlone_vars.pkt->creator = COMPONENT_OHLONE; ! ohlone_vars.pkt->owner = COMPONENT_OHLONE; ! ! packetfunctions_reserveHeaderSize(ohlone_vars.pkt, buffer_len); ! memcpy(ohlone_vars.pkt->payload, buffer, buffer_len); ! ! if ((opentcp_send(ohlone_vars.pkt))==E_FAIL) { ! openqueue_freePacketBuffer(ohlone_vars.pkt); ! opentcp_close(); ! } ! ! } ! ! bool ohlone_check4chars(uint8_t c1[4], uint8_t c2[4]) { ! return ((c1[0] == c2[0]) && ! (c1[1] == c2[1]) && ! (c1[2] == c2[2]) && ! (c1[3] == c2[3])); ! } ! ! void ohlone_receive(OpenQueueEntry_t* msg) { ! uint8_t payload_index; ! ! for (payload_index=0;payload_indexlength-3;payload_index++) { ! if (ohlone_check4chars(msg->payload+payload_index,(unsigned char *) "GET ")) ! memcpy(ohlone_vars.getRequest, ! msg->payload + payload_index + 4, ! msg->length - payload_index - 4); ! ! if (ohlone_check4chars(msg->payload+payload_index, (unsigned char *)"\r\n\r\n")) { ! ohlone_vars.httpChunk = 0; ! ohlone_sendpkt(); ! return; ! } ! } ! openserial_printData((uint8_t*)(msg->payload),msg->length); ! openqueue_freePacketBuffer(msg); ! } ! ! void ohlone_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! msg->owner = COMPONENT_OHLONE; ! if (msg->creator!=COMPONENT_OHLONE) { ! openserial_printError(COMPONENT_OHLONE,ERR_UNEXPECTED_SENDDONE, ! (errorparameter_t)0, ! (errorparameter_t)0); ! } ! ! ohlone_sendpkt(); ! openqueue_freePacketBuffer(msg); ! } ! ! void ohlone_connectDone(owerror_t error) { ! } ! ! bool ohlone_debugPrint(void) { ! return FALSE; ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/07-App/ohlone/ohlone.h ../../../sys/net/openwsn/07-App/ohlone/ohlone.h *** openwsn/07-App/ohlone/ohlone.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/ohlone/ohlone.h Wed Jan 15 13:48:27 2014 *************** *** 1,31 **** ! #ifndef __OHLONE_H ! #define __OHLONE_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup ohlone ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void ohlone_init(); ! bool ohlone_shouldIlisten(); ! void ohlone_receive(OpenQueueEntry_t* msg); ! void ohlone_sendDone(OpenQueueEntry_t* msg, error_t error); ! void ohlone_connectDone(error_t error); ! bool ohlone_debugPrint(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,40 ---- ! #ifndef __OHLONE_H ! #define __OHLONE_H ! ! /** ! \addtogroup AppTcp ! \{ ! \addtogroup ohlone ! \{ ! */ ! ! #include "opentcp.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== module variables ================================ ! ! typedef struct { ! OpenQueueEntry_t* pkt; ! bool sending; ! uint16_t httpChunk; ! uint8_t getRequest[TCP_DEFAULT_WINDOW_SIZE]; ! } ohlone_vars_t; ! ! //=========================== prototypes ====================================== ! ! void ohlone_init(void); ! bool ohlone_shouldIlisten(void); ! void ohlone_receive(OpenQueueEntry_t* msg); ! void ohlone_sendDone(OpenQueueEntry_t* msg, owerror_t error); ! void ohlone_connectDone(owerror_t error); ! bool ohlone_debugPrint(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/ohlone/ohlone_webpages.c ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.c *** openwsn/07-App/ohlone/ohlone_webpages.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.c Wed Jan 15 13:48:27 2014 *************** *** 1,94 **** ! /** ! \brief Webpgages for Ohlone ! ! \author Ankur Mehta , September 2010 ! */ ! ! #include "openwsn.h" ! #include "ohlone_webpages.h" ! ! /* ! #include "gyro.h" ! #include "large_range_accel.h" ! #include "magnetometer.h" ! #include "sensitive_accel_temperature.h" ! */ ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place); ! void ohlone_line_replace16(uint8_t *buffer, uint16_t value); ! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensors); ! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensors); ! ! //=========================== public ========================================== ! ! void ohlone_webpages_init() { ! /* ! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) ! gyro_init(); ! large_range_accel_init(); ! magnetometer_init(); ! sensitive_accel_temperature_init(); ! } ! */ ! } ! ! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet) { ! // TODO : enforce max of TCP_DEFAULT_WINDOW_SIZE ! uint8_t len = 0; ! uint8_t current_line = 0; ! current_line--; ! ! HTTP_LINE("HTTP/1.1 200 OK\r\n\r\n"); ! ! switch (*(getRequest + 1)) { ! ! default: ! memcpy(packet + len, ":)", 2); ! len += 2; ! } ! ! return len; ! } ! ! //=========================== private ========================================= ! ! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place) { ! uint8_t digit = '0'; ! while (value > place) { ! value -= place; ! digit++; ! } ! *buffer = digit; ! return value; ! } ! ! void ohlone_line_replace16(uint8_t *buffer, uint16_t value) { ! value = ohlone_replace_digit(buffer++, value, 10000); ! value = ohlone_replace_digit(buffer++, value, 1000); ! value = ohlone_replace_digit(buffer++, value, 100); ! value = ohlone_replace_digit(buffer++, value, 10); ! value = ohlone_replace_digit(buffer++, value, 1); ! } ! ! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensordata) { ! uint8_t len = 0; ! ohlone_line_replace16(buffer + len, (sensordata[0] << 8) + sensordata[1]); ! len += 5; buffer[len++] = ','; ! ohlone_line_replace16(buffer + len, (sensordata[2] << 8) + sensordata[3]); ! len += 5; buffer[len++] = ','; ! ohlone_line_replace16(buffer + len, (sensordata[4] << 8) + sensordata[5]); ! len += 5; ! return len; ! } ! ! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensordata) { ! uint8_t len = ohlone_insert3sensors(buffer, sensordata); ! buffer[len++] = ','; ! ohlone_line_replace16(buffer + len, (sensordata[6] << 8) + sensordata[7]); ! len += 5; ! return len; } \ No newline at end of file --- 1,94 ---- ! /** ! \brief Webpgages for Ohlone ! ! \author Ankur Mehta , September 2010 ! */ ! ! #include "openwsn.h" ! #include "ohlone_webpages.h" ! ! /* ! #include "gyro.h" ! #include "large_range_accel.h" ! #include "magnetometer.h" ! #include "sensitive_accel_temperature.h" ! */ ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place); ! void ohlone_line_replace16(uint8_t *buffer, uint16_t value); ! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensors); ! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensors); ! ! //=========================== public ========================================== ! ! void ohlone_webpages_init(void) { ! /* ! if (*(&eui64+3)==0x09) { // this is a GINA board (not a basestation) ! gyro_init(); ! large_range_accel_init(); ! magnetometer_init(); ! sensitive_accel_temperature_init(); ! } ! */ ! } ! ! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet) { ! // TODO : enforce max of TCP_DEFAULT_WINDOW_SIZE ! uint8_t len = 0; ! uint8_t current_line = 0; ! current_line--; ! ! HTTP_LINE("HTTP/1.1 200 OK\r\n\r\n"); ! ! switch (*(getRequest + 1)) { ! ! default: ! memcpy(packet + len, ":)", 2); ! len += 2; ! } ! ! return len; ! } ! ! //=========================== private ========================================= ! ! uint16_t ohlone_replace_digit(uint8_t *buffer, uint16_t value, uint16_t place) { ! uint8_t digit = '0'; ! while (value > place) { ! value -= place; ! digit++; ! } ! *buffer = digit; ! return value; ! } ! ! void ohlone_line_replace16(uint8_t *buffer, uint16_t value) { ! value = ohlone_replace_digit(buffer++, value, 10000); ! value = ohlone_replace_digit(buffer++, value, 1000); ! value = ohlone_replace_digit(buffer++, value, 100); ! value = ohlone_replace_digit(buffer++, value, 10); ! value = ohlone_replace_digit(buffer++, value, 1); ! } ! ! uint8_t ohlone_insert3sensors(uint8_t *buffer, uint8_t *sensordata) { ! uint8_t len = 0; ! ohlone_line_replace16(buffer + len, (sensordata[0] << 8) + sensordata[1]); ! len += 5; buffer[len++] = ','; ! ohlone_line_replace16(buffer + len, (sensordata[2] << 8) + sensordata[3]); ! len += 5; buffer[len++] = ','; ! ohlone_line_replace16(buffer + len, (sensordata[4] << 8) + sensordata[5]); ! len += 5; ! return len; ! } ! ! uint8_t ohlone_insert4sensors(uint8_t *buffer, uint8_t *sensordata) { ! uint8_t len = ohlone_insert3sensors(buffer, sensordata); ! buffer[len++] = ','; ! ohlone_line_replace16(buffer + len, (sensordata[6] << 8) + sensordata[7]); ! len += 5; ! return len; } \ No newline at end of file diff -crB openwsn/07-App/ohlone/ohlone_webpages.h ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.h *** openwsn/07-App/ohlone/ohlone_webpages.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/ohlone/ohlone_webpages.h Wed Jan 15 13:48:27 2014 *************** *** 1,33 **** ! /** ! \brief Webpages for Ohlone ! ! \author Ankur Mehta , September 2010 ! */ ! ! #ifndef __OHLONEWEBPAGES_H ! #define __OHLONEWEBPAGES_H ! ! //=========================== define ========================================== ! ! #define HTTP_LINE(str) { \ ! if (chunk == ++current_line) { \ ! memcpy(packet, str, sizeof(str)-1); \ ! len = sizeof(str)-1; \ ! } \ ! } ! ! #define HTTP_LINE_REPLACE16(offset, value) { \ ! if (chunk == current_line) \ ! ohlone_line_replace16(packet+offset, value); \ ! } ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void ohlone_webpages_init(); ! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet); ! #endif \ No newline at end of file --- 1,33 ---- ! /** ! \brief Webpages for Ohlone ! ! \author Ankur Mehta , September 2010 ! */ ! ! #ifndef __OHLONEWEBPAGES_H ! #define __OHLONEWEBPAGES_H ! ! //=========================== define ========================================== ! ! #define HTTP_LINE(str) { \ ! if (chunk == ++current_line) { \ ! memcpy(packet, str, sizeof(str)-1); \ ! len = sizeof(str)-1; \ ! } \ ! } ! ! #define HTTP_LINE_REPLACE16(offset, value) { \ ! if (chunk == current_line) \ ! ohlone_line_replace16(packet+offset, value); \ ! } ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void ohlone_webpages_init(void); ! uint8_t ohlone_webpage(uint8_t *getRequest, uint16_t chunk, uint8_t *packet); ! #endif \ No newline at end of file diff -crB openwsn/07-App/r6tus/r6tus.c ../../../sys/net/openwsn/07-App/r6tus/r6tus.c *** openwsn/07-App/r6tus/r6tus.c Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/07-App/r6tus/r6tus.c Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,211 ---- + /** + \brief CoAP schedule manager application. + + \author Xavi Vilajosana , Feb. 2013. + + */ + + #include "openwsn.h" + #include "r6tus.h" + #include "opentimers.h" + #include "openqueue.h" + #include "packetfunctions.h" + #include "openserial.h" + #include "scheduler.h" + #include "schedule.h" + #include "idmanager.h" + + //=========================== defines ========================================= + + #define TSCH_GET_OPTIONS 4 //how many params in a get request. + + const uint8_t r6tus_path0[] = "6tus"; + + //=========================== variables ======================================= + + r6tus_vars_t r6tus_vars; + + //=========================== prototypes ====================================== + + owerror_t r6tus_receive(OpenQueueEntry_t* msg, + coap_header_iht* coap_header, + coap_option_iht* coap_options); + + void r6tus_sendDone(OpenQueueEntry_t* msg, + owerror_t error); + + //=========================== public ========================================== + + void r6tus_init() { + + if(idmanager_getIsDAGroot()==TRUE) return; + // prepare the resource descriptor for the /r6tus path + r6tus_vars.desc.path0len = sizeof(r6tus_path0)-1; + r6tus_vars.desc.path0val = (uint8_t*)(&r6tus_path0); + r6tus_vars.desc.path1len = 0; + r6tus_vars.desc.path1val = NULL; + r6tus_vars.desc.componentID = COMPONENT_R6TUS; + r6tus_vars.desc.callbackRx = &r6tus_receive; + r6tus_vars.desc.callbackSendDone = &r6tus_sendDone; + + opencoap_register(&r6tus_vars.desc); + } + + //=========================== private ========================================= + + /** + \brief Receives a command and a list of items to be used by the command. + + the coap payload contains, command_type (CREATE,READ,UPDATE,DELETE) number of + items to be processed. + A tuple including address,slotoffset,choffset,whether is shared or not and link + type. + + According to the command it returns the list of responses or the required + information. + */ + owerror_t r6tus_receive(OpenQueueEntry_t* msg, + coap_header_iht* coap_header, + coap_option_iht* coap_options) { + + uint8_t i; + owerror_t outcome; + r6tus_command_t* link_command; + r6tus_command_t getResponse; + slotinfo_element_t* link_element; + slotinfo_element_t getLink_elementResponse; + open_addr_t temp_addr; + owerror_t responses[R6TUS_MAXRESPONSES]; + //assuming data comes in binary format. + + if (coap_header->Code==COAP_CODE_REQ_GET) { + outcome = E_SUCCESS; + // parsing the options from header + // assuming the following header: /6tus/LinkComandType/targetSlot/targetAddress + // if (coap_header->OC != TSCH_GET_OPTIONS) { + //option[0] is 6tus + getResponse.type=(link_command_t)coap_options[1].pValue[0]; + if (getResponse.type != READ_LINK){ + //fail if this is not a READ REQUEST + outcome = E_FAIL; + coap_header->Code = COAP_CODE_RESP_CONTENT; + //return as this is not the right request. + return outcome; + } + + getResponse.numelem = 1; //get is always for 1 element. + getLink_elementResponse.slotOffset=coap_options[2].pValue[0]; + + switch (coap_options[3].length){ + case ADDR_16B: + temp_addr.type=ADDR_16B; + memcpy(&(temp_addr.addr_16b[0]), &(coap_options[3].pValue[0]),LENGTH_ADDR16b); + schedule_getSlotInfo(getLink_elementResponse.slotOffset, &temp_addr, &getLink_elementResponse); + outcome = E_SUCCESS; + break; + case ADDR_64B: + temp_addr.type=ADDR_64B; + memcpy(&(temp_addr.addr_64b[0]), &(coap_options[3].pValue[0]),LENGTH_ADDR64b); + schedule_getSlotInfo(getLink_elementResponse.slotOffset, &temp_addr, &getLink_elementResponse); + outcome = E_SUCCESS; + break; + case ADDR_128B: + // not supported + outcome = E_FAIL; + break; + default: + outcome = E_FAIL; + break; + } + + coap_header->Code = COAP_CODE_RESP_CONTENT; + // By using the same link_element we don't need to write the packet. + // It returns the same payload but with the correct values. + if (outcome==E_SUCCESS) { + // write the payload in the response. + packetfunctions_reserveHeaderSize(msg,sizeof(slotinfo_element_t)); + memcpy(&msg->payload[0],&getLink_elementResponse,sizeof(slotinfo_element_t)); + } + } else if (coap_header->Code==COAP_CODE_REQ_PUT) { + link_command = (r6tus_command_t*) msg->payload; + //parsing all cases at post as we want params. once tested we can decide. GET does not accept params + //so params should be encoded in the url. + switch (link_command->type){ + case READ_LINK: + outcome=E_FAIL; + //cannot put READ operation + break; + case CREATE_LINK: + case UPDATE_LINK: //update should be post according to REST architecture. + outcome=E_FAIL; + if (link_command->numelemnumelem;i++) { + link_element=(slotinfo_element_t*) &(msg->payload[sizeof(r6tus_command_t)+i*sizeof(slotinfo_element_t)]); + temp_addr.type=ADDR_64B; + memcpy(&(temp_addr.addr_64b[0]), &(link_element->address[0]),LENGTH_ADDR64b); + responses[i]=schedule_addActiveSlot(link_element->slotOffset,link_element->link_type,link_element->shared,link_element->channelOffset,&temp_addr,(link_command->type==UPDATE_LINK)); + } + outcome=E_SUCCESS; + } + break; + case DELETE_LINK: + outcome=E_FAIL; + //cannot delete with PUT/POST + break; + default: + openserial_printError(COMPONENT_R6TUS,ERR_COMMAND_NOT_ALLOWED, + (errorparameter_t)0, + (errorparameter_t)0 + ); + //who clears the packet?? + //error. Print error and send error msg. + outcome = E_FAIL; + break; + } + //response of the post + if (outcome==E_SUCCESS){ + + // reset packet payload + msg->payload = &(msg->packet[127]); + msg->length = 0; + //copy the response. + + //packetfunctions_reserveHeaderSize(msg,link_command->numelem); + //memcpy(&(msg->payload[0]), &(responses[0]),link_command->numelem); + + // set the CoAP header + coap_header->Code = COAP_CODE_RESP_CONTENT; + } + } else if (coap_header->Code==COAP_CODE_REQ_DELETE) { + link_command = (r6tus_command_t*) msg->payload; + switch (link_command->type){ + case DELETE_LINK: + outcome=E_FAIL; + if (link_command->numelemnumelem;i++) { + link_element=(slotinfo_element_t*) &(msg->payload[sizeof(r6tus_command_t)+i*sizeof(slotinfo_element_t)]); + temp_addr.type=ADDR_64B; + memcpy(&(temp_addr.addr_64b[0]), &(link_element->address[0]),LENGTH_ADDR64b); + //remove the required links. + responses[i]=schedule_removeActiveSlot(link_element->slotOffset,&temp_addr); + } + outcome=E_SUCCESS; + } + break; + default: + openserial_printError(COMPONENT_R6TUS,ERR_COMMAND_NOT_ALLOWED, + (errorparameter_t)0, + (errorparameter_t)0); + //who clears the packet?? + //error. Print error and send error msg. + outcome = E_FAIL; + break; + } + } + return outcome; + } + + + void r6tus_sendDone(OpenQueueEntry_t* msg, owerror_t error) { + openqueue_freePacketBuffer(msg); + } diff -crB openwsn/07-App/r6tus/r6tus.h ../../../sys/net/openwsn/07-App/r6tus/r6tus.h *** openwsn/07-App/r6tus/r6tus.h Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/07-App/r6tus/r6tus.h Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,60 ---- + /** + \brief CoAP schedule manager application. + + \author Xavi Vilajosana , Feb. 2013. + + */ + + + #ifndef __RSCHED_H + #define __RSCHED_H + + /** + \addtogroup AppCoAP + \{ + \addtogroup rsched + \{ + */ + + #include "openwsn.h" + #include "opencoap.h" + #include "schedule.h" + + //=========================== define ========================================== + + #define R6TUS_MAXRESPONSES 20 //max number of elements to be processed by a command. + + //=========================== typedef ========================================= + + //CRUD OPERATIONS FOR LINKS. + typedef enum { + CREATE_LINK = 0, + READ_LINK = 1, + UPDATE_LINK = 2, + DELETE_LINK = 3, + }link_command_t; + + //header + PRAGMA(pack(1)); //elements for slot info + typedef struct { + link_command_t type; + uint8_t numelem;//number of elements + }r6tus_command_t; + PRAGMA(pack()); + + //=========================== variables ======================================= + + typedef struct { + coap_resource_desc_t desc; + } r6tus_vars_t; + + //=========================== prototypes ====================================== + + void r6tus_init(); + + /** + \} + \} + */ + + #endif diff -crB openwsn/07-App/rex/rex.c ../../../sys/net/openwsn/07-App/rex/rex.c *** openwsn/07-App/rex/rex.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rex/rex.c Wed Jan 15 13:48:27 2014 *************** *** 1,149 **** ! #include "openwsn.h" ! #include "rex.h" ! #include "opencoap.h" ! #include "opentimers.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "scheduler.h" ! //#include "ADC_Channel.h" ! ! //=========================== defines ========================================= ! ! /// inter-packet period (in ms) ! #define REXPERIOD 10000 ! #define PAYLOADLEN 62 ! ! const uint8_t rex_path0[] = "rex"; ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! opentimer_id_t timerId; ! } rex_vars_t; ! ! rex_vars_t rex_vars; ! ! //=========================== prototypes ====================================== ! ! error_t rex_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rex_timer_cb(); ! void rex_task_cb(); ! void rex_sendDone(OpenQueueEntry_t* msg, ! error_t error); ! ! //=========================== public ========================================== ! ! void rex_init() { ! ! // prepare the resource descriptor for the /rex path ! rex_vars.desc.path0len = sizeof(rex_path0)-1; ! rex_vars.desc.path0val = (uint8_t*)(&rex_path0); ! rex_vars.desc.path1len = 0; ! rex_vars.desc.path1val = NULL; ! rex_vars.desc.componentID = COMPONENT_REX; ! rex_vars.desc.callbackRx = &rex_receive; ! rex_vars.desc.callbackSendDone = &rex_sendDone; ! ! ! opencoap_register(&rex_vars.desc); ! rex_vars.timerId = opentimers_start(REXPERIOD, ! TIMER_PERIODIC,TIME_MS, ! rex_timer_cb); ! } ! ! //=========================== private ========================================= ! ! error_t rex_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! return E_FAIL; ! } ! ! //timer fired, but we don't want to execute task in ISR mode ! //instead, push task to scheduler with COAP priority, and let scheduler take care of it ! void rex_timer_cb(){ ! scheduler_push_task(rex_task_cb,TASKPRIO_COAP); ! } ! ! void rex_task_cb() { ! OpenQueueEntry_t* pkt; ! error_t outcome; ! uint8_t numOptions; ! uint8_t i; ! ! uint16_t x_int = 0; ! //uint16_t* p_x_int = &x_int; ! uint16_t sum = 0; ! uint16_t avg = 0; ! uint8_t N_avg = 10; ! ! for (int i = 0; i < N_avg; i++) ! { ! //ADC_getvoltage(p_x_int); ! ! sum += x_int; ! } ! avg = sum/N_avg; ! ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_REX); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_REX,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_REX; ! pkt->owner = COMPONENT_REX; ! // CoAP payload ! packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); ! for (i=0;ipayload[i] = i; ! } ! avg = openrandom_get16b(); ! pkt->payload[0] = (avg>>8)&0xff; ! pkt->payload[1] = (avg>>0)&0xff; ! ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(rex_path0)-1); ! memcpy(&pkt->payload[0],&rex_path0,sizeof(rex_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | ! sizeof(rex_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &rex_vars.desc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! return; ! } ! ! void rex_sendDone(OpenQueueEntry_t* msg, error_t error) { ! openqueue_freePacketBuffer(msg); ! } --- 1,159 ---- ! #include "openwsn.h" ! #include "rex.h" ! #include "opencoap.h" ! #include "opentimers.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "scheduler.h" ! //#include "ADC_Channel.h" ! #include "idmanager.h" ! #include "IEEE802154E.h" ! ! //=========================== defines ========================================= ! ! /// inter-packet period (in ms) ! #define REXPERIOD 10000 ! #define PAYLOADLEN 62 ! ! const uint8_t rex_path0[] = "rex"; ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! opentimer_id_t timerId; ! } rex_vars_t; ! ! rex_vars_t rex_vars; ! ! //=========================== prototypes ====================================== ! ! owerror_t rex_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rex_timer_cb(); ! void rex_task_cb(); ! void rex_sendDone(OpenQueueEntry_t* msg, ! owerror_t error); ! ! //=========================== public ========================================== ! ! void rex_init() { ! ! // prepare the resource descriptor for the /rex path ! rex_vars.desc.path0len = sizeof(rex_path0)-1; ! rex_vars.desc.path0val = (uint8_t*)(&rex_path0); ! rex_vars.desc.path1len = 0; ! rex_vars.desc.path1val = NULL; ! rex_vars.desc.componentID = COMPONENT_REX; ! rex_vars.desc.callbackRx = &rex_receive; ! rex_vars.desc.callbackSendDone = &rex_sendDone; ! ! ! opencoap_register(&rex_vars.desc); ! rex_vars.timerId = opentimers_start(REXPERIOD, ! TIMER_PERIODIC,TIME_MS, ! rex_timer_cb); ! } ! ! //=========================== private ========================================= ! ! owerror_t rex_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! return E_FAIL; ! } ! ! //timer fired, but we don't want to execute task in ISR mode ! //instead, push task to scheduler with COAP priority, and let scheduler take care of it ! void rex_timer_cb(){ ! scheduler_push_task(rex_task_cb,TASKPRIO_COAP); ! } ! ! void rex_task_cb() { ! OpenQueueEntry_t* pkt; ! owerror_t outcome; ! uint8_t numOptions; ! uint8_t i; ! ! uint16_t x_int = 0; ! //uint16_t* p_x_int = &x_int; ! uint16_t sum = 0; ! uint16_t avg = 0; ! uint8_t N_avg = 10; ! ! // don't run if not synch ! if (ieee154e_isSynch() == FALSE) return; ! ! // don't run on dagroot ! if (idmanager_getIsDAGroot()) { ! opentimers_stop(rex_vars.timerId); ! return; ! } ! ! ! for (i = 0; i < N_avg; i++) { ! //ADC_getvoltage(p_x_int); ! sum += x_int; ! } ! avg = sum/N_avg; ! ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_REX); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_REX,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_REX; ! pkt->owner = COMPONENT_REX; ! // CoAP payload ! packetfunctions_reserveHeaderSize(pkt,PAYLOADLEN); ! for (i=0;ipayload[i] = i; ! } ! avg = openrandom_get16b(); ! pkt->payload[0] = (avg>>8)&0xff; ! pkt->payload[1] = (avg>>0)&0xff; ! ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(rex_path0)-1); ! memcpy(&pkt->payload[0],&rex_path0,sizeof(rex_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | ! sizeof(rex_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &rex_vars.desc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! return; ! } ! ! void rex_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! openqueue_freePacketBuffer(msg); ! } diff -crB openwsn/07-App/rex/rex.h ../../../sys/net/openwsn/07-App/rex/rex.h *** openwsn/07-App/rex/rex.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rex/rex.h Wed Jan 15 13:48:27 2014 *************** *** 1,26 **** ! #ifndef __REX_H ! #define __REX_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup rT ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rex_init(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,26 ---- ! #ifndef __REX_H ! #define __REX_H ! ! /** ! \addtogroup AppUdp ! \{ ! \addtogroup rT ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rex_init(); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/rheli/rheli.c ../../../sys/net/openwsn/07-App/rheli/rheli.c *** openwsn/07-App/rheli/rheli.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rheli/rheli.c Wed Jan 15 13:48:27 2014 *************** *** 1,84 **** ! #include "openwsn.h" ! #include "rheli.h" ! #include "opentimers.h" ! #include "opencoap.h" ! #include "packetfunctions.h" ! #include "heli.h" ! #include "openqueue.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! opentimer_id_t timerId; ! } rheli_vars_t; ! ! rheli_vars_t rheli_vars; ! ! const uint8_t rheli_path0[] = "h"; ! ! //=========================== prototypes ====================================== ! ! error_t rheli_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rheli_timer(); ! void rheli_sendDone(OpenQueueEntry_t* msg, ! error_t error); ! ! //=========================== public ========================================== ! ! void rheli_init() { ! // initialize the heli drivers ! heli_init(); ! ! // prepare the resource descriptor ! rheli_vars.desc.path0len = sizeof(rheli_path0)-1; ! rheli_vars.desc.path0val = (uint8_t*)(&rheli_path0); ! rheli_vars.desc.path1len = 0; ! rheli_vars.desc.path1val = NULL; ! rheli_vars.desc.componentID = COMPONENT_RHELI; ! rheli_vars.desc.callbackRx = &rheli_receive; ! rheli_vars.desc.callbackSendDone = &rheli_sendDone; ! ! opencoap_register(&rheli_vars.desc); ! rheli_vars.timerId = opentimers_start(1000, ! TIMER_PERIODIC,TIME_MS, ! rheli_timer); ! } ! ! //=========================== private ========================================= ! ! error_t rheli_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! error_t outcome; ! ! if (coap_header->Code==COAP_CODE_REQ_POST) { ! ! // switch on the heli ! heli_on(); ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // set the CoAP header ! coap_header->OC = 0; ! coap_header->Code = COAP_CODE_RESP_CHANGED; ! ! outcome = E_SUCCESS; ! } else { ! outcome = E_FAIL; ! } ! return outcome; ! } ! ! void rheli_timer() { ! // switch off the heli ! heli_off(); ! } ! ! void rheli_sendDone(OpenQueueEntry_t* msg, error_t error) { ! openqueue_freePacketBuffer(msg); } \ No newline at end of file --- 1,83 ---- ! #include "openwsn.h" ! #include "rheli.h" ! #include "opentimers.h" ! #include "opencoap.h" ! #include "packetfunctions.h" ! #include "heli.h" ! #include "openqueue.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! opentimer_id_t timerId; ! } rheli_vars_t; ! ! rheli_vars_t rheli_vars; ! ! const uint8_t rheli_path0[] = "h"; ! ! //=========================== prototypes ====================================== ! ! owerror_t rheli_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rheli_timer(); ! void rheli_sendDone(OpenQueueEntry_t* msg, ! owerror_t error); ! ! //=========================== public ========================================== ! ! void rheli_init() { ! // initialize the heli drivers ! heli_init(); ! ! // prepare the resource descriptor ! rheli_vars.desc.path0len = sizeof(rheli_path0)-1; ! rheli_vars.desc.path0val = (uint8_t*)(&rheli_path0); ! rheli_vars.desc.path1len = 0; ! rheli_vars.desc.path1val = NULL; ! rheli_vars.desc.componentID = COMPONENT_RHELI; ! rheli_vars.desc.callbackRx = &rheli_receive; ! rheli_vars.desc.callbackSendDone = &rheli_sendDone; ! ! opencoap_register(&rheli_vars.desc); ! rheli_vars.timerId = opentimers_start(1000, ! TIMER_PERIODIC,TIME_MS, ! rheli_timer); ! } ! ! //=========================== private ========================================= ! ! owerror_t rheli_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! owerror_t outcome; ! ! if (coap_header->Code==COAP_CODE_REQ_POST) { ! ! // switch on the heli ! heli_on(); ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // set the CoAP header ! coap_header->Code = COAP_CODE_RESP_CHANGED; ! ! outcome = E_SUCCESS; ! } else { ! outcome = E_FAIL; ! } ! return outcome; ! } ! ! void rheli_timer() { ! // switch off the heli ! heli_off(); ! } ! ! void rheli_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! openqueue_freePacketBuffer(msg); } \ No newline at end of file diff -crB openwsn/07-App/rheli/rheli.h ../../../sys/net/openwsn/07-App/rheli/rheli.h *** openwsn/07-App/rheli/rheli.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rheli/rheli.h Wed Jan 15 13:48:27 2014 *************** *** 1,26 **** ! #ifndef __RHELI_H ! #define __RHELI_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup rHeli ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rheli_init(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,26 ---- ! #ifndef __RHELI_H ! #define __RHELI_H ! ! /** ! \addtogroup AppCoAP ! \{ ! \addtogroup rHeli ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rheli_init(); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/rinfo/Makefile ../../../sys/net/openwsn/07-App/rinfo/Makefile *** openwsn/07-App/rinfo/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/07-App/rinfo/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) + $(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 + $(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 + #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) + $(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 + $(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[] = ";if=\"actuator\";rt=\"ipso:light\";ct=\"0\""; ! ! //=========================== prototypes ====================================== ! ! error_t rwellknown_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rwellknown_sendDone(OpenQueueEntry_t* msg, ! error_t error); ! ! //=========================== public ========================================== ! ! void rwellknown_init() { ! // prepare the resource descriptor for the /.well-known/core path ! rwellknown_vars.desc.path0len = sizeof(rwellknown_path0)-1; ! rwellknown_vars.desc.path0val = (uint8_t*)(&rwellknown_path0); ! rwellknown_vars.desc.path1len = sizeof(rwellknown_path1)-1; ! rwellknown_vars.desc.path1val = (uint8_t*)(&rwellknown_path1); ! rwellknown_vars.desc.componentID = COMPONENT_RWELLKNOWN; ! rwellknown_vars.desc.callbackRx = &rwellknown_receive; ! rwellknown_vars.desc.callbackSendDone = &rwellknown_sendDone; ! ! opencoap_register(&rwellknown_vars.desc); ! } ! ! //=========================== private ========================================= ! ! error_t rwellknown_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! error_t outcome; ! ! if (coap_header->Code==COAP_CODE_REQ_GET) { ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // add link descriptors to the packet ! opencoap_writeLinks(msg); ! ! // add return option ! packetfunctions_reserveHeaderSize(msg,2); ! msg->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | ! 1; ! msg->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; ! ! // set the CoAP header ! coap_header->OC = 1; ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! } else { ! outcome = E_FAIL; ! } ! return outcome; ! } ! ! void rwellknown_sendDone(OpenQueueEntry_t* msg, error_t error) { ! openqueue_freePacketBuffer(msg); } \ No newline at end of file --- 1,80 ---- ! #include "openwsn.h" ! #include "rwellknown.h" ! #include "opencoap.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "idmanager.h" ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! } rwellknown_vars_t; ! ! rwellknown_vars_t rwellknown_vars; ! ! const uint8_t rwellknown_path0[] = ".well-known"; ! const uint8_t rwellknown_path1[] = "core"; ! const uint8_t rwellknown_testlink[] = ";if=\"actuator\";rt=\"ipso:light\";ct=\"0\""; ! ! //=========================== prototypes ====================================== ! ! owerror_t rwellknown_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rwellknown_sendDone(OpenQueueEntry_t* msg, ! owerror_t error); ! ! //=========================== public ========================================== ! ! void rwellknown_init(void) { ! ! ! if(idmanager_getIsDAGroot()==TRUE) return; ! ! // prepare the resource descriptor for the /.well-known/core path ! rwellknown_vars.desc.path0len = sizeof(rwellknown_path0)-1; ! rwellknown_vars.desc.path0val = (uint8_t*)(&rwellknown_path0); ! rwellknown_vars.desc.path1len = sizeof(rwellknown_path1)-1; ! rwellknown_vars.desc.path1val = (uint8_t*)(&rwellknown_path1); ! rwellknown_vars.desc.componentID = COMPONENT_RWELLKNOWN; ! rwellknown_vars.desc.callbackRx = &rwellknown_receive; ! rwellknown_vars.desc.callbackSendDone = &rwellknown_sendDone; ! ! opencoap_register(&rwellknown_vars.desc); ! } ! ! //=========================== private ========================================= ! ! owerror_t rwellknown_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! owerror_t outcome; ! ! if (coap_header->Code==COAP_CODE_REQ_GET) { ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // add link descriptors to the packet ! opencoap_writeLinks(msg); ! ! // add return option ! packetfunctions_reserveHeaderSize(msg,2); ! msg->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | ! 1; ! msg->payload[1] = COAP_MEDTYPE_APPLINKFORMAT; ! ! // set the CoAP header ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! } else { ! outcome = E_FAIL; ! } ! return outcome; ! } ! ! void rwellknown_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! openqueue_freePacketBuffer(msg); } \ No newline at end of file diff -crB openwsn/07-App/rwellknown/rwellknown.h ../../../sys/net/openwsn/07-App/rwellknown/rwellknown.h *** openwsn/07-App/rwellknown/rwellknown.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rwellknown/rwellknown.h Wed Jan 15 13:48:27 2014 *************** *** 1,26 **** ! #ifndef __RWELLKNOWN_H ! #define __RWELLKNOWN_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup rWellKnown ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rwellknown_init(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,26 ---- ! #ifndef __RWELLKNOWN_H ! #define __RWELLKNOWN_H ! ! /** ! \addtogroup AppCoAP ! \{ ! \addtogroup rWellKnown ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rwellknown_init(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/rxl1/rxl1.c ../../../sys/net/openwsn/07-App/rxl1/rxl1.c *** openwsn/07-App/rxl1/rxl1.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rxl1/rxl1.c Wed Jan 15 13:48:27 2014 *************** *** 1,176 **** ! #include "openwsn.h" ! #include "rxl1.h" ! #include "opentimers.h" ! #include "opencoap.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "sensitive_accel_temperature.h" ! ! ! //=========================== defines ========================================= ! ! /// inter-packet period (in mseconds) ! #define RXL1PERIOD 6000 ! ! const uint8_t rxl1_path0[] = "x"; ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! opentimer_id_t timerId; ! } rxl1_vars_t; ! ! rxl1_vars_t rxl1_vars; ! ! //=========================== prototypes ====================================== ! ! error_t rxl1_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rxl1_timer(); ! void rxl1_sendDone(OpenQueueEntry_t* msg, ! error_t error); ! ! //=========================== public ========================================== ! ! void rxl1_init() { ! // startup the sensor ! sensitive_accel_temperature_init(); ! ! // prepare the resource descriptor for the /temp path ! rxl1_vars.desc.path0len = sizeof(rxl1_path0)-1; ! rxl1_vars.desc.path0val = (uint8_t*)(&rxl1_path0); ! rxl1_vars.desc.path1len = 0; ! rxl1_vars.desc.path1val = NULL; ! rxl1_vars.desc.componentID = COMPONENT_RXL1; ! rxl1_vars.desc.callbackRx = &rxl1_receive; ! rxl1_vars.desc.callbackSendDone = &rxl1_sendDone; ! ! //we start a timer, but just to get a timer ID, we stop it immediately ! rxl1_vars.timerId = opentimers_start(openrandom_get16b()%RXL1PERIOD, ! TIMER_PERIODIC,TIME_MS, ! rxl1_timer); ! opentimers_stop(rxl1_vars.timerId); ! ! opencoap_register(&rxl1_vars.desc); ! } ! ! //=========================== private ========================================= ! ! error_t rxl1_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! error_t outcome; ! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; ! ! if (coap_header->Code==COAP_CODE_REQ_POST) { ! // start/stop the data generation to data server ! ! if (msg->payload[0]=='1') { ! //restart timer ! opentimers_restart(rxl1_vars.timerId); ! ! } else { ! //stop timer ! opentimers_stop(rxl1_vars.timerId); ! } ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // CoAP header ! coap_header->OC = 0; ! coap_header->Code = COAP_CODE_RESP_VALID; ! ! outcome = E_SUCCESS; ! ! } else if (coap_header->Code==COAP_CODE_REQ_GET) { ! // return current sensor value ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // CoAP payload (8 bytes of XL data) ! packetfunctions_reserveHeaderSize(msg,8); ! sensitive_accel_temperature_get_measurement(&rawdata[0]); ! memcpy(&msg->payload[0],&rawdata[8],8); ! ! // set the CoAP header ! coap_header->OC = 0; ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! ! } else { ! // return an error message ! outcome = E_FAIL; ! } ! ! return outcome; ! } ! ! void rxl1_timer() { ! OpenQueueEntry_t* pkt; ! error_t outcome; ! uint8_t numOptions; ! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; ! ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_RXL1); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_RXL1,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_RXL1; ! pkt->owner = COMPONENT_RXL1; ! // CoAP payload (2 bytes of temperature data) ! packetfunctions_reserveHeaderSize(pkt,2); ! sensitive_accel_temperature_get_measurement(&rawdata[0]); ! pkt->payload[0] = rawdata[8]; ! pkt->payload[1] = rawdata[9]; ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(rxl1_path0)-1); ! memcpy(&pkt->payload[0],&rxl1_path0,sizeof(rxl1_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_LOCATIONPATH-COAP_OPTION_CONTENTTYPE) << 4 | ! sizeof(rxl1_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_CONTENTTYPE << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &rxl1_vars.desc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! ! return; ! } ! ! void rxl1_sendDone(OpenQueueEntry_t* msg, error_t error) { ! openqueue_freePacketBuffer(msg); ! } --- 1,174 ---- ! #include "openwsn.h" ! #include "rxl1.h" ! #include "opentimers.h" ! #include "opencoap.h" ! #include "openqueue.h" ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "openrandom.h" ! #include "sensitive_accel_temperature.h" ! ! ! //=========================== defines ========================================= ! ! /// inter-packet period (in mseconds) ! #define RXL1PERIOD 6000 ! ! const uint8_t rxl1_path0[] = "x"; ! ! //=========================== variables ======================================= ! ! typedef struct { ! coap_resource_desc_t desc; ! opentimer_id_t timerId; ! } rxl1_vars_t; ! ! rxl1_vars_t rxl1_vars; ! ! //=========================== prototypes ====================================== ! ! owerror_t rxl1_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options); ! void rxl1_timer(); ! void rxl1_sendDone(OpenQueueEntry_t* msg, ! owerror_t error); ! ! //=========================== public ========================================== ! ! void rxl1_init() { ! // startup the sensor ! sensitive_accel_temperature_init(); ! ! // prepare the resource descriptor for the /temp path ! rxl1_vars.desc.path0len = sizeof(rxl1_path0)-1; ! rxl1_vars.desc.path0val = (uint8_t*)(&rxl1_path0); ! rxl1_vars.desc.path1len = 0; ! rxl1_vars.desc.path1val = NULL; ! rxl1_vars.desc.componentID = COMPONENT_RXL1; ! rxl1_vars.desc.callbackRx = &rxl1_receive; ! rxl1_vars.desc.callbackSendDone = &rxl1_sendDone; ! ! //we start a timer, but just to get a timer ID, we stop it immediately ! rxl1_vars.timerId = opentimers_start(openrandom_get16b()%RXL1PERIOD, ! TIMER_PERIODIC,TIME_MS, ! rxl1_timer); ! opentimers_stop(rxl1_vars.timerId); ! ! opencoap_register(&rxl1_vars.desc); ! } ! ! //=========================== private ========================================= ! ! owerror_t rxl1_receive(OpenQueueEntry_t* msg, ! coap_header_iht* coap_header, ! coap_option_iht* coap_options) { ! owerror_t outcome; ! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; ! ! if (coap_header->Code==COAP_CODE_REQ_POST) { ! // start/stop the data generation to data server ! ! if (msg->payload[0]=='1') { ! //restart timer ! opentimers_restart(rxl1_vars.timerId); ! ! } else { ! //stop timer ! opentimers_stop(rxl1_vars.timerId); ! } ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // CoAP header ! coap_header->Code = COAP_CODE_RESP_VALID; ! ! outcome = E_SUCCESS; ! ! } else if (coap_header->Code==COAP_CODE_REQ_GET) { ! // return current sensor value ! ! // reset packet payload ! msg->payload = &(msg->packet[127]); ! msg->length = 0; ! ! // CoAP payload (8 bytes of XL data) ! packetfunctions_reserveHeaderSize(msg,8); ! sensitive_accel_temperature_get_measurement(&rawdata[0]); ! memcpy(&msg->payload[0],&rawdata[8],8); ! ! // set the CoAP header ! coap_header->Code = COAP_CODE_RESP_CONTENT; ! ! outcome = E_SUCCESS; ! ! } else { ! // return an error message ! outcome = E_FAIL; ! } ! ! return outcome; ! } ! ! void rxl1_timer() { ! OpenQueueEntry_t* pkt; ! owerror_t outcome; ! uint8_t numOptions; ! uint8_t rawdata[SENSITIVE_ACCEL_TEMPERATURE_DATALEN]; ! ! ! // create a CoAP RD packet ! pkt = openqueue_getFreePacketBuffer(COMPONENT_RXL1); ! if (pkt==NULL) { ! openserial_printError(COMPONENT_RXL1,ERR_NO_FREE_PACKET_BUFFER, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openqueue_freePacketBuffer(pkt); ! return; ! } ! // take ownership over that packet ! pkt->creator = COMPONENT_RXL1; ! pkt->owner = COMPONENT_RXL1; ! // CoAP payload (2 bytes of temperature data) ! packetfunctions_reserveHeaderSize(pkt,2); ! sensitive_accel_temperature_get_measurement(&rawdata[0]); ! pkt->payload[0] = rawdata[8]; ! pkt->payload[1] = rawdata[9]; ! numOptions = 0; ! // location-path option ! packetfunctions_reserveHeaderSize(pkt,sizeof(rxl1_path0)-1); ! memcpy(&pkt->payload[0],&rxl1_path0,sizeof(rxl1_path0)-1); ! packetfunctions_reserveHeaderSize(pkt,1); ! pkt->payload[0] = (COAP_OPTION_NUM_URIPATH) << 4 | ! sizeof(rxl1_path0)-1; ! numOptions++; ! // content-type option ! packetfunctions_reserveHeaderSize(pkt,2); ! pkt->payload[0] = COAP_OPTION_NUM_CONTENTFORMAT << 4 | ! 1; ! pkt->payload[1] = COAP_MEDTYPE_APPOCTETSTREAM; ! numOptions++; ! // metadata ! pkt->l4_destination_port = WKP_UDP_COAP; ! pkt->l3_destinationAdd.type = ADDR_128B; ! memcpy(&pkt->l3_destinationAdd.addr_128b[0],&ipAddr_motesEecs,16); ! // send ! outcome = opencoap_send(pkt, ! COAP_TYPE_NON, ! COAP_CODE_REQ_PUT, ! numOptions, ! &rxl1_vars.desc); ! // avoid overflowing the queue if fails ! if (outcome==E_FAIL) { ! openqueue_freePacketBuffer(pkt); ! } ! ! ! return; ! } ! ! void rxl1_sendDone(OpenQueueEntry_t* msg, owerror_t error) { ! openqueue_freePacketBuffer(msg); ! } diff -crB openwsn/07-App/rxl1/rxl1.h ../../../sys/net/openwsn/07-App/rxl1/rxl1.h *** openwsn/07-App/rxl1/rxl1.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/07-App/rxl1/rxl1.h Wed Jan 15 13:48:27 2014 *************** *** 1,26 **** ! #ifndef __RXL1_H ! #define __RXL1_H ! ! /** ! \addtogroup App ! \{ ! \addtogroup rXL1 ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rxl1_init(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,26 ---- ! #ifndef __RXL1_H ! #define __RXL1_H ! ! /** ! \addtogroup AppCoAP ! \{ ! \addtogroup rXL1 ! \{ ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void rxl1_init(); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/07-App/tcpecho/Makefile ../../../sys/net/openwsn/07-App/tcpecho/Makefile *** openwsn/07-App/tcpecho/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/07-App/tcpecho/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,32 ---- + SUBSUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBSUBMOD) + + $(BINDIR)$(SUBSUBMOD): $(OBJ) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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 + $(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 + #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) + $(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) + $(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 , February 2012. ! */ ! ! #ifndef __BOARD_INFO_H ! #define __BOARD_INFO_H ! ! #include "stdint.h" ! #include "msp430f1611.h" ! #include "string.h" ! ! //=========================== define ========================================== ! ! // (pre-)processor scpecific commands ! ! #define port_INLINE inline ! ! #define PRAGMA(x) _Pragma(#x) ! #define PACK(x) pack(x) ! ! #define INTERRUPT_DECLARATION() __istate_t s; ! #define DISABLE_INTERRUPTS() s = __get_interrupt_state(); \ ! __disable_interrupt(); ! #define ENABLE_INTERRUPTS() __set_interrupt_state(s); ! ! //===== timer ! ! #define PORT_TIMER_WIDTH uint16_t ! #define PORT_SIGNED_INT_WIDTH int16_t ! #define PORT_TICS_PER_MS 33 ! ! // on TelosB, we use the comparatorA interrupt for the OS ! #define SCHEDULER_WAKEUP() CACTL1 |= CAIFG ! #define SCHEDULER_ENABLE_INTERRUPT() CACTL1 = CAIE ! ! //===== pins ! ! // [P4.5] radio VREG ! #define PORT_PIN_RADIO_VREG_HIGH() P4OUT |= 0x20; ! #define PORT_PIN_RADIO_VREG_LOW() P4OUT &= ~0x20; ! // [P4.6] radio RESET ! #define PORT_PIN_RADIO_RESET_HIGH() P4OUT |= 0x40; ! #define PORT_PIN_RADIO_RESET_LOW() P4OUT &= ~0x40; ! ! //===== IEEE802154E timing ! ! // time-slot related ! #define PORT_TsSlotDuration 491 // counter counts one extra count, see datasheet ! ! // execution speed related ! #define PORT_maxTxDataPrepare 100 // 2899us (measured 2420us) ! #define PORT_maxRxAckPrepare 20 // 610us (measured 474us) ! #define PORT_maxRxDataPrepare 33 // 1000us (measured 477us) ! #define PORT_maxTxAckPrepare 40 // 792us (measured 746us)- cannot be bigger than 28.. is the limit for telosb as actvitiy_rt5 is executed almost there. ! ! // radio speed related ! #define PORT_delayTx 12 // 366us (measured 352us) ! #define PORT_delayRx 0 // 0us (can not measure) ! ! //=========================== variables ======================================= ! ! // The variables below are used by CoAP's registration engine. ! ! static const uint8_t rreg_uriquery[] = "h=ucb"; ! static const uint8_t infoBoardname[] = "TelosB"; ! static const uint8_t infouCName[] = "MSP430f1611"; ! static const uint8_t infoRadioName[] = "CC2420"; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! //=========================== private ========================================= ! ! #endif --- 1,93 ---- ! /** ! \brief TelosB-specific board information bsp module. ! ! This module file defines board-related element, but which are applicable only ! to this board. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __BOARD_INFO_H ! #define __BOARD_INFO_H ! ! #include "stdint.h" ! #include "msp430f1611.h" ! #include "string.h" ! ! //=========================== define ========================================== ! ! // (pre-)processor scpecific commands ! ! #define port_INLINE inline ! ! #define PRAGMA(x) _Pragma(#x) ! #define PACK(x) pack(x) ! ! //===== interrupt state ! ! #if defined(__GNUC__) && (__GNUC__==4) && (__GNUC_MINOR__<=5) && defined(__MSP430__) ! // mspgcc <4.5.x ! #define INTERRUPT_DECLARATION() unsigned short s; ! #define DISABLE_INTERRUPTS() s = READ_SR&0x0008; \ ! __disable_interrupt(); ! #define ENABLE_INTERRUPTS() __asm__("bis %0,r2" : : "ir" ((uint16_t) s)); ! #else ! // other ! #define INTERRUPT_DECLARATION() __istate_t s; ! #define DISABLE_INTERRUPTS() s = __get_interrupt_state(); \ ! __disable_interrupt(); ! #define ENABLE_INTERRUPTS() __set_interrupt_state(s); ! #endif ! ! //===== timer ! ! #define PORT_TIMER_WIDTH uint16_t ! #define PORT_RADIOTIMER_WIDTH uint16_t ! ! #define PORT_SIGNED_INT_WIDTH int16_t ! #define PORT_TICS_PER_MS 33 ! ! // on TelosB, we use the comparatorA interrupt for the OS ! #define SCHEDULER_WAKEUP() CACTL1 |= CAIFG ! #define SCHEDULER_ENABLE_INTERRUPT() CACTL1 = CAIE ! ! //===== pins ! ! // [P4.5] radio VREG ! #define PORT_PIN_RADIO_VREG_HIGH() P4OUT |= 0x20; ! #define PORT_PIN_RADIO_VREG_LOW() P4OUT &= ~0x20; ! // [P4.6] radio RESET ! #define PORT_PIN_RADIO_RESET_HIGH() P4OUT |= 0x40; ! #define PORT_PIN_RADIO_RESET_LOW() P4OUT &= ~0x40; ! ! //===== IEEE802154E timing ! ! // time-slot related ! #define PORT_TsSlotDuration 491 // counter counts one extra count, see datasheet ! ! // execution speed related ! #define PORT_maxTxDataPrepare 100 // 2899us (measured 2420us) ! #define PORT_maxRxAckPrepare 20 // 610us (measured 474us) ! #define PORT_maxRxDataPrepare 33 // 1000us (measured 477us) ! #define PORT_maxTxAckPrepare 40 // 792us (measured 746us)- cannot be bigger than 28.. is the limit for telosb as actvitiy_rt5 is executed almost there. ! ! // radio speed related ! #define PORT_delayTx 12 // 366us (measured 352us) ! #define PORT_delayRx 0 // 0us (can not measure) ! ! //=========================== variables ======================================= ! ! // The variables below are used by CoAP's registration engine. ! ! static const uint8_t rreg_uriquery[] = "h=ucb"; ! static const uint8_t infoBoardname[] = "TelosB"; ! static const uint8_t infouCName[] = "MSP430f1611"; ! static const uint8_t infoRadioName[] = "CC2420"; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! //=========================== private ========================================= ! ! #endif diff -crB openwsn/board_ow.c ../../../sys/net/openwsn/board_ow.c *** openwsn/board_ow.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/board_ow.c Wed Jan 15 13:48:27 2014 *************** *** 1,138 **** ! /** ! \brief TelosB-specific definition of the "board" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "board.h" ! // bsp modules ! #include "debugpins.h" ! #include "leds.h" ! #include "uart.h" ! #include "spi.h" ! #include "bsp_timer.h" ! #include "radio.h" ! #include "radiotimer.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== main ============================================ ! ! extern int mote_main(void); ! int main(void) { ! return mote_main(); ! } ! ! //=========================== public ========================================== ! ! void board_init() { ! // disable watchdog timer ! WDTCTL = WDTPW + WDTHOLD; ! ! // setup clock speed ! DCOCTL |= DCO0 | DCO1 | DCO2; // MCLK at ~8MHz ! BCSCTL1 |= RSEL0 | RSEL1 | RSEL2; // MCLK at ~8MHz ! // by default, ACLK from 32kHz XTAL which is running ! ! // initialize pins ! P4DIR |= 0x20; // [P4.5] radio VREG: output ! P4DIR |= 0x40; // [P4.6] radio reset: output ! ! // initialize bsp modules ! debugpins_init(); ! leds_init(); ! uart_init(); ! spi_init(); ! bsp_timer_init(); ! radio_init(); ! radiotimer_init(); ! ! // enable interrupts ! __bis_SR_register(GIE); ! } ! ! void board_sleep() { ! __bis_SR_register(GIE+LPM0_bits); // sleep, but leave ACLK on ! } ! ! void board_reset() { ! WDTCTL = (WDTPW+0x1200) + WDTHOLD; // writing a wrong watchdog password to causes handler to reset ! } ! ! //=========================== private ========================================= ! ! //=========================== interrupt handlers ============================== ! ! // DACDMA_VECTOR ! ! // PORT2_VECTOR ! ! #pragma vector = USART1TX_VECTOR ! __interrupt void USART1TX_ISR (void) { ! debugpins_isr_set(); ! if (uart_tx_isr()==KICK_SCHEDULER) { // UART; TX ! __bic_SR_register_on_exit(CPUOFF); ! } ! debugpins_isr_clr(); ! } ! ! #pragma vector = USART1RX_VECTOR ! __interrupt void USART1RX_ISR (void) { ! debugpins_isr_set(); ! if (uart_rx_isr()==KICK_SCHEDULER) { // UART: RX ! __bic_SR_register_on_exit(CPUOFF); ! } ! debugpins_isr_clr(); ! } ! ! // PORT1_VECTOR ! ! // TIMERA1_VECTOR ! ! #pragma vector = TIMERA0_VECTOR ! __interrupt void TIMERA0_ISR (void) { ! debugpins_isr_set(); ! if (bsp_timer_isr()==KICK_SCHEDULER) { // timer: 0 ! __bic_SR_register_on_exit(CPUOFF); ! } ! debugpins_isr_clr(); ! } ! ! // ADC12_VECTOR ! ! // USART0TX_VECTOR ! ! #pragma vector = USART0RX_VECTOR ! __interrupt void USART0RX_ISR (void) { ! debugpins_isr_set(); ! if (spi_isr()==KICK_SCHEDULER) { // SPI ! __bic_SR_register_on_exit(CPUOFF); ! } ! debugpins_isr_clr(); ! } ! ! // WDT_VECTOR ! ! #pragma vector = COMPARATORA_VECTOR ! __interrupt void COMPARATORA_ISR (void) { ! debugpins_isr_set(); ! __bic_SR_register_on_exit(CPUOFF); // restart CPU ! debugpins_isr_clr(); ! } ! ! #pragma vector = TIMERB1_VECTOR ! __interrupt void TIMERB1_ISR (void) { ! debugpins_isr_set(); ! if (radiotimer_isr()==KICK_SCHEDULER) { // radiotimer ! __bic_SR_register_on_exit(CPUOFF); ! } ! debugpins_isr_clr(); ! } ! ! // TIMERB0_VECTOR ! ! // NMI_VECTOR ! --- 1,65 ---- ! #include "msp430f1611.h" ! #include "board_ow.h" ! ! #include "leds.h" ! #include "uart_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 , February 2012. ! */ ! ! #ifndef __BOARD_H ! #define __BOARD_H ! ! #include "board_info.h" ! ! //=========================== define ========================================== ! ! typedef enum { ! DO_NOT_KICK_SCHEDULER, ! KICK_SCHEDULER, ! } kick_scheduler_t; ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void board_init(); ! void board_sleep(); ! void board_reset(); ! ! #endif --- 1,49 ---- ! #ifndef __BOARD_H ! #define __BOARD_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup board ! \{ ! ! \brief Cross-platform declaration "board" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "board_info.h" ! ! //=========================== define ========================================== ! ! typedef enum { ! DO_NOT_KICK_SCHEDULER, ! KICK_SCHEDULER, ! } kick_scheduler_t; ! ! #if defined(__GNUC__) && (__GNUC__==4) && (__GNUC_MINOR__<=5) && defined(__MSP430__) ! // mspgcc <4.5.x ! #include ! #define ISR(v) interrupt (v ## _VECTOR) v ## _ISR(void) ! #else ! // other ! #define __PRAGMA__(x) _Pragma(#x) ! #define ISR(v) __PRAGMA__(vector=v ##_VECTOR) __interrupt void v ##_ISR(void) ! #endif ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void board_init_ow(void); ! void board_sleep(void); ! void board_reset(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/cc2420.h ../../../sys/net/openwsn/cc2420.h *** openwsn/cc2420.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/cc2420.h Wed Jan 15 13:48:27 2014 *************** *** 1,407 **** ! /** ! \brief Register definitions for the Texas Instruments CC2420 radio chip. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __CC2420_H ! #define __CC2420_H ! ! //=========================== spi flags ======================================= ! ! #define CC2420_FLAG_READ 0x40 ! #define CC2420_FLAG_WRITE 0x00 ! ! #define CC2420_FLAG_RAM 0x80 ! #define CC2420_FLAG_REG 0x00 ! ! //=========================== status byte ===================================== ! ! typedef struct { ! uint8_t reserved_1:1; ! uint8_t rssi_valid:1; ! uint8_t lock:1; ! uint8_t tx_active:1; ! uint8_t enc_busy:1; ! uint8_t tx_underflow:1; ! uint8_t xosc16m_stable:1; ! uint8_t reserved_2:1; ! } cc2420_status_t; ! ! //=========================== strobes ========================================= ! ! #define CC2420_SNOP 0x00 // [S ] No Operation ! #define CC2420_SXOSCON 0x01 // [S ] Turn on the crystal oscillator ! #define CC2420_STXCAL 0x02 // [S ] Enable and calibrate frequency synthesizer for TX ! #define CC2420_SRXON 0x03 // [S ] Enable RX ! #define CC2420_STXON 0x04 // [S ] Enable TX after calibration (if not already performed) ! #define CC2420_STXONCCA 0x05 // [S ] If CCA indicates a clear channel, Enable calibration, then TX ! #define CC2420_SRFOFF 0x06 // [S ] Disable RX/TX and frequency synthesizer ! #define CC2420_SXOSCOFF 0x07 // [S ] Turn off the crystal oscillator and RF ! #define CC2420_SFLUSHRX 0x08 // [S ] Flush the RX FIFO buffer and reset the demodulator ! #define CC2420_SFLUSHTX 0x09 // [S ] Flush the TX FIFO buffer ! #define CC2420_SACK 0x0a // [S ] Send acknowledge frame, with pending field cleared ! #define CC2420_SACKPEND 0x0b // [S ] Send acknowledge frame, with pending field set ! #define CC2420_SRXDEC 0x0c // [S ] Start RXFIFO in-line decryption / authentication ! #define CC2420_STXENC 0x0d // [S ] Start TXFIFO in-line encryption / authentication ! #define CC2420_SAES 0x0e // [S ] AES Stand alone encryption strobe ! ! //=========================== registers ======================================= ! ! /// [R/W] Main Control Register ! #define CC2420_MAIN_ADDR 0x10 ! typedef struct { ! uint16_t XOSC16M_BYPASS:1; ! uint16_t reserved_w0:10; ! uint16_t FS_RESETn:1; ! uint16_t MOD_RESETn:1; ! uint16_t DEMOD_RESETn:1; ! uint16_t ENC_RESETn:1; ! uint16_t RESETn:1; ! } cc2420_MAIN_reg_t; ! ! /// [R/W] Modem Control Register 0 ! #define CC2420_MDMCTRL0_ADDR 0x11 ! typedef struct { ! uint16_t PREAMBLE_LENGTH:4; ! uint16_t AUTOACK:1; ! uint16_t AUTOCRC:1; ! uint16_t CCA_MODE:2; ! uint16_t CCA_HYST:3; ! uint16_t ADR_DECODE:1; ! uint16_t PAN_COORDINATOR:1; ! uint16_t RESERVED_FRAME_MODE:1; ! uint16_t reserved_w0:2; ! } cc2420_MDMCTRL0_reg_t; ! ! /// [R/W] Modem Control Register 1 ! #define CC2420_MDMCTRL1_ADDR 0x12 ! typedef struct { ! uint16_t RX_MODE:2; ! uint16_t TX_MODE:2; ! uint16_t MODULATION_MODE:1; ! uint16_t DEMOD_AVG_MODE:1; ! uint16_t CORR_THR:5; ! uint16_t reserved_w0:5; ! } cc2420_MDMCTRL1_reg_t; ! ! // [R/W] RSSI and CCA Status and Control register ! #define CC2420_RSSI_ADDR 0x13 ! typedef struct { ! uint16_t RSSI_VAL:8; ! uint16_t CCR_THR:8; ! } cc2420_RSSI_reg_t; ! ! /// [R/W] Synchronisation word control register ! #define CC2420_SYNCWORD_ADDR 0x14 ! typedef struct { ! uint16_t SYNCWORD:16; ! } cc2420_SYNCWORD_reg_t; ! ! /// [R/W] Transmit Control Register ! #define CC2420_TXCTRL_ADDR 0x15 ! typedef struct { ! uint16_t PA_LEVEL:5; ! uint16_t reserved_w1:1; ! uint16_t PA_CURRENT:3; ! uint16_t TXMIX_CURRENT:2; ! uint16_t TXMIX_CAP_ARRAY:2; ! uint16_t TX_TURNAROUND:1; ! uint16_t TXMIXBUF_CUR:2; ! } cc2420_TXCTRL_reg_t; ! ! /// [R/W] Receive Control Register 0 ! #define CC2420_RXCTRL0_ADDR 0x16 ! typedef struct { ! uint16_t LOW_LNA_CURRENT:2; ! uint16_t MED_LNA_CURRENT:2; ! uint16_t HIGH_LNA_CURRENT:2; ! uint16_t LOW_LNA_GAIN:2; ! uint16_t MED_LNA_GAIN:2; ! uint16_t HIGH_LNA_GAIN:2; ! uint16_t RXMIXBUF_CUR:2; ! uint16_t reserved_w0:2; ! } cc2420_RXCTRL0_reg_t; ! ! /// [R/W] Receive Control Register 1 ! #define CC2420_RXCTRL1_ADDR 0x17 ! typedef struct { ! uint16_t RXMIX_CURRENT:2; ! uint16_t RXMIX_VCM:2; ! uint16_t RXMIX_TAIL:2; ! uint16_t LNA_CAP_ARRAY:2; ! uint16_t MED_HGM:1; ! uint16_t HIGH_HGM:1; ! uint16_t MED_LOWGAIN:1; ! uint16_t LOW_LOWGAIN:1; ! uint16_t RXBPF_MIDCUR:1; ! uint16_t RXBPF_LOCUR:1; ! uint16_t reserved_w0:2; ! } cc2420_RXCTRL1_reg_t; ! ! /// [R/W] Frequency Synthesizer Control and Status Register ! #define CC2420_FSCTRL_ADDR 0x18 ! typedef struct { ! uint16_t FREQ:10; ! uint16_t LOCK_STATUS:1; ! uint16_t LOCK_LENGTH:1; ! uint16_t CAL_RUNNING:1; ! uint16_t CAL_DONE:1; ! uint16_t LOCK_THR:2; ! } cc2420_FSCTRL_reg_t; ! ! /// [R/W] Security Control Register 0 ! #define CC2420_SECCTRL0_ADDR 0x19 ! typedef struct { ! uint16_t SEC_MODE:2; ! uint16_t SEC_M:3; ! uint16_t SEC_RXKEYSEL:1; ! uint16_t SEC_TXKEYSEL:1; ! uint16_t SEC_SAKEYSEL:1; ! uint16_t SEC_CBC_HEAD:1; ! uint16_t RXFIFO_PROTECTION:1; ! uint16_t reserved_w0:6; ! } cc2420_SECCTRL0_reg_t; ! ! /// [R/W] Security Control Register 1 ! #define CC2420_SECCTRL1_ADDR 0x1a ! typedef struct { ! uint16_t SEC_RXL:7; ! uint16_t reserved_1_w0:1; ! uint16_t SEC_TXL:7; ! uint16_t reserved_2_w0:1; ! } cc2420_SECCTRL1_reg_t; ! ! /// [R/W] Battery Monitor Control and Status Register ! #define CC2420_BATTMON_ADDR 0x1b ! typedef struct { ! uint16_t BATTMON_VOLTAGE:5; ! uint16_t BATTMON_EN:1; ! uint16_t BATTMON_OK:1; ! uint16_t reserved_w0:9; ! } cc2420_BATTMON_reg_t; ! ! /// [R/W] Input / Output Control Register 0 ! #define CC2420_IOCFG0_ADDR 0x1c ! typedef struct { ! uint16_t FIFOP_THR:7; ! uint16_t CCA_POLARITY:1; ! uint16_t SFD_POLARITY:1; ! uint16_t FIFOP_POLARITY:1; ! uint16_t FIFO_POLARITY:1; ! uint16_t BCN_ACCEPT:1; ! uint16_t reserved_w0:4; ! } cc2420_IOCFG0_reg_t; ! ! /// [R/W] Input / Output Control Register 1 ! #define CC2420_IOCFG1_ADDR 0x1d ! typedef struct { ! uint16_t CCAMUX:5; ! uint16_t SFDMUX:5; ! uint16_t HSSD_SRC:3; ! uint16_t reserved_w0:3; ! } cc2420_IOCFG1_reg_t; ! ! /// [R/W] Manufacturer ID, Low 16 bits ! #define CC2420_MANFIDL_ADDR 0x1e ! typedef struct { ! uint16_t MANFID:12; ! uint16_t PARTNUM:4; ! } cc2420_MANFIDL_reg_t; ! ! /// [R/W] Manufacturer ID, High 16 bits ! #define CC2420_MANFIDH_ADDR 0x1f ! typedef struct { ! uint16_t PARTNUM:12; ! uint16_t VERSION:4; ! } cc2420_MANFIDH_reg_t; ! ! /// [R/W] Finite State Machine Time Constants ! #define CC2420_FSMTC_ADDR 0x20 ! typedef struct { ! uint16_t TC_TXEND2PAOFF:3; ! uint16_t TC_TXEND2SWITCH:3; ! uint16_t TC_PAON2TX:4; ! uint16_t TC_SWITCH2TX:3; ! uint16_t TC_RXCHAIN2RX:3; ! } cc2420_FSMTC_reg_t; ! ! /// [R/W] Manual signal AND override register ! #define CC2420_MANAND_ADDR 0x21 ! typedef struct { ! uint16_t LNAMIX_PD:1; ! uint16_t RXBPF_PD:1; ! uint16_t VGA_PD:1; ! uint16_t ADC_PD:1; ! uint16_t FS_PD:1; ! uint16_t CHP_PD:1; ! uint16_t RXBPF_CAL_PD:1; ! uint16_t XOSC16M_PD:1; ! uint16_t DAC_LPF_PD:1; ! uint16_t PA_P_PD:1; ! uint16_t PA_N_PD:1; ! uint16_t PRE_PD:1; ! uint16_t RXTX:1; ! uint16_t BALUN_CTRL:1; ! uint16_t BIAS_PD:1; ! uint16_t VGA_RESET_N:1; ! } cc2420_MANAND_reg_t; ! ! /// [R/W] Manual signal OR override register ! #define CC2420_MANOR_ADDR 0x22 ! typedef struct { ! uint16_t LNAMIX_PD:1; ! uint16_t RXBPF_PD:1; ! uint16_t VGA_PD:1; ! uint16_t ADC_PD:1; ! uint16_t FS_PD:1; ! uint16_t CHP_PD:1; ! uint16_t RXBPF_CAL_PD:1; ! uint16_t XOSC16M_PD:1; ! uint16_t DAC_LPF_PD:1; ! uint16_t PA_P_PD:1; ! uint16_t PA_N_PD:1; ! uint16_t PRE_PD:1; ! uint16_t RXTX:1; ! uint16_t BALUN_CTRL:1; ! uint16_t BIAS_PD:1; ! uint16_t VGA_RESET_N:1; ! } cc2420_MANOR_reg_t; ! ! /// [R/W] AGC Control Register ! #define CC2420_AGCCTRL_ADDR 0x23 ! typedef struct { ! uint16_t LNAMIX_GAINMODE:2; ! uint16_t LNAMIX_GAINMODE_O:2; ! uint16_t VGA_GAIN:7; ! uint16_t VGA_GAIN_OE:1; ! uint16_t reserved_w0:4; ! } cc2420_AGCCTRL_reg_t; ! ! /// [R/W] AGC Test Register 0 ! #define CC2420_AGCTST0_ADDR 0x24 ! typedef struct { ! uint16_t LNAMIX_THR_L:6; ! uint16_t LNAMIX_THR_H:6; ! uint16_t LNAMIX_HYST:4; ! } cc2420_AGCTST0_reg_t; ! ! /// [R/W] AGC Test Register 1 ! #define CC2420_AGCTST1_ADDR 0x25 ! typedef struct { ! uint16_t AGC_REF:6; ! uint16_t AGC_WIN_SIZE:2; ! uint16_t AGC_PEAK_DET_MODE:3; ! uint16_t AGC_SETTLE_WAIT:2; ! uint16_t PEAKDET_CUR_BOOST:1; ! uint16_t AGC_BLANK_MODE:1; ! uint16_t reserved_w0:1; ! } cc2420_AGCTST1_reg_t; ! ! /// [R/W] AGC Test Register 2 ! #define CC2420_AGCTST2_ADDR 0x26 ! typedef struct { ! uint16_t LOW2MEDGAIN:5; ! uint16_t MED2HIGHGAIN:5; ! uint16_t reserved_w0:6; ! } cc2420_AGCTST2_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 0 ! #define CC2420_FSTST0_ADDR 0x27 ! typedef struct { ! uint16_t VCO_ARRAY_RES:5; ! uint16_t VCO_ARRAY_O:5; ! uint16_t VCO_ARRAY_OE:1; ! uint16_t VCO_ARRAY_SETTLE_LONG:1; ! uint16_t reserved_w0:4; ! } cc2420_FSTST0_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 1 ! #define CC2420_FSTST1_ADDR 0x28 ! typedef struct { ! uint16_t VC_DAC_VAL:3; ! uint16_t VC_DAC_EN:1; ! uint16_t VCO_CURRENT_K:6; ! uint16_t VCO_CURRENT_REF:4; ! uint16_t VCO_ARRAY_CAL_LONG:1; ! uint16_t VCO_TX_NOCAL:1; ! } cc2420_FSTST1_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 2 ! #define CC2420_FSTST2_ADDR 0x29 ! typedef struct { ! uint16_t VCO_CURRENT_RES:6; ! uint16_t VCO_CURRENT_O:6; ! uint16_t VCO_CURRENT_OE:1; ! uint16_t VCO_CURCAL_SPEED:2; ! uint16_t reserved_w0:1; ! } cc2420_FSTST2_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 3 ! #define CC2420_FSTST3_ADDR 0x2a ! typedef struct { ! uint16_t START_CHP_CURRENT:4; ! uint16_t STOP_CHP_CURRENT:4; ! uint16_t CHP_STEP_PERIOD:2; ! uint16_t PD_DELAY:1; ! uint16_t CHP_DISABLE:1; ! uint16_t CHP_TEST_DN:1; ! uint16_t CHP_TEST_UP:1; ! uint16_t CHP_CURRENT_OE:1; ! uint16_t CHP_CAL_DISABLE:1; ! } cc2420_FSTST3_reg_t; ! ! /// [R/W] Receiver Bandpass Filter Test Register ! #define CC2420_RXBPFTST_ADDR 0x2b ! typedef struct { ! uint16_t RXBPF_CAP_RES:7; ! uint16_t RXBPF_CAP_O:7; ! uint16_t RXBPF_CAP_OE:1; ! uint16_t reserved_w0:1; ! } cc2420_RXBPFTST_reg_t; ! ! /// [R ] Finite State Machine State Status Register ! #define CC2420_FSMSTATE_ADDR 0x2c ! typedef struct { ! uint16_t FSM_CUR_STATE:6; ! uint16_t reserved_w0:10; ! } cc2420_FSMSTATE_reg_t; ! ! /// [R/W] ADC Test Register ! #define CC2420_ADCTST_ADDR 0x2d ! typedef struct { ! uint16_t ADC_Q:7; ! uint16_t reserved_w0:1; ! uint16_t ADC_I:7; ! uint16_t ADC_CLOCK_DISABLE:1; ! } cc2420_ADCTST_reg_t; ! ! /// [R/W] DAC Test Register ! #define CC2420_DACTST_ADDR 0x2e ! typedef struct { ! uint16_t DAC_Q_O:6; ! uint16_t DAC_I_O:6; ! uint16_t DAC_SRC:3; ! uint16_t reserved_w0:1; ! } cc2420_DACTST_reg_t; ! ! /// [R/W] Top Level Test Register ! #define CC2420_TOPTST_ADDR 0x2f ! typedef struct { ! uint16_t ATESTMOD_MODE:4; ! uint16_t ATESTMOD_PD:1; ! uint16_t VC_IN_TEST_EN:1; ! uint16_t TEST_BATTMON_EN:1; ! uint16_t RAM_BIST_RUN:1; ! uint16_t reserved_w0:8; ! } cc2420_TOPTST_reg_t; ! ! //=========================== buffer ========================================== ! ! /// [ W] Transmit FIFO Byte Register ! #define CC2420_TXFIFO_ADDR 0x3e ! ! /// [R/W] Receiver FIFO Byte Register ! #define CC2420_RXFIFO_ADDR 0x3f ! #endif \ No newline at end of file --- 1,407 ---- ! /** ! \brief Register definitions for the Texas Instruments CC2420 radio chip. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __CC2420_H ! #define __CC2420_H ! ! //=========================== spi flags ======================================= ! ! #define CC2420_FLAG_READ 0x40 ! #define CC2420_FLAG_WRITE 0x00 ! ! #define CC2420_FLAG_RAM 0x80 ! #define CC2420_FLAG_REG 0x00 ! ! //=========================== status byte ===================================== ! ! typedef struct { ! uint8_t reserved_1:1; ! uint8_t rssi_valid:1; ! uint8_t lock:1; ! uint8_t tx_active:1; ! uint8_t enc_busy:1; ! uint8_t tx_underflow:1; ! uint8_t xosc16m_stable:1; ! uint8_t reserved_2:1; ! } cc2420_status_t; ! ! //=========================== strobes ========================================= ! ! #define CC2420_SNOP 0x00 // [S ] No Operation ! #define CC2420_SXOSCON 0x01 // [S ] Turn on the crystal oscillator ! #define CC2420_STXCAL 0x02 // [S ] Enable and calibrate frequency synthesizer for TX ! #define CC2420_SRXON 0x03 // [S ] Enable RX ! #define CC2420_STXON 0x04 // [S ] Enable TX after calibration (if not already performed) ! #define CC2420_STXONCCA 0x05 // [S ] If CCA indicates a clear channel, Enable calibration, then TX ! #define CC2420_SRFOFF 0x06 // [S ] Disable RX/TX and frequency synthesizer ! #define CC2420_SXOSCOFF 0x07 // [S ] Turn off the crystal oscillator and RF ! #define CC2420_SFLUSHRX 0x08 // [S ] Flush the RX FIFO buffer and reset the demodulator ! #define CC2420_SFLUSHTX 0x09 // [S ] Flush the TX FIFO buffer ! #define CC2420_SACK 0x0a // [S ] Send acknowledge frame, with pending field cleared ! #define CC2420_SACKPEND 0x0b // [S ] Send acknowledge frame, with pending field set ! #define CC2420_SRXDEC 0x0c // [S ] Start RXFIFO in-line decryption / authentication ! #define CC2420_STXENC 0x0d // [S ] Start TXFIFO in-line encryption / authentication ! #define CC2420_SAES 0x0e // [S ] AES Stand alone encryption strobe ! ! //=========================== registers ======================================= ! ! /// [R/W] Main Control Register ! #define CC2420_MAIN_ADDR 0x10 ! typedef struct { ! uint16_t XOSC16M_BYPASS:1; ! uint16_t reserved_w0:10; ! uint16_t FS_RESETn:1; ! uint16_t MOD_RESETn:1; ! uint16_t DEMOD_RESETn:1; ! uint16_t ENC_RESETn:1; ! uint16_t RESETn:1; ! } cc2420_MAIN_reg_t; ! ! /// [R/W] Modem Control Register 0 ! #define CC2420_MDMCTRL0_ADDR 0x11 ! typedef struct { ! uint16_t PREAMBLE_LENGTH:4; ! uint16_t AUTOACK:1; ! uint16_t AUTOCRC:1; ! uint16_t CCA_MODE:2; ! uint16_t CCA_HYST:3; ! uint16_t ADR_DECODE:1; ! uint16_t PAN_COORDINATOR:1; ! uint16_t RESERVED_FRAME_MODE:1; ! uint16_t reserved_w0:2; ! } cc2420_MDMCTRL0_reg_t; ! ! /// [R/W] Modem Control Register 1 ! #define CC2420_MDMCTRL1_ADDR 0x12 ! typedef struct { ! uint16_t RX_MODE:2; ! uint16_t TX_MODE:2; ! uint16_t MODULATION_MODE:1; ! uint16_t DEMOD_AVG_MODE:1; ! uint16_t CORR_THR:5; ! uint16_t reserved_w0:5; ! } cc2420_MDMCTRL1_reg_t; ! ! // [R/W] RSSI and CCA Status and Control register ! #define CC2420_RSSI_ADDR 0x13 ! typedef struct { ! uint16_t RSSI_VAL:8; ! uint16_t CCR_THR:8; ! } cc2420_RSSI_reg_t; ! ! /// [R/W] Synchronisation word control register ! #define CC2420_SYNCWORD_ADDR 0x14 ! typedef struct { ! uint16_t SYNCWORD:16; ! } cc2420_SYNCWORD_reg_t; ! ! /// [R/W] Transmit Control Register ! #define CC2420_TXCTRL_ADDR 0x15 ! typedef struct { ! uint16_t PA_LEVEL:5; ! uint16_t reserved_w1:1; ! uint16_t PA_CURRENT:3; ! uint16_t TXMIX_CURRENT:2; ! uint16_t TXMIX_CAP_ARRAY:2; ! uint16_t TX_TURNAROUND:1; ! uint16_t TXMIXBUF_CUR:2; ! } cc2420_TXCTRL_reg_t; ! ! /// [R/W] Receive Control Register 0 ! #define CC2420_RXCTRL0_ADDR 0x16 ! typedef struct { ! uint16_t LOW_LNA_CURRENT:2; ! uint16_t MED_LNA_CURRENT:2; ! uint16_t HIGH_LNA_CURRENT:2; ! uint16_t LOW_LNA_GAIN:2; ! uint16_t MED_LNA_GAIN:2; ! uint16_t HIGH_LNA_GAIN:2; ! uint16_t RXMIXBUF_CUR:2; ! uint16_t reserved_w0:2; ! } cc2420_RXCTRL0_reg_t; ! ! /// [R/W] Receive Control Register 1 ! #define CC2420_RXCTRL1_ADDR 0x17 ! typedef struct { ! uint16_t RXMIX_CURRENT:2; ! uint16_t RXMIX_VCM:2; ! uint16_t RXMIX_TAIL:2; ! uint16_t LNA_CAP_ARRAY:2; ! uint16_t MED_HGM:1; ! uint16_t HIGH_HGM:1; ! uint16_t MED_LOWGAIN:1; ! uint16_t LOW_LOWGAIN:1; ! uint16_t RXBPF_MIDCUR:1; ! uint16_t RXBPF_LOCUR:1; ! uint16_t reserved_w0:2; ! } cc2420_RXCTRL1_reg_t; ! ! /// [R/W] Frequency Synthesizer Control and Status Register ! #define CC2420_FSCTRL_ADDR 0x18 ! typedef struct { ! uint16_t FREQ:10; ! uint16_t LOCK_STATUS:1; ! uint16_t LOCK_LENGTH:1; ! uint16_t CAL_RUNNING:1; ! uint16_t CAL_DONE:1; ! uint16_t LOCK_THR:2; ! } cc2420_FSCTRL_reg_t; ! ! /// [R/W] Security Control Register 0 ! #define CC2420_SECCTRL0_ADDR 0x19 ! typedef struct { ! uint16_t SEC_MODE:2; ! uint16_t SEC_M:3; ! uint16_t SEC_RXKEYSEL:1; ! uint16_t SEC_TXKEYSEL:1; ! uint16_t SEC_SAKEYSEL:1; ! uint16_t SEC_CBC_HEAD:1; ! uint16_t RXFIFO_PROTECTION:1; ! uint16_t reserved_w0:6; ! } cc2420_SECCTRL0_reg_t; ! ! /// [R/W] Security Control Register 1 ! #define CC2420_SECCTRL1_ADDR 0x1a ! typedef struct { ! uint16_t SEC_RXL:7; ! uint16_t reserved_1_w0:1; ! uint16_t SEC_TXL:7; ! uint16_t reserved_2_w0:1; ! } cc2420_SECCTRL1_reg_t; ! ! /// [R/W] Battery Monitor Control and Status Register ! #define CC2420_BATTMON_ADDR 0x1b ! typedef struct { ! uint16_t BATTMON_VOLTAGE:5; ! uint16_t BATTMON_EN:1; ! uint16_t BATTMON_OK:1; ! uint16_t reserved_w0:9; ! } cc2420_BATTMON_reg_t; ! ! /// [R/W] Input / Output Control Register 0 ! #define CC2420_IOCFG0_ADDR 0x1c ! typedef struct { ! uint16_t FIFOP_THR:7; ! uint16_t CCA_POLARITY:1; ! uint16_t SFD_POLARITY:1; ! uint16_t FIFOP_POLARITY:1; ! uint16_t FIFO_POLARITY:1; ! uint16_t BCN_ACCEPT:1; ! uint16_t reserved_w0:4; ! } cc2420_IOCFG0_reg_t; ! ! /// [R/W] Input / Output Control Register 1 ! #define CC2420_IOCFG1_ADDR 0x1d ! typedef struct { ! uint16_t CCAMUX:5; ! uint16_t SFDMUX:5; ! uint16_t HSSD_SRC:3; ! uint16_t reserved_w0:3; ! } cc2420_IOCFG1_reg_t; ! ! /// [R/W] Manufacturer ID, Low 16 bits ! #define CC2420_MANFIDL_ADDR 0x1e ! typedef struct { ! uint16_t MANFID:12; ! uint16_t PARTNUM:4; ! } cc2420_MANFIDL_reg_t; ! ! /// [R/W] Manufacturer ID, High 16 bits ! #define CC2420_MANFIDH_ADDR 0x1f ! typedef struct { ! uint16_t PARTNUM:12; ! uint16_t AVERSION:4; // collision with -DVERSION=$(GIT_VERSION) ! } cc2420_MANFIDH_reg_t; ! ! /// [R/W] Finite State Machine Time Constants ! #define CC2420_FSMTC_ADDR 0x20 ! typedef struct { ! uint16_t TC_TXEND2PAOFF:3; ! uint16_t TC_TXEND2SWITCH:3; ! uint16_t TC_PAON2TX:4; ! uint16_t TC_SWITCH2TX:3; ! uint16_t TC_RXCHAIN2RX:3; ! } cc2420_FSMTC_reg_t; ! ! /// [R/W] Manual signal AND override register ! #define CC2420_MANAND_ADDR 0x21 ! typedef struct { ! uint16_t LNAMIX_PD:1; ! uint16_t RXBPF_PD:1; ! uint16_t VGA_PD:1; ! uint16_t ADC_PD:1; ! uint16_t FS_PD:1; ! uint16_t CHP_PD:1; ! uint16_t RXBPF_CAL_PD:1; ! uint16_t XOSC16M_PD:1; ! uint16_t DAC_LPF_PD:1; ! uint16_t PA_P_PD:1; ! uint16_t PA_N_PD:1; ! uint16_t PRE_PD:1; ! uint16_t RXTX:1; ! uint16_t BALUN_CTRL:1; ! uint16_t BIAS_PD:1; ! uint16_t VGA_RESET_N:1; ! } cc2420_MANAND_reg_t; ! ! /// [R/W] Manual signal OR override register ! #define CC2420_MANOR_ADDR 0x22 ! typedef struct { ! uint16_t LNAMIX_PD:1; ! uint16_t RXBPF_PD:1; ! uint16_t VGA_PD:1; ! uint16_t ADC_PD:1; ! uint16_t FS_PD:1; ! uint16_t CHP_PD:1; ! uint16_t RXBPF_CAL_PD:1; ! uint16_t XOSC16M_PD:1; ! uint16_t DAC_LPF_PD:1; ! uint16_t PA_P_PD:1; ! uint16_t PA_N_PD:1; ! uint16_t PRE_PD:1; ! uint16_t RXTX:1; ! uint16_t BALUN_CTRL:1; ! uint16_t BIAS_PD:1; ! uint16_t VGA_RESET_N:1; ! } cc2420_MANOR_reg_t; ! ! /// [R/W] AGC Control Register ! #define CC2420_AGCCTRL_ADDR 0x23 ! typedef struct { ! uint16_t LNAMIX_GAINMODE:2; ! uint16_t LNAMIX_GAINMODE_O:2; ! uint16_t VGA_GAIN:7; ! uint16_t VGA_GAIN_OE:1; ! uint16_t reserved_w0:4; ! } cc2420_AGCCTRL_reg_t; ! ! /// [R/W] AGC Test Register 0 ! #define CC2420_AGCTST0_ADDR 0x24 ! typedef struct { ! uint16_t LNAMIX_THR_L:6; ! uint16_t LNAMIX_THR_H:6; ! uint16_t LNAMIX_HYST:4; ! } cc2420_AGCTST0_reg_t; ! ! /// [R/W] AGC Test Register 1 ! #define CC2420_AGCTST1_ADDR 0x25 ! typedef struct { ! uint16_t AGC_REF:6; ! uint16_t AGC_WIN_SIZE:2; ! uint16_t AGC_PEAK_DET_MODE:3; ! uint16_t AGC_SETTLE_WAIT:2; ! uint16_t PEAKDET_CUR_BOOST:1; ! uint16_t AGC_BLANK_MODE:1; ! uint16_t reserved_w0:1; ! } cc2420_AGCTST1_reg_t; ! ! /// [R/W] AGC Test Register 2 ! #define CC2420_AGCTST2_ADDR 0x26 ! typedef struct { ! uint16_t LOW2MEDGAIN:5; ! uint16_t MED2HIGHGAIN:5; ! uint16_t reserved_w0:6; ! } cc2420_AGCTST2_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 0 ! #define CC2420_FSTST0_ADDR 0x27 ! typedef struct { ! uint16_t VCO_ARRAY_RES:5; ! uint16_t VCO_ARRAY_O:5; ! uint16_t VCO_ARRAY_OE:1; ! uint16_t VCO_ARRAY_SETTLE_LONG:1; ! uint16_t reserved_w0:4; ! } cc2420_FSTST0_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 1 ! #define CC2420_FSTST1_ADDR 0x28 ! typedef struct { ! uint16_t VC_DAC_VAL:3; ! uint16_t VC_DAC_EN:1; ! uint16_t VCO_CURRENT_K:6; ! uint16_t VCO_CURRENT_REF:4; ! uint16_t VCO_ARRAY_CAL_LONG:1; ! uint16_t VCO_TX_NOCAL:1; ! } cc2420_FSTST1_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 2 ! #define CC2420_FSTST2_ADDR 0x29 ! typedef struct { ! uint16_t VCO_CURRENT_RES:6; ! uint16_t VCO_CURRENT_O:6; ! uint16_t VCO_CURRENT_OE:1; ! uint16_t VCO_CURCAL_SPEED:2; ! uint16_t reserved_w0:1; ! } cc2420_FSTST2_reg_t; ! ! /// [R/W] Frequency Synthesizer Test Register 3 ! #define CC2420_FSTST3_ADDR 0x2a ! typedef struct { ! uint16_t START_CHP_CURRENT:4; ! uint16_t STOP_CHP_CURRENT:4; ! uint16_t CHP_STEP_PERIOD:2; ! uint16_t PD_DELAY:1; ! uint16_t CHP_DISABLE:1; ! uint16_t CHP_TEST_DN:1; ! uint16_t CHP_TEST_UP:1; ! uint16_t CHP_CURRENT_OE:1; ! uint16_t CHP_CAL_DISABLE:1; ! } cc2420_FSTST3_reg_t; ! ! /// [R/W] Receiver Bandpass Filter Test Register ! #define CC2420_RXBPFTST_ADDR 0x2b ! typedef struct { ! uint16_t RXBPF_CAP_RES:7; ! uint16_t RXBPF_CAP_O:7; ! uint16_t RXBPF_CAP_OE:1; ! uint16_t reserved_w0:1; ! } cc2420_RXBPFTST_reg_t; ! ! /// [R ] Finite State Machine State Status Register ! #define CC2420_FSMSTATE_ADDR 0x2c ! typedef struct { ! uint16_t FSM_CUR_STATE:6; ! uint16_t reserved_w0:10; ! } cc2420_FSMSTATE_reg_t; ! ! /// [R/W] ADC Test Register ! #define CC2420_ADCTST_ADDR 0x2d ! typedef struct { ! uint16_t ADC_Q:7; ! uint16_t reserved_w0:1; ! uint16_t ADC_I:7; ! uint16_t ADC_CLOCK_DISABLE:1; ! } cc2420_ADCTST_reg_t; ! ! /// [R/W] DAC Test Register ! #define CC2420_DACTST_ADDR 0x2e ! typedef struct { ! uint16_t DAC_Q_O:6; ! uint16_t DAC_I_O:6; ! uint16_t DAC_SRC:3; ! uint16_t reserved_w0:1; ! } cc2420_DACTST_reg_t; ! ! /// [R/W] Top Level Test Register ! #define CC2420_TOPTST_ADDR 0x2f ! typedef struct { ! uint16_t ATESTMOD_MODE:4; ! uint16_t ATESTMOD_PD:1; ! uint16_t VC_IN_TEST_EN:1; ! uint16_t TEST_BATTMON_EN:1; ! uint16_t RAM_BIST_RUN:1; ! uint16_t reserved_w0:8; ! } cc2420_TOPTST_reg_t; ! ! //=========================== buffer ========================================== ! ! /// [ W] Transmit FIFO Byte Register ! #define CC2420_TXFIFO_ADDR 0x3e ! ! /// [R/W] Receiver FIFO Byte Register ! #define CC2420_RXFIFO_ADDR 0x3f ! #endif \ No newline at end of file diff -crB openwsn/cross-layers/Makefile ../../../sys/net/openwsn/cross-layers/Makefile *** openwsn/cross-layers/Makefile Wed Jan 15 13:55:34 2014 --- ../../../sys/net/openwsn/cross-layers/Makefile Wed Jan 15 13:48:27 2014 *************** *** 0 **** --- 1,32 ---- + SUBMOD:=$(shell basename $(CURDIR)).a + #BINDIR = $(RIOTBASE)/bin/ + SRC = $(wildcard *.c) + OBJ = $(SRC:%.c=$(BINDIR)%.o) + DEP = $(SRC:%.c=$(BINDIR)%.d) + + INCLUDES += -I$(RIOTBASE) -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -I$(RIOTBASE)/drivers/include -I$(RIOTBASE)/drivers/cc110x_ng/include -I$(RIOTBASE)/cpu/arm_common/include -I$(RIOTBASE)/sys/net/include/ + INCLUDES += -I$(CURDIR)/02a-MAClow + INCLUDES += -I$(CURDIR)/02b-MAChigh + INCLUDES += -I$(CURDIR)/03a-IPHC + INCLUDES += -I$(CURDIR)/03b-IPv6 + INCLUDES += -I$(CURDIR)/04-TRAN + INCLUDES += -I$(CURDIR)/cross-layers + + .PHONY: $(BINDIR)$(SUBMOD) + + $(BINDIR)$(SUBMOD): $(OBJ) + $(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 + $(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 COMPONENT_IEEE802154E){ ! ENABLE_INTERRUPTS(); ! return NULL; ! } ! ! // if you get here, I will try to allocate a buffer for you ! ! // walk through queue and find free entry ! for (i=0;itype==ADDR_64B) { ! // a neighbor is specified, look for a packet unicast to that neigbhbor ! for (i=0;itype==ADDR_ANYCAST) { ! // anycast case: look for a packet which is either not created by RES ! // or an KA (created by RES, but not broadcast) ! for (i=0;icreator = COMPONENT_NULL; ! entry->owner = COMPONENT_NULL; ! entry->payload = &(entry->packet[127]); ! entry->length = 0; ! //l4 ! entry->l4_protocol = IANA_UNDEFINED; ! //l3 ! entry->l3_destinationAdd.type = ADDR_NONE; ! entry->l3_sourceAdd.type = ADDR_NONE; ! //l2 ! entry->l2_nextORpreviousHop.type = ADDR_NONE; ! entry->l2_frameType = IEEE154_TYPE_UNDEFINED; ! entry->l2_retriesLeft = 0; ! } --- 1,257 ---- ! #include "openwsn.h" ! #include "openqueue.h" ! #include "openserial.h" ! #include "packetfunctions.h" ! #include "IEEE802154E.h" ! ! //=========================== variables ======================================= ! ! openqueue_vars_t openqueue_vars; ! ! //=========================== prototypes ====================================== ! ! void openqueue_reset_entry(OpenQueueEntry_t* entry); ! ! //=========================== public ========================================== ! ! //======= admin ! ! /** ! \brief Initialize this module. ! */ ! void openqueue_init(void) { ! uint8_t i; ! for (i=0;i COMPONENT_IEEE802154E){ ! ENABLE_INTERRUPTS(); ! return NULL; ! } ! ! // if you get here, I will try to allocate a buffer for you ! ! // walk through queue and find free entry ! for (i=0;itype==ADDR_64B) { ! // a neighbor is specified, look for a packet unicast to that neigbhbor ! for (i=0;itype==ADDR_ANYCAST) { ! // anycast case: look for a packet which is either not created by RES ! // or an KA (created by RES, but not broadcast) ! for (i=0;icreator = COMPONENT_NULL; ! entry->owner = COMPONENT_NULL; ! entry->payload = &(entry->packet[127]); ! entry->length = 0; ! //l4 ! entry->l4_protocol = IANA_UNDEFINED; ! //l3 ! entry->l3_destinationAdd.type = ADDR_NONE; ! entry->l3_sourceAdd.type = ADDR_NONE; ! //l2 ! entry->l2_nextORpreviousHop.type = ADDR_NONE; ! entry->l2_frameType = IEEE154_TYPE_UNDEFINED; ! entry->l2_retriesLeft = 0; ! } diff -crB openwsn/cross-layers/openqueue.h ../../../sys/net/openwsn/cross-layers/openqueue.h *** openwsn/cross-layers/openqueue.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/cross-layers/openqueue.h Wed Jan 15 13:48:27 2014 *************** *** 1,49 **** ! #ifndef __OPENQUEUE_H ! #define __OPENQUEUE_H ! ! /** ! \addtogroup cross-layers ! \{ ! \addtogroup OpenQueue ! \{ ! */ ! ! #include "openwsn.h" ! #include "IEEE802154.h" ! ! //=========================== define ========================================== ! ! #define QUEUELENGTH 10 ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint8_t creator; ! uint8_t owner; ! } debugOpenQueueEntry_t; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void openqueue_init(); ! bool debugPrint_queue(); ! // called by any component ! OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator); ! error_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt); ! void openqueue_removeAllCreatedBy(uint8_t creator); ! void openqueue_removeAllOwnedBy(uint8_t owner); ! // called by res ! OpenQueueEntry_t* openqueue_resGetSentPacket(); ! OpenQueueEntry_t* openqueue_resGetReceivedPacket(); ! // called by IEEE80215E ! OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor); ! OpenQueueEntry_t* openqueue_macGetAdvPacket(); ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,53 ---- ! #ifndef __OPENQUEUE_H ! #define __OPENQUEUE_H ! ! /** ! \addtogroup cross-layers ! \{ ! \addtogroup OpenQueue ! \{ ! */ ! ! #include "openwsn.h" ! #include "IEEE802154.h" ! ! //=========================== define ========================================== ! ! #define QUEUELENGTH 10 ! ! //=========================== typedef ========================================= ! ! typedef struct { ! uint8_t creator; ! uint8_t owner; ! } debugOpenQueueEntry_t; ! ! //=========================== module variables ================================ ! ! typedef struct { ! OpenQueueEntry_t queue[QUEUELENGTH]; ! } openqueue_vars_t; ! ! //=========================== prototypes ====================================== ! ! // admin ! void openqueue_init(void); ! bool debugPrint_queue(void); ! // called by any component ! OpenQueueEntry_t* openqueue_getFreePacketBuffer(uint8_t creator); ! owerror_t openqueue_freePacketBuffer(OpenQueueEntry_t* pkt); ! void openqueue_removeAllCreatedBy(uint8_t creator); ! void openqueue_removeAllOwnedBy(uint8_t owner); ! // called by res ! OpenQueueEntry_t* openqueue_resGetSentPacket(void); ! OpenQueueEntry_t* openqueue_resGetReceivedPacket(void); ! // called by IEEE80215E ! OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor); ! OpenQueueEntry_t* openqueue_macGetAdvPacket(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/cross-layers/openrandom.c ../../../sys/net/openwsn/cross-layers/openrandom.c *** openwsn/cross-layers/openrandom.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/cross-layers/openrandom.c Wed Jan 15 13:48:27 2014 *************** *** 1,38 **** ! #include "openwsn.h" ! #include "openrandom.h" ! #include "idmanager.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! uint16_t shift_reg; // Galois shift register used to obtain a pseudo-random number ! } random_vars_t; ! ! random_vars_t random_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void openrandom_init() { ! // seed the random number generator with the last 2 bytes of the MAC address ! random_vars.shift_reg = 0; ! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[0]*256; ! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[1]; ! } ! ! uint16_t openrandom_get16b() { ! uint8_t i; ! uint16_t random_value; ! random_value = 0; ! for(i=0;i<16;i++) { ! // Galois shift register ! // taps: 16 14 13 11 ! // characteristic polynomial: x^16 + x^14 + x^13 + x^11 + 1 ! random_value |= (random_vars.shift_reg & 0x01)<>1)^(-(int16_t)(random_vars.shift_reg & 1)&0xb400); ! } ! return random_value; ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,34 ---- ! #include "openwsn.h" ! #include "openrandom.h" ! #include "idmanager.h" ! ! //=========================== variables ======================================= ! ! random_vars_t random_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void openrandom_init(void) { ! // seed the random number generator with the last 2 bytes of the MAC address ! random_vars.shift_reg = 0; ! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[0]*256; ! random_vars.shift_reg += idmanager_getMyID(ADDR_16B)->addr_16b[1]; ! } ! ! uint16_t openrandom_get16b(void) { ! uint8_t i; ! uint16_t random_value; ! random_value = 0; ! for(i=0;i<16;i++) { ! // Galois shift register ! // taps: 16 14 13 11 ! // characteristic polynomial: x^16 + x^14 + x^13 + x^11 + 1 ! random_value |= (random_vars.shift_reg & 0x01)<>1)^(-(int16_t)(random_vars.shift_reg & 1)&0xb400); ! } ! return random_value; ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/cross-layers/openrandom.h ../../../sys/net/openwsn/cross-layers/openrandom.h *** openwsn/cross-layers/openrandom.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/cross-layers/openrandom.h Wed Jan 15 13:48:27 2014 *************** *** 1,29 **** ! #ifndef __OPENRANDOM_H ! #define __OPENRANDOM_H ! ! /** ! \addtogroup helpers ! \{ ! \addtogroup Random ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void openrandom_init(); ! uint16_t openrandom_get16b(); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,33 ---- ! #ifndef __OPENRANDOM_H ! #define __OPENRANDOM_H ! ! /** ! \addtogroup cross-layers ! \{ ! \addtogroup OpenRandom ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== module variables ================================ ! ! typedef struct { ! uint16_t shift_reg; // Galois shift register used to obtain a pseudo-random number ! } random_vars_t; ! ! //=========================== prototypes ====================================== ! ! void openrandom_init(void); ! uint16_t openrandom_get16b(void); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/cross-layers/packetfunctions.c ../../../sys/net/openwsn/cross-layers/packetfunctions.c *** openwsn/cross-layers/packetfunctions.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/cross-layers/packetfunctions.c Wed Jan 15 13:48:27 2014 *************** *** 1,447 **** ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "idmanager.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length); ! ! //=========================== public ========================================== ! ! //======= address translation ! ! //assuming an ip128b is a concatenation of prefix64b followed by a mac64b ! void packetfunctions_ip128bToMac64b( ! open_addr_t* ip128b, ! open_addr_t* prefix64btoWrite, ! open_addr_t* mac64btoWrite) { ! if (ip128b->type!=ADDR_128B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)ip128b->type, ! (errorparameter_t)0); ! mac64btoWrite->type=ADDR_NONE; ! return; ! } ! prefix64btoWrite->type=ADDR_PREFIX; ! memcpy(prefix64btoWrite->prefix, &(ip128b->addr_128b[0]), 8); ! mac64btoWrite->type=ADDR_64B; ! memcpy(mac64btoWrite->addr_64b , &(ip128b->addr_128b[8]), 8); ! } ! void packetfunctions_mac64bToIp128b( ! open_addr_t* prefix64b, ! open_addr_t* mac64b, ! open_addr_t* ip128bToWrite) { ! if (prefix64b->type!=ADDR_PREFIX || mac64b->type!=ADDR_64B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)prefix64b->type, ! (errorparameter_t)1); ! ip128bToWrite->type=ADDR_NONE; ! return; ! } ! ip128bToWrite->type=ADDR_128B; ! memcpy(&(ip128bToWrite->addr_128b[0]), &(prefix64b->prefix[0]), 8); ! memcpy(&(ip128bToWrite->addr_128b[8]), &(mac64b->addr_64b[0]), 8); ! } ! ! //assuming an mac16b is lower 2B of mac64b ! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite) { ! if (mac64b->type!=ADDR_64B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)mac64b->type, ! (errorparameter_t)2); ! mac16btoWrite->type=ADDR_NONE; ! return; ! } ! mac16btoWrite->type = ADDR_16B; ! mac16btoWrite->addr_16b[0] = mac64b->addr_64b[6]; ! mac16btoWrite->addr_16b[1] = mac64b->addr_64b[7]; ! } ! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite) { ! if (mac16b->type!=ADDR_16B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)mac16b->type, ! (errorparameter_t)3); ! mac64btoWrite->type=ADDR_NONE; ! return; ! } ! mac64btoWrite->type = ADDR_64B; ! mac64btoWrite->addr_64b[0] = 0; ! mac64btoWrite->addr_64b[1] = 0; ! mac64btoWrite->addr_64b[2] = 0; ! mac64btoWrite->addr_64b[3] = 0; ! mac64btoWrite->addr_64b[4] = 0; ! mac64btoWrite->addr_64b[5] = 0; ! mac64btoWrite->addr_64b[6] = mac16b->addr_16b[0]; ! mac64btoWrite->addr_64b[7] = mac16b->addr_16b[1]; ! } ! ! //======= address recognition ! ! bool packetfunctions_isBroadcastMulticast(open_addr_t* address) { ! uint8_t i; ! uint8_t address_length; ! //IPv6 multicast ! if (address->type==ADDR_128B) { ! if (address->addr_128b[0]==0xff) { ! return TRUE; ! } else { ! return FALSE; ! } ! } ! //15.4 broadcast ! switch (address->type) { ! case ADDR_16B: ! address_length = 2; ! break; ! case ADDR_64B: ! address_length = 8; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)4); ! return FALSE; ! } ! for (i=0;iaddr_128b[i]!=0xFF) { ! return FALSE; ! } ! } ! return TRUE; ! } ! ! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address) { ! if ( ! address->type == ADDR_128B && ! address->addr_128b[0] == 0xff && ! address->addr_128b[1] == 0x02 && ! address->addr_128b[2] == 0x00 && ! address->addr_128b[3] == 0x00 && ! address->addr_128b[4] == 0x00 && ! address->addr_128b[5] == 0x00 && ! address->addr_128b[6] == 0x00 && ! address->addr_128b[7] == 0x00 && ! address->addr_128b[8] == 0x00 && ! address->addr_128b[9] == 0x00 && ! address->addr_128b[10] == 0x00 && ! address->addr_128b[11] == 0x00 && ! address->addr_128b[12] == 0x00 && ! address->addr_128b[13] == 0x00 && ! address->addr_128b[14] == 0x00 && ! address->addr_128b[15] == 0x02 ! ) { ! return TRUE; ! } ! return FALSE; ! } ! ! bool packetfunctions_isAllHostsMulticast(open_addr_t* address) { ! if ( ! address->type == ADDR_128B && ! address->addr_128b[0] == 0xff && ! address->addr_128b[1] == 0x02 && ! address->addr_128b[2] == 0x00 && ! address->addr_128b[3] == 0x00 && ! address->addr_128b[4] == 0x00 && ! address->addr_128b[5] == 0x00 && ! address->addr_128b[6] == 0x00 && ! address->addr_128b[7] == 0x00 && ! address->addr_128b[8] == 0x00 && ! address->addr_128b[9] == 0x00 && ! address->addr_128b[10] == 0x00 && ! address->addr_128b[11] == 0x00 && ! address->addr_128b[12] == 0x00 && ! address->addr_128b[13] == 0x00 && ! address->addr_128b[14] == 0x00 && ! address->addr_128b[15] == 0x01 ! ) { ! return TRUE; ! } ! return FALSE; ! } ! ! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2) { ! uint8_t address_length; ! ! if (address_1->type!=address_2->type) { ! return FALSE; ! } ! switch (address_1->type) { ! case ADDR_16B: ! case ADDR_PANID: ! address_length = 2; ! break; ! case ADDR_64B: ! case ADDR_PREFIX: ! address_length = 8; ! break; ! case ADDR_128B: ! address_length = 16; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address_1->type, ! (errorparameter_t)5); ! return FALSE; ! } ! if (memcmp((void*)address_1->addr_128b,(void*)address_2->addr_128b,address_length)==0) { ! return TRUE; ! } ! return FALSE; ! } ! ! //======= address read/write ! ! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian) { ! uint8_t i; ! uint8_t address_length; ! ! writeToAddress->type = type; ! switch (type) { ! case ADDR_16B: ! case ADDR_PANID: ! address_length = 2; ! break; ! case ADDR_64B: ! case ADDR_PREFIX: ! address_length = 8; ! break; ! case ADDR_128B: ! address_length = 16; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)type, ! (errorparameter_t)6); ! return; ! } ! ! for (i=0;iaddr_128b[address_length-1-i] = *(payload+i); ! } else { ! writeToAddress->addr_128b[i] = *(payload+i); ! } ! } ! } ! ! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian) { ! uint8_t i; ! uint8_t address_length; ! ! switch (address->type) { ! case ADDR_16B: ! case ADDR_PANID: ! address_length = 2; ! break; ! case ADDR_64B: ! case ADDR_PREFIX: ! address_length = 8; ! break; ! case ADDR_128B: ! address_length = 16; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)7); ! return; ! } ! ! for (i=0;ipayload -= sizeof(uint8_t); ! msg->length += sizeof(uint8_t); ! if (littleEndian) { ! *((uint8_t*)(msg->payload)) = address->addr_128b[i]; ! } else { ! *((uint8_t*)(msg->payload)) = address->addr_128b[address_length-1-i]; ! } ! } ! } ! ! //======= reserving/tossing headers ! ! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->payload -= header_length; ! pkt->length += header_length; ! if ( (uint8_t*)(pkt->payload) < (uint8_t*)(pkt->packet) ) { ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)0, ! (errorparameter_t)pkt->length); ! } ! } ! ! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->payload += header_length; ! pkt->length -= header_length; ! if ( (uint8_t*)(pkt->payload) > (uint8_t*)(pkt->packet+126) ) { ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)1, ! (errorparameter_t)pkt->length); ! } ! } ! ! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->length += header_length; ! if (pkt->length>127) { ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)2, ! (errorparameter_t)pkt->length); ! } ! } ! ! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->length -= header_length; ! if (pkt->length>128) {//wraps around, so a negative value will be >128 ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)3, ! (errorparameter_t)pkt->length); ! } ! } ! ! //======= CRC calculation ! ! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg) { ! uint16_t crc; ! uint8_t i; ! uint8_t count; ! crc = 0; ! for (count=1;countlength-2;count++) { ! crc = crc ^ (uint8_t)*(msg->payload+count); ! //crc = crc ^ (uint16_t)*ptr++ << 8; ! for (i=0;i<8;i++) { ! if (crc & 0x1) { ! crc = crc >> 1 ^ 0x8408; ! } else { ! crc = crc >> 1; ! } ! } ! } ! *(msg->payload+(msg->length-2)) = crc%256; ! *(msg->payload+(msg->length-1)) = crc/256; ! } ! ! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg) { ! uint16_t crc; ! uint8_t i; ! uint8_t count; ! crc = 0; ! for (count=0;countlength-2;count++) { ! crc = crc ^ (uint8_t)*(msg->payload+count); ! //crc = crc ^ (uint16_t)*ptr++ << 8; ! for (i=0;i<8;i++) { ! if (crc & 0x1) { ! crc = crc >> 1 ^ 0x8408; ! } else { ! crc = crc >> 1; ! } ! } ! } ! if (*(msg->payload+(msg->length-2))==crc%256 && ! *(msg->payload+(msg->length-1))==crc/256) { ! return TRUE; ! } else { ! return FALSE; ! } ! } ! ! //======= checksum calculation ! ! //see http://www-net.cs.umass.edu/kurose/transport/UDP.html, or http://tools.ietf.org/html/rfc1071 ! //see http://en.wikipedia.org/wiki/User_Datagram_Protocol#IPv6_PSEUDO-HEADER ! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr) { ! open_addr_t temp_dest_prefix; ! open_addr_t temp_dest_mac64b; ! uint8_t temp_checksum[2]; ! uint8_t little_helper[2]; ! //initialization ! temp_checksum[0] = 0; ! temp_checksum[1] = 0; ! *checksum_ptr = 0; ! *(checksum_ptr+1) = 0; ! //source/destination address ! packetfunctions_ip128bToMac64b(&(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b); ! if (packetfunctions_sameAddress(&temp_dest_prefix,idmanager_getMyID(ADDR_PREFIX))) { ! little_helper[0] = 0xfe; ! little_helper[1] = 0x80; ! //source address prefix ! onesComplementSum(temp_checksum,little_helper,2); ! //source address EUI ! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_64B))->addr_64b,8); ! //destination address prefix (fe:80) ! onesComplementSum(temp_checksum,little_helper,2); ! //destination address EUI ! onesComplementSum(temp_checksum,temp_dest_mac64b.addr_64b,8); ! } else { ! //source address prefix ! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_PREFIX))->prefix,8); ! //source address EUI ! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_64B))->addr_64b,8); ! //destination address ! onesComplementSum(temp_checksum,msg->l3_destinationAdd.addr_128b,16); ! } ! //length ! little_helper[0] = 0; ! little_helper[1] = msg->length; ! onesComplementSum(temp_checksum,little_helper,2); ! //next header ! little_helper[0] = 0; ! little_helper[1] = msg->l4_protocol; ! onesComplementSum(temp_checksum,little_helper,2); ! //ICMPv6 packet ! onesComplementSum(temp_checksum,msg->payload,msg->length); ! temp_checksum[0] ^= 0xFF; ! temp_checksum[1] ^= 0xFF; ! //write in packet ! *checksum_ptr = temp_checksum[0]; ! *(checksum_ptr+1) = temp_checksum[1]; ! } ! ! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length) { ! uint32_t sum = 0xFFFF & (global_sum[0]<<8 | global_sum[1]); ! while (length>1) { ! sum += 0xFFFF & (*ptr<<8 | *(ptr+1)); ! ptr += 2; ! length -= 2; ! } ! if (length) { ! sum += (0xFF & *ptr)<<8; ! } ! while (sum>>16) { ! sum = (sum & 0xFFFF)+(sum >> 16); ! } ! global_sum[0] = (sum>>8) & 0xFF; ! global_sum[1] = sum & 0xFF; ! } ! ! //======= endianness ! ! void packetfunctions_htons( uint16_t val, uint8_t* dest ) { ! dest[0] = (val & 0xff00) >> 8; ! dest[1] = (val & 0x00ff); ! } ! ! uint16_t packetfunctions_ntohs( uint8_t* src ) { ! return (((uint16_t) src[0]) << 8) | ! (((uint16_t) src[1]) ! ); ! } ! ! void packetfunctions_htonl( uint32_t val, uint8_t* dest ) { ! dest[0] = (val & 0xff000000) >> 24; ! dest[1] = (val & 0x00ff0000) >> 16; ! dest[2] = (val & 0x0000ff00) >> 8; ! dest[3] = (val & 0x000000ff); ! } ! ! uint32_t packetfunctions_ntohl( uint8_t* src ) { ! return (((uint32_t) src[0]) << 24) | ! (((uint32_t) src[1]) << 16) | ! (((uint32_t) src[2]) << 8) | ! (((uint32_t) src[3]) ! ); ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,444 ---- ! #include "packetfunctions.h" ! #include "openserial.h" ! #include "idmanager.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length); ! ! //=========================== public ========================================== ! ! //======= address translation ! ! //assuming an ip128b is a concatenation of prefix64b followed by a mac64b ! void packetfunctions_ip128bToMac64b( ! open_addr_t* ip128b, ! open_addr_t* prefix64btoWrite, ! open_addr_t* mac64btoWrite) { ! if (ip128b->type!=ADDR_128B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)ip128b->type, ! (errorparameter_t)0); ! mac64btoWrite->type=ADDR_NONE; ! return; ! } ! prefix64btoWrite->type=ADDR_PREFIX; ! memcpy(prefix64btoWrite->prefix, &(ip128b->addr_128b[0]), 8); ! mac64btoWrite->type=ADDR_64B; ! memcpy(mac64btoWrite->addr_64b , &(ip128b->addr_128b[8]), 8); ! } ! void packetfunctions_mac64bToIp128b( ! open_addr_t* prefix64b, ! open_addr_t* mac64b, ! open_addr_t* ip128bToWrite) { ! if (prefix64b->type!=ADDR_PREFIX || mac64b->type!=ADDR_64B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)prefix64b->type, ! (errorparameter_t)1); ! ip128bToWrite->type=ADDR_NONE; ! return; ! } ! ip128bToWrite->type=ADDR_128B; ! memcpy(&(ip128bToWrite->addr_128b[0]), &(prefix64b->prefix[0]), 8); ! memcpy(&(ip128bToWrite->addr_128b[8]), &(mac64b->addr_64b[0]), 8); ! } ! ! //assuming an mac16b is lower 2B of mac64b ! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite) { ! if (mac64b->type!=ADDR_64B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)mac64b->type, ! (errorparameter_t)2); ! mac16btoWrite->type=ADDR_NONE; ! return; ! } ! mac16btoWrite->type = ADDR_16B; ! mac16btoWrite->addr_16b[0] = mac64b->addr_64b[6]; ! mac16btoWrite->addr_16b[1] = mac64b->addr_64b[7]; ! } ! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite) { ! if (mac16b->type!=ADDR_16B) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)mac16b->type, ! (errorparameter_t)3); ! mac64btoWrite->type=ADDR_NONE; ! return; ! } ! mac64btoWrite->type = ADDR_64B; ! mac64btoWrite->addr_64b[0] = 0; ! mac64btoWrite->addr_64b[1] = 0; ! mac64btoWrite->addr_64b[2] = 0; ! mac64btoWrite->addr_64b[3] = 0; ! mac64btoWrite->addr_64b[4] = 0; ! mac64btoWrite->addr_64b[5] = 0; ! mac64btoWrite->addr_64b[6] = mac16b->addr_16b[0]; ! mac64btoWrite->addr_64b[7] = mac16b->addr_16b[1]; ! } ! ! //======= address recognition ! ! bool packetfunctions_isBroadcastMulticast(open_addr_t* address) { ! uint8_t i; ! uint8_t address_length; ! //IPv6 multicast ! if (address->type==ADDR_128B) { ! if (address->addr_128b[0]==0xff) { ! return TRUE; ! } else { ! return FALSE; ! } ! } ! //15.4 broadcast ! switch (address->type) { ! case ADDR_16B: ! address_length = 2; ! break; ! case ADDR_64B: ! address_length = 8; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)4); ! return FALSE; ! } ! for (i=0;iaddr_128b[i]!=0xFF) { ! return FALSE; ! } ! } ! return TRUE; ! } ! ! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address) { ! if ( ! address->type == ADDR_128B && ! address->addr_128b[0] == 0xff && ! address->addr_128b[1] == 0x02 && ! address->addr_128b[2] == 0x00 && ! address->addr_128b[3] == 0x00 && ! address->addr_128b[4] == 0x00 && ! address->addr_128b[5] == 0x00 && ! address->addr_128b[6] == 0x00 && ! address->addr_128b[7] == 0x00 && ! address->addr_128b[8] == 0x00 && ! address->addr_128b[9] == 0x00 && ! address->addr_128b[10] == 0x00 && ! address->addr_128b[11] == 0x00 && ! address->addr_128b[12] == 0x00 && ! address->addr_128b[13] == 0x00 && ! address->addr_128b[14] == 0x00 && ! address->addr_128b[15] == 0x02 ! ) { ! return TRUE; ! } ! return FALSE; ! } ! ! bool packetfunctions_isAllHostsMulticast(open_addr_t* address) { ! if ( ! address->type == ADDR_128B && ! address->addr_128b[0] == 0xff && ! address->addr_128b[1] == 0x02 && ! address->addr_128b[2] == 0x00 && ! address->addr_128b[3] == 0x00 && ! address->addr_128b[4] == 0x00 && ! address->addr_128b[5] == 0x00 && ! address->addr_128b[6] == 0x00 && ! address->addr_128b[7] == 0x00 && ! address->addr_128b[8] == 0x00 && ! address->addr_128b[9] == 0x00 && ! address->addr_128b[10] == 0x00 && ! address->addr_128b[11] == 0x00 && ! address->addr_128b[12] == 0x00 && ! address->addr_128b[13] == 0x00 && ! address->addr_128b[14] == 0x00 && ! address->addr_128b[15] == 0x01 ! ) { ! return TRUE; ! } ! return FALSE; ! } ! ! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2) { ! uint8_t address_length; ! ! if (address_1->type!=address_2->type) { ! return FALSE; ! } ! switch (address_1->type) { ! case ADDR_16B: ! case ADDR_PANID: ! address_length = 2; ! break; ! case ADDR_64B: ! case ADDR_PREFIX: ! address_length = 8; ! break; ! case ADDR_128B: ! case ADDR_ANYCAST: ! address_length = 16; ! break; ! ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address_1->type, ! (errorparameter_t)5); ! return FALSE; ! } ! if (memcmp((void*)address_1->addr_128b,(void*)address_2->addr_128b,address_length)==0) { ! return TRUE; ! } ! return FALSE; ! } ! ! //======= address read/write ! ! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian) { ! uint8_t i; ! uint8_t address_length; ! ! writeToAddress->type = type; ! switch (type) { ! case ADDR_16B: ! case ADDR_PANID: ! address_length = 2; ! break; ! case ADDR_64B: ! case ADDR_PREFIX: ! address_length = 8; ! break; ! case ADDR_128B: ! address_length = 16; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)type, ! (errorparameter_t)6); ! return; ! } ! ! for (i=0;iaddr_128b[address_length-1-i] = *(payload+i); ! } else { ! writeToAddress->addr_128b[i] = *(payload+i); ! } ! } ! } ! ! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian) { ! uint8_t i; ! uint8_t address_length; ! ! switch (address->type) { ! case ADDR_16B: ! case ADDR_PANID: ! address_length = 2; ! break; ! case ADDR_64B: ! case ADDR_PREFIX: ! address_length = 8; ! break; ! case ADDR_128B: ! address_length = 16; ! break; ! default: ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_WRONG_ADDR_TYPE, ! (errorparameter_t)address->type, ! (errorparameter_t)7); ! return; ! } ! ! for (i=0;ipayload -= sizeof(uint8_t); ! msg->length += sizeof(uint8_t); ! if (littleEndian) { ! *((uint8_t*)(msg->payload)) = address->addr_128b[i]; ! } else { ! *((uint8_t*)(msg->payload)) = address->addr_128b[address_length-1-i]; ! } ! } ! } ! ! //======= reserving/tossing headers ! ! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->payload -= header_length; ! pkt->length += header_length; ! if ( (uint8_t*)(pkt->payload) < (uint8_t*)(pkt->packet) ) { ! openserial_printCritical(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)0, ! (errorparameter_t)pkt->length); ! } ! } ! ! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->payload += header_length; ! pkt->length -= header_length; ! if ( (uint8_t*)(pkt->payload) > (uint8_t*)(pkt->packet+126) ) { ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)1, ! (errorparameter_t)pkt->length); ! } ! } ! ! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->length += header_length; ! if (pkt->length>127) { ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)2, ! (errorparameter_t)pkt->length); ! } ! } ! ! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length) { ! pkt->length -= header_length; ! if (pkt->length>128) {//wraps around, so a negative value will be >128 ! openserial_printError(COMPONENT_PACKETFUNCTIONS,ERR_HEADER_TOO_LONG, ! (errorparameter_t)3, ! (errorparameter_t)pkt->length); ! } ! } ! ! //======= CRC calculation ! ! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg) { ! uint16_t crc; ! uint8_t i; ! uint8_t count; ! crc = 0; ! for (count=1;countlength-2;count++) { ! crc = crc ^ (uint8_t)*(msg->payload+count); ! //crc = crc ^ (uint16_t)*ptr++ << 8; ! for (i=0;i<8;i++) { ! if (crc & 0x1) { ! crc = crc >> 1 ^ 0x8408; ! } else { ! crc = crc >> 1; ! } ! } ! } ! *(msg->payload+(msg->length-2)) = crc%256; ! *(msg->payload+(msg->length-1)) = crc/256; ! } ! ! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg) { ! uint16_t crc; ! uint8_t i; ! uint8_t count; ! crc = 0; ! for (count=0;countlength-2;count++) { ! crc = crc ^ (uint8_t)*(msg->payload+count); ! //crc = crc ^ (uint16_t)*ptr++ << 8; ! for (i=0;i<8;i++) { ! if (crc & 0x1) { ! crc = crc >> 1 ^ 0x8408; ! } else { ! crc = crc >> 1; ! } ! } ! } ! if (*(msg->payload+(msg->length-2))==crc%256 && ! *(msg->payload+(msg->length-1))==crc/256) { ! return TRUE; ! } else { ! return FALSE; ! } ! } ! ! //======= checksum calculation ! ! //see http://www-net.cs.umass.edu/kurose/transport/UDP.html, or http://tools.ietf.org/html/rfc1071 ! //see http://en.wikipedia.org/wiki/User_Datagram_Protocol#IPv6_PSEUDO-HEADER ! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr) { ! uint8_t temp_checksum[2]; ! uint8_t little_helper[2]; ! ! // initialize running checksum ! temp_checksum[0] = 0; ! temp_checksum[1] = 0; ! ! //===== IPv6 pseudo header ! ! // source address (prefix and EUI64) ! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_PREFIX))->prefix,8); ! onesComplementSum(temp_checksum,(idmanager_getMyID(ADDR_64B))->addr_64b,8); ! ! // destination address ! onesComplementSum(temp_checksum,msg->l3_destinationAdd.addr_128b,16); ! ! // length ! little_helper[0] = 0; ! little_helper[1] = msg->length; ! onesComplementSum(temp_checksum,little_helper,2); ! ! // next header ! little_helper[0] = 0; ! little_helper[1] = msg->l4_protocol; ! onesComplementSum(temp_checksum,little_helper,2); ! ! //===== payload ! ! // reset the checksum currently in the payload ! *checksum_ptr = 0; ! *(checksum_ptr+1) = 0; ! ! onesComplementSum(temp_checksum,msg->payload,msg->length); ! temp_checksum[0] ^= 0xFF; ! temp_checksum[1] ^= 0xFF; ! ! //write in packet ! *checksum_ptr = temp_checksum[0]; ! *(checksum_ptr+1) = temp_checksum[1]; ! } ! ! ! void onesComplementSum(uint8_t* global_sum, uint8_t* ptr, int length) { ! uint32_t sum = 0xFFFF & (global_sum[0]<<8 | global_sum[1]); ! while (length>1) { ! sum += 0xFFFF & (*ptr<<8 | *(ptr+1)); ! ptr += 2; ! length -= 2; ! } ! if (length) { ! sum += (0xFF & *ptr)<<8; ! } ! while (sum>>16) { ! sum = (sum & 0xFFFF)+(sum >> 16); ! } ! global_sum[0] = (sum>>8) & 0xFF; ! global_sum[1] = sum & 0xFF; ! } ! ! //======= endianness ! ! void packetfunctions_htons( uint16_t val, uint8_t* dest ) { ! dest[0] = (val & 0xff00) >> 8; ! dest[1] = (val & 0x00ff); ! } ! ! uint16_t packetfunctions_ntohs( uint8_t* src ) { ! return (((uint16_t) src[0]) << 8) | ! (((uint16_t) src[1]) ! ); ! } ! ! void packetfunctions_htonl( uint32_t val, uint8_t* dest ) { ! dest[0] = (val & 0xff000000) >> 24; ! dest[1] = (val & 0x00ff0000) >> 16; ! dest[2] = (val & 0x0000ff00) >> 8; ! dest[3] = (val & 0x000000ff); ! } ! ! uint32_t packetfunctions_ntohl( uint8_t* src ) { ! return (((uint32_t) src[0]) << 24) | ! (((uint32_t) src[1]) << 16) | ! (((uint32_t) src[2]) << 8) | ! (((uint32_t) src[3]) ! ); ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/cross-layers/packetfunctions.h ../../../sys/net/openwsn/cross-layers/packetfunctions.h *** openwsn/cross-layers/packetfunctions.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/cross-layers/packetfunctions.h Wed Jan 15 13:48:27 2014 *************** *** 1,61 **** ! #ifndef __PACKETFUNCTIONS_H ! #define __PACKETFUNCTIONS_H ! ! /** ! \addtogroup helpers ! \{ ! \addtogroup PacketFunctions ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // address translation ! void packetfunctions_ip128bToMac64b(open_addr_t* ip128b,open_addr_t* prefix64btoWrite,open_addr_t* mac64btoWrite); ! void packetfunctions_mac64bToIp128b(open_addr_t* prefix64b,open_addr_t* mac64b,open_addr_t* ip128bToWrite); ! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite); ! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite); ! ! // address recognition ! bool packetfunctions_isBroadcastMulticast(open_addr_t* address); ! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address); ! bool packetfunctions_isAllHostsMulticast(open_addr_t* address); ! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2); ! ! // read/write addresses to/from packets ! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian); ! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian); ! ! // reserving/tossing headers and footers ! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length); ! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length); ! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length); ! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length); ! ! // calculate CRC ! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg); ! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg); ! ! // calculate checksum ! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr); ! ! // endianness ! void packetfunctions_htons( uint16_t val, uint8_t* dest ); ! uint16_t packetfunctions_ntohs( uint8_t* src ); ! void packetfunctions_htonl( uint32_t val, uint8_t* dest ); ! uint32_t packetfunctions_ntohl( uint8_t* src ); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,61 ---- ! #ifndef __PACKETFUNCTIONS_H ! #define __PACKETFUNCTIONS_H ! ! /** ! \addtogroup cross-layers ! \{ ! \addtogroup PacketFunctions ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // address translation ! void packetfunctions_ip128bToMac64b(open_addr_t* ip128b,open_addr_t* prefix64btoWrite,open_addr_t* mac64btoWrite); ! void packetfunctions_mac64bToIp128b(open_addr_t* prefix64b,open_addr_t* mac64b,open_addr_t* ip128bToWrite); ! void packetfunctions_mac64bToMac16b(open_addr_t* mac64b, open_addr_t* mac16btoWrite); ! void packetfunctions_mac16bToMac64b(open_addr_t* mac16b, open_addr_t* mac64btoWrite); ! ! // address recognition ! bool packetfunctions_isBroadcastMulticast(open_addr_t* address); ! bool packetfunctions_isAllRoutersMulticast(open_addr_t* address); ! bool packetfunctions_isAllHostsMulticast(open_addr_t* address); ! bool packetfunctions_sameAddress(open_addr_t* address_1, open_addr_t* address_2); ! ! // read/write addresses to/from packets ! void packetfunctions_readAddress(uint8_t* payload, uint8_t type, open_addr_t* writeToAddress, bool littleEndian); ! void packetfunctions_writeAddress(OpenQueueEntry_t* msg, open_addr_t* address, bool littleEndian); ! ! // reserving/tossing headers and footers ! void packetfunctions_reserveHeaderSize(OpenQueueEntry_t* pkt, uint8_t header_length); ! void packetfunctions_tossHeader(OpenQueueEntry_t* pkt, uint8_t header_length); ! void packetfunctions_reserveFooterSize(OpenQueueEntry_t* pkt, uint8_t header_length); ! void packetfunctions_tossFooter(OpenQueueEntry_t* pkt, uint8_t header_length); ! ! // calculate CRC ! void packetfunctions_calculateCRC(OpenQueueEntry_t* msg); ! bool packetfunctions_checkCRC(OpenQueueEntry_t* msg); ! ! // calculate checksum ! void packetfunctions_calculateChecksum(OpenQueueEntry_t* msg, uint8_t* checksum_ptr); ! ! // endianness ! void packetfunctions_htons( uint16_t val, uint8_t* dest ); ! uint16_t packetfunctions_ntohs( uint8_t* src ); ! void packetfunctions_htonl( uint32_t val, uint8_t* dest ); ! uint32_t packetfunctions_ntohl( uint8_t* src ); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/debugpins.c ../../../sys/net/openwsn/debugpins.c *** openwsn/debugpins.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/debugpins.c Wed Jan 15 13:48:27 2014 *************** *** 1,93 **** ! /** ! \brief TelosB-specific definition of the "debugpins" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "debugpins.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void debugpins_init() { ! P6DIR |= 0x40; // frame [P6.6] ! P6DIR |= 0x80; // slot [P6.7] ! P2DIR |= 0x08; // fsm [P2.3] ! P2DIR |= 0x40; // task [P2.6] ! P6DIR |= 0x01; // isr [P6.0] ! P6DIR |= 0x02; // radio [P6.1] ! } ! ! // P6.6 ! void debugpins_frame_toggle() { ! P6OUT ^= 0x40; ! } ! void debugpins_frame_clr() { ! P6OUT &= ~0x40; ! } ! void debugpins_frame_set() { ! P6OUT |= 0x40; ! } ! ! // P6.7 ! void debugpins_slot_toggle() { ! P6OUT ^= 0x80; ! } ! void debugpins_slot_clr() { ! P6OUT &= ~0x80; ! } ! void debugpins_slot_set() { ! P6OUT |= 0x80; ! } ! ! // P2.3 ! void debugpins_fsm_toggle() { ! P2OUT ^= 0x08; ! } ! void debugpins_fsm_clr() { ! P2OUT &= ~0x08; ! } ! void debugpins_fsm_set() { ! P2OUT |= 0x08; ! } ! ! // P2.6 ! void debugpins_task_toggle() { ! P2OUT ^= 0x40; ! } ! void debugpins_task_clr() { ! P2OUT &= ~0x40; ! } ! void debugpins_task_set() { ! P2OUT |= 0x40; ! } ! ! // P6.0 ! void debugpins_isr_toggle() { ! P6OUT ^= 0x01; ! } ! void debugpins_isr_clr() { ! P6OUT &= ~0x01; ! } ! void debugpins_isr_set() { ! P6OUT |= 0x01; ! } ! ! // P6.1 ! void debugpins_radio_toggle() { ! P6OUT ^= 0x02; ! } ! void debugpins_radio_clr() { ! P6OUT &= ~0x02; ! } ! void debugpins_radio_set() { ! P6OUT |= 0x02; ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,110 ---- ! /** ! \brief TelosB-specific definition of the "debugpins" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! #include // needed for uin8_t, uint16_t ! #include "msp430f1611.h" ! #include "debugpins.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void debugpins_init(void) { ! P6DIR |= 0x40; // frame [P6.6] ! P6DIR |= 0x80; // slot [P6.7] ! P2DIR |= 0x08; // fsm [P2.3] ! P2DIR |= 0x40; // task [P2.6] ! P6DIR |= 0x01; // isr [P6.0] ! P6DIR |= 0x02; // radio [P6.1] ! } ! ! // P6.6 ! void debugpins_frame_toggle(void) { ! P6OUT ^= 0x40; ! } ! void debugpins_frame_clr(void) { ! P6OUT &= ~0x40; ! } ! void debugpins_frame_set(void) { ! P6OUT |= 0x40; ! } ! ! // P6.7 ! void debugpins_slot_toggle(void) { ! P6OUT ^= 0x80; ! } ! void debugpins_slot_clr(void) { ! P6OUT &= ~0x80; ! } ! void debugpins_slot_set(void) { ! P6OUT |= 0x80; ! } ! ! // P2.3 ! void debugpins_fsm_toggle(void) { ! P2OUT ^= 0x08; ! } ! void debugpins_fsm_clr(void) { ! P2OUT &= ~0x08; ! } ! void debugpins_fsm_set(void) { ! P2OUT |= 0x08; ! } ! ! // P2.6 ! void debugpins_task_toggle(void) { ! P2OUT ^= 0x40; ! } ! void debugpins_task_clr(void) { ! P2OUT &= ~0x40; ! } ! void debugpins_task_set(void) { ! P2OUT |= 0x40; ! } ! ! // P6.0 ! void debugpins_isr_toggle(void) { ! P6OUT ^= 0x01; ! } ! void debugpins_isr_clr(void) { ! P6OUT &= ~0x01; ! } ! void debugpins_isr_set(void) { ! P6OUT |= 0x01; ! } ! ! // P6.1 ! void debugpins_radio_toggle(void) { ! P6OUT ^= 0x02; ! } ! void debugpins_radio_clr(void) { ! P6OUT &= ~0x02; ! } ! void debugpins_radio_set(void) { ! P6OUT |= 0x02; ! } ! ! ! void leds_toggle_2x(void){ ! ! uint16_t i; ! debugpins_task_toggle(); ! for (i=0;i<0xFFFF;i++); ! for (i=0;i<0xFFFF;i++); ! debugpins_task_toggle(); ! } ! void leds_toggle_4x(void){ ! uint16_t i; ! leds_toggle_2x(); ! for (i=0;i<0xFFFF;i++); ! for (i=0;i<0xFFFF;i++); ! leds_toggle_2x(); ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/debugpins.h ../../../sys/net/openwsn/debugpins.h *** openwsn/debugpins.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/debugpins.h Wed Jan 15 13:48:27 2014 *************** *** 1,44 **** ! /** ! \brief Cross-platform declaration "leds" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __DEBUGPINS_H ! #define __DEBUGPINS_H ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void debugpins_init(); ! ! void debugpins_frame_toggle(); ! void debugpins_frame_clr(); ! void debugpins_frame_set(); ! ! void debugpins_slot_toggle(); ! void debugpins_slot_clr(); ! void debugpins_slot_set(); ! ! void debugpins_fsm_toggle(); ! void debugpins_fsm_clr(); ! void debugpins_fsm_set(); ! ! void debugpins_task_toggle(); ! void debugpins_task_clr(); ! void debugpins_task_set(); ! ! void debugpins_isr_toggle(); ! void debugpins_isr_clr(); ! void debugpins_isr_set(); ! ! void debugpins_radio_toggle(); ! void debugpins_radio_clr(); ! void debugpins_radio_set(); ! ! #endif --- 1,54 ---- ! #ifndef __DEBUGPINS_H ! #define __DEBUGPINS_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup debugpins ! \{ ! ! \brief Cross-platform declaration "leds" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void debugpins_init(void); ! ! void debugpins_frame_toggle(void); ! void debugpins_frame_clr(void); ! void debugpins_frame_set(void); ! ! void debugpins_slot_toggle(void); ! void debugpins_slot_clr(void); ! void debugpins_slot_set(void); ! ! void debugpins_fsm_toggle(void); ! void debugpins_fsm_clr(void); ! void debugpins_fsm_set(void); ! ! void debugpins_task_toggle(void); ! void debugpins_task_clr(void); ! void debugpins_task_set(void); ! ! void debugpins_isr_toggle(void); ! void debugpins_isr_clr(void); ! void debugpins_isr_set(void); ! ! void debugpins_radio_toggle(void); ! void debugpins_radio_clr(void); ! void debugpins_radio_set(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/eui64.c ../../../sys/net/openwsn/eui64.c *** openwsn/eui64.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/eui64.c Wed Jan 15 13:48:27 2014 *************** *** 1,218 **** ! /** ! \brief TelosB-specific definition of the "eui64" bsp module. ! ! \author Thomas Watteyne , March 2012. ! */ ! ! #include "msp430f1611.h" ! #include "string.h" ! #include "eui64.h" ! ! //=========================== defines ========================================= ! ! #define PIN_1WIRE 0x10 ! ! //=========================== enums =========================================== ! ! enum { ! OW_DLY_A = 6, ! OW_DLY_B = 64, ! OW_DLY_C = 60, ! OW_DLY_D = 10, ! OW_DLY_E = 9, ! OW_DLY_F = 55, ! OW_DLY_G = 0, ! OW_DLY_H = 480, ! OW_DLY_I = 90, ! OW_DLY_J = 220, ! }; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // 1Wire ! uint8_t ow_reset(); ! void ow_write_byte(uint8_t byte); ! uint8_t ow_read_byte(); ! void ow_write_bit(int is_one); ! uint8_t ow_read_bit(); ! void ow_write_bit_one(); ! void ow_write_bit_zero(); ! // CRC ! uint8_t crc8_byte(uint8_t crc, uint8_t byte); ! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len); ! // timer ! void delay_us(uint16_t delay); ! // pin ! void owpin_init(); ! void owpin_output_low(); ! void owpin_output_high(); ! void owpin_prepare_read(); ! uint8_t owpin_read(); ! ! //=========================== public ========================================== ! ! void eui64_get(uint8_t* addressToWrite) { // >= 6000us ! uint8_t id[8]; ! int retry; ! int crc; ! uint8_t* byte; ! uint16_t oldTactl; ! ! retry = 5; ! memset(addressToWrite,0,8); ! ! // store current value of TACTL ! oldTactl = TACTL; ! ! // start timer in continuous mode at 1MHz ! TACTL = TASSEL_2 | ID_2 | MC_2; ! ! owpin_init(); ! while (retry-- > 0) { ! crc = 0; ! ! if(ow_reset()) { ! ow_write_byte(0x33); //read rom ! for(byte=id+7; byte>=id; byte--) { ! crc = crc8_byte( crc, *byte=ow_read_byte() ); ! } ! if(crc==0) { ! // CRC valid ! *(addressToWrite+0) = 0x14; ! *(addressToWrite+1) = 0x15; ! *(addressToWrite+2) = 0x92; ! memcpy(addressToWrite+3,id+1,5); ! } ! } ! } ! ! // restore value of TACTL ! TACTL = oldTactl; ! } ! ! //=========================== private ========================================= ! ! //===== 1Wire ! ! // admin ! ! uint8_t ow_reset() { // >= 960us ! int present; ! owpin_output_low(); ! delay_us(OW_DLY_H); // t_RSTL ! owpin_prepare_read(); ! delay_us(OW_DLY_I); // t_MSP ! present = owpin_read(); ! delay_us(OW_DLY_J); // t_REC ! return (present==0); ! } ! ! // byte-level access ! ! void ow_write_byte(uint8_t byte) {// >= 560us ! uint8_t bit; ! for(bit=0x01;bit!=0;bit<<=1) { ! ow_write_bit(byte & bit); ! } ! } ! ! uint8_t ow_read_byte() { // >= 560us ! uint8_t byte = 0; ! uint8_t bit; ! for( bit=0x01; bit!=0; bit<<=1 ) { ! if(ow_read_bit()) { ! byte |= bit; ! } ! } ! return byte; ! } ! ! // bit-level access ! ! void ow_write_bit(int is_one) { // >= 70us ! if(is_one) { ! ow_write_bit_one(); ! } else { ! ow_write_bit_zero(); ! } ! } ! ! uint8_t ow_read_bit() { // >= 70us ! int bit; ! owpin_output_low(); ! delay_us(OW_DLY_A); // t_RL ! owpin_prepare_read(); ! delay_us(OW_DLY_E); // near-max t_MSR ! bit = owpin_read(); ! delay_us(OW_DLY_F); // t_REC ! return bit; ! } ! ! void ow_write_bit_one() { // >= 70us ! owpin_output_low(); ! delay_us(OW_DLY_A); // t_W1L ! owpin_output_high(); ! delay_us(OW_DLY_B); // t_SLOT - t_W1L ! } ! ! void ow_write_bit_zero() { // >= 70us ! owpin_output_low(); ! delay_us(OW_DLY_C); // t_W0L ! owpin_output_high(); ! delay_us(OW_DLY_D); // t_SLOT - t_W0L ! } ! ! //===== CRC ! ! uint8_t crc8_byte(uint8_t crc, uint8_t byte) { ! int i; ! crc ^= byte; ! for( i=0; i<8; i++ ) ! { ! if( crc & 1 ) ! crc = (crc >> 1) ^ 0x8c; ! else ! crc >>= 1; ! } ! return crc; ! } ! ! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len) { ! uint8_t* end = bytes+len; ! while( bytes != end ) ! crc = crc8_byte( crc, *bytes++ ); ! return crc; ! } ! ! //===== timer ! ! void delay_us(uint16_t delay) { ! uint16_t startTime; ! startTime = TAR; ! while (TAR, March 2012. ! */ ! ! #include "msp430f1611.h" ! #include "string.h" ! #include "eui64.h" ! ! //=========================== defines ========================================= ! ! #define PIN_1WIRE 0x10 ! ! //=========================== enums =========================================== ! ! enum { ! OW_DLY_A = 6, ! OW_DLY_B = 64, ! OW_DLY_C = 60, ! OW_DLY_D = 10, ! OW_DLY_E = 9, ! OW_DLY_F = 55, ! OW_DLY_G = 0, ! OW_DLY_H = 480, ! OW_DLY_I = 90, ! OW_DLY_J = 220, ! }; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // 1Wire ! uint8_t ow_reset(void); ! void ow_write_byte(uint8_t byte); ! uint8_t ow_read_byte(void); ! void ow_write_bit(int is_one); ! uint8_t ow_read_bit(void); ! void ow_write_bit_one(void); ! void ow_write_bit_zero(void); ! // CRC ! uint8_t crc8_byte(uint8_t crc, uint8_t byte); ! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len); ! // timer ! void delay_us(uint16_t delay); ! // pin ! void owpin_init(void); ! void owpin_output_low(void); ! void owpin_output_high(void); ! void owpin_prepare_read(void); ! uint8_t owpin_read(void); ! ! //=========================== public ========================================== ! ! void eui64_get(uint8_t* addressToWrite) { // >= 6000us ! uint8_t id[8]; ! int retry; ! int crc; ! uint8_t* byte; ! uint16_t oldTactl; ! ! retry = 5; ! memset(addressToWrite,0,8); ! ! // store current value of TACTL ! oldTactl = TACTL; ! ! // start timer in continuous mode at 1MHz ! TACTL = TASSEL_2 | ID_2 | MC_2; ! ! owpin_init(); ! while (retry-- > 0) { ! crc = 0; ! ! if(ow_reset()) { ! ow_write_byte(0x33); //read rom ! for(byte=id+7; byte>=id; byte--) { ! crc = crc8_byte( crc, *byte=ow_read_byte() ); ! } ! if(crc==0) { ! // CRC valid ! *(addressToWrite+0) = 0x14; ! *(addressToWrite+1) = 0x15; ! *(addressToWrite+2) = 0x92; ! memcpy(addressToWrite+3,id+1,5); ! } ! } ! } ! ! // restore value of TACTL ! TACTL = oldTactl; ! } ! ! //=========================== private ========================================= ! ! //===== 1Wire ! ! // admin ! ! uint8_t ow_reset(void) { // >= 960us ! int present; ! owpin_output_low(); ! delay_us(OW_DLY_H); // t_RSTL ! owpin_prepare_read(); ! delay_us(OW_DLY_I); // t_MSP ! present = owpin_read(); ! delay_us(OW_DLY_J); // t_REC ! return (present==0); ! } ! ! // byte-level access ! ! void ow_write_byte(uint8_t byte) {// >= 560us ! uint8_t bit; ! for(bit=0x01;bit!=0;bit<<=1) { ! ow_write_bit(byte & bit); ! } ! } ! ! uint8_t ow_read_byte(void) { // >= 560us ! uint8_t byte = 0; ! uint8_t bit; ! for( bit=0x01; bit!=0; bit<<=1 ) { ! if(ow_read_bit()) { ! byte |= bit; ! } ! } ! return byte; ! } ! ! // bit-level access ! ! void ow_write_bit(int is_one) { // >= 70us ! if(is_one) { ! ow_write_bit_one(); ! } else { ! ow_write_bit_zero(); ! } ! } ! ! uint8_t ow_read_bit(void) { // >= 70us ! int bit; ! owpin_output_low(); ! delay_us(OW_DLY_A); // t_RL ! owpin_prepare_read(); ! delay_us(OW_DLY_E); // near-max t_MSR ! bit = owpin_read(); ! delay_us(OW_DLY_F); // t_REC ! return bit; ! } ! ! void ow_write_bit_one(void) { // >= 70us ! owpin_output_low(); ! delay_us(OW_DLY_A); // t_W1L ! owpin_output_high(); ! delay_us(OW_DLY_B); // t_SLOT - t_W1L ! } ! ! void ow_write_bit_zero(void) { // >= 70us ! owpin_output_low(); ! delay_us(OW_DLY_C); // t_W0L ! owpin_output_high(); ! delay_us(OW_DLY_D); // t_SLOT - t_W0L ! } ! ! //===== CRC ! ! uint8_t crc8_byte(uint8_t crc, uint8_t byte) { ! int i; ! crc ^= byte; ! for( i=0; i<8; i++ ) ! { ! if( crc & 1 ) ! crc = (crc >> 1) ^ 0x8c; ! else ! crc >>= 1; ! } ! return crc; ! } ! ! uint8_t crc8_bytes(uint8_t crc, uint8_t* bytes, uint8_t len) { ! uint8_t* end = bytes+len; ! while( bytes != end ) ! crc = crc8_byte( crc, *bytes++ ); ! return crc; ! } ! ! //===== timer ! ! void delay_us(uint16_t delay) { ! uint16_t startTime; ! startTime = TAR; ! while (TAR, March 2012. ! */ ! ! #ifndef __EUI64_H ! #define __EUI64_H ! ! #include ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void eui64_get(uint8_t* addressToWrite); ! #endif \ No newline at end of file --- 1,32 ---- ! #ifndef __EUI64_H ! #define __EUI64_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup eui64 ! \{ ! ! \brief Cross-platform declaration "eui64" bsp module. ! ! \author Thomas Watteyne , March 2012. ! */ ! ! #include ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void eui64_get(uint8_t* addressToWrite); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/leds.c ../../../sys/net/openwsn/leds.c *** openwsn/leds.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/leds.c Wed Jan 15 13:48:27 2014 *************** *** 1,137 **** ! /** ! \brief TelosB-specific definition of the "leds" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "leds.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void leds_init() { ! P5DIR |= 0x70; // P5DIR = 0bx111xxxx for LEDs ! P5OUT |= 0x70; // P2OUT = 0bx111xxxx, all LEDs off ! } ! ! // red = LED1 = P5.4 ! void leds_error_on() { ! P5OUT &= ~0x10; ! } ! void leds_error_off() { ! P5OUT |= 0x10; ! } ! void leds_error_toggle() { ! P5OUT ^= 0x10; ! } ! uint8_t leds_error_isOn() { ! return (uint8_t)(P5OUT & 0x10)>>4; ! } ! void leds_error_blink() { ! uint8_t i; ! volatile uint16_t delay; ! // turn all LEDs off ! P5OUT |= 0x70; ! ! // blink error LED for ~10s ! for (i=0;i<80;i++) { ! P5OUT ^= 0x10; ! for (delay=0xffff;delay>0;delay--); ! } ! } ! ! // green = LED2 = P5.5 ! void leds_radio_on() { ! P5OUT &= ~0x20; ! } ! void leds_radio_off() { ! P5OUT |= 0x20; ! } ! void leds_radio_toggle() { ! P5OUT ^= 0x20; ! } ! uint8_t leds_radio_isOn() { ! return (uint8_t)(P5OUT & 0x20)>>5; ! } ! ! // blue = LED3 = P5.6 ! void leds_sync_on() { ! P5OUT &= ~0x40; ! } ! void leds_sync_off() { ! P5OUT |= 0x40; ! } ! void leds_sync_toggle() { ! P5OUT ^= 0x40; ! } ! uint8_t leds_sync_isOn() { ! return (uint8_t)(P5OUT & 0x40)>>6; ! } ! ! void leds_debug_on() { ! // TelosB doesn't have a debug LED :( ! } ! void leds_debug_off() { ! // TelosB doesn't have a debug LED :( ! } ! void leds_debug_toggle() { ! // TelosB doesn't have a debug LED :( ! } ! uint8_t leds_debug_isOn() { ! // TelosB doesn't have a debug LED :( ! return 0; ! } ! ! void leds_all_on() { ! P5OUT &= ~0x70; ! } ! void leds_all_off() { ! P5OUT |= 0x70; ! } ! void leds_all_toggle() { ! P5OUT ^= 0x70; ! } ! ! void leds_circular_shift() { ! uint8_t leds_on; ! // get LED state ! leds_on = (~P5OUT & 0x70) >> 4; ! // modify LED state ! if (leds_on==0) { // if no LEDs on, switch on one ! leds_on = 0x01; ! } else { ! leds_on <<= 1; // shift by one position ! if ((leds_on & 0x08)!=0) { ! leds_on &= ~0x08; ! leds_on |= 0x01; // handle overflow ! } ! } ! // apply updated LED state ! leds_on <<= 4; // send back to position 4 ! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on ! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on ! } ! ! void leds_increment() { ! uint8_t leds_on; ! // get LED state ! leds_on = (~P5OUT & 0x70) >> 4; ! // modify LED state ! if (leds_on==0) { // if no LEDs on, switch on one ! leds_on = 0x01; ! } else { ! leds_on += 1; ! } ! // apply updated LED state ! leds_on <<= 4; // send back to position 4 ! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on ! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on ! } ! //=========================== private ========================================= \ No newline at end of file --- 1,137 ---- ! /** ! \brief TelosB-specific definition of the "leds" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "leds.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void leds_init(void) { ! P5DIR |= 0x70; // P5DIR = 0bx111xxxx for LEDs ! P5OUT |= 0x70; // P2OUT = 0bx111xxxx, all LEDs off ! } ! ! // red = LED1 = P5.4 ! void leds_error_on(void) { ! P5OUT &= ~0x10; ! } ! void leds_error_off(void) { ! P5OUT |= 0x10; ! } ! void leds_error_toggle(void) { ! P5OUT ^= 0x10; ! } ! uint8_t leds_error_isOn(void) { ! return (uint8_t)(P5OUT & 0x10)>>4; ! } ! void leds_error_blink(void) { ! uint8_t i; ! volatile uint16_t delay; ! // turn all LEDs off ! P5OUT |= 0x70; ! ! // blink error LED for ~10s ! for (i=0;i<80;i++) { ! P5OUT ^= 0x10; ! for (delay=0xffff;delay>0;delay--); ! } ! } ! ! // green = LED2 = P5.5 ! void leds_radio_on(void) { ! P5OUT &= ~0x20; ! } ! void leds_radio_off(void) { ! P5OUT |= 0x20; ! } ! void leds_radio_toggle(void) { ! P5OUT ^= 0x20; ! } ! uint8_t leds_radio_isOn(void) { ! return (uint8_t)(P5OUT & 0x20)>>5; ! } ! ! // blue = LED3 = P5.6 ! void leds_sync_on(void) { ! P5OUT &= ~0x40; ! } ! void leds_sync_off(void) { ! P5OUT |= 0x40; ! } ! void leds_sync_toggle(void) { ! P5OUT ^= 0x40; ! } ! uint8_t leds_sync_isOn(void) { ! return (uint8_t)(P5OUT & 0x40)>>6; ! } ! ! void leds_debug_on(void) { ! // TelosB doesn't have a debug LED :( ! } ! void leds_debug_off(void) { ! // TelosB doesn't have a debug LED :( ! } ! void leds_debug_toggle(void) { ! // TelosB doesn't have a debug LED :( ! } ! uint8_t leds_debug_isOn(void) { ! // TelosB doesn't have a debug LED :( ! return 0; ! } ! ! void leds_all_on(void) { ! P5OUT &= ~0x70; ! } ! void leds_all_off(void) { ! P5OUT |= 0x70; ! } ! void leds_all_toggle(void) { ! P5OUT ^= 0x70; ! } ! ! void leds_circular_shift(void) { ! uint8_t leds_on; ! // get LED state ! leds_on = (~P5OUT & 0x70) >> 4; ! // modify LED state ! if (leds_on==0) { // if no LEDs on, switch on one ! leds_on = 0x01; ! } else { ! leds_on <<= 1; // shift by one position ! if ((leds_on & 0x08)!=0) { ! leds_on &= ~0x08; ! leds_on |= 0x01; // handle overflow ! } ! } ! // apply updated LED state ! leds_on <<= 4; // send back to position 4 ! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on ! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on ! } ! ! void leds_increment(void) { ! uint8_t leds_on; ! // get LED state ! leds_on = (~P5OUT & 0x70) >> 4; ! // modify LED state ! if (leds_on==0) { // if no LEDs on, switch on one ! leds_on = 0x01; ! } else { ! leds_on += 1; ! } ! // apply updated LED state ! leds_on <<= 4; // send back to position 4 ! P5OUT |= (~leds_on & 0x70); // switch on the leds marked '1' in leds_on ! P5OUT &= ~( leds_on & 0x70); // switch off the leds marked '0' in leds_on ! } ! //=========================== private ========================================= \ No newline at end of file diff -crB openwsn/leds.h ../../../sys/net/openwsn/leds.h *** openwsn/leds.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/leds.h Wed Jan 15 13:48:27 2014 *************** *** 1,50 **** ! /** ! \brief Cross-platform declaration "leds" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __LEDS_H ! #define __LEDS_H ! ! #include "stdint.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void leds_init(); ! ! void leds_error_on(); ! void leds_error_off(); ! void leds_error_toggle(); ! uint8_t leds_error_isOn(); ! void leds_error_blink(); ! ! void leds_radio_on(); ! void leds_radio_off(); ! void leds_radio_toggle(); ! uint8_t leds_radio_isOn(); ! ! void leds_sync_on(); ! void leds_sync_off(); ! void leds_sync_toggle(); ! uint8_t leds_sync_isOn(); ! ! void leds_debug_on(); ! void leds_debug_off(); ! void leds_debug_toggle(); ! uint8_t leds_debug_isOn(); ! ! void leds_all_on(); ! void leds_all_off(); ! void leds_all_toggle(); ! ! void leds_circular_shift(); ! void leds_increment(); ! ! #endif --- 1,60 ---- ! #ifndef __LEDS_H ! #define __LEDS_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup leds ! \{ ! ! \brief Cross-platform declaration "leds" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "stdint.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void leds_init(void); ! ! void leds_error_on(void); ! void leds_error_off(void); ! void leds_error_toggle(void); ! uint8_t leds_error_isOn(void); ! void leds_error_blink(void); ! ! void leds_radio_on(void); ! void leds_radio_off(void); ! void leds_radio_toggle(void); ! uint8_t leds_radio_isOn(void); ! ! void leds_sync_on(void); ! void leds_sync_off(void); ! void leds_sync_toggle(void); ! uint8_t leds_sync_isOn(void); ! ! void leds_debug_on(void); ! void leds_debug_off(void); ! void leds_debug_toggle(void); ! uint8_t leds_debug_isOn(void); ! ! void leds_all_on(void); ! void leds_all_off(void); ! void leds_all_toggle(void); ! ! void leds_circular_shift(void); ! void leds_increment(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/openhdlc.c ../../../sys/net/openwsn/openhdlc.c *** openwsn/openhdlc.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/openhdlc.c Wed Jan 15 13:48:27 2014 *************** *** 1,20 **** ! /** ! \brief Definition of the "openserial" driver. ! ! \author Min Ting , October 2012. ! \author Fabien Chraim , October 2012. ! */ ! ! #include "openhdlc.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! uint16_t crcIteration(uint16_t crc, uint8_t byte) { ! return (crc >> 8) ^ fcstab[(crc ^ byte) & 0xff]; ! } ! ! //=========================== private ========================================= --- 1,20 ---- ! /** ! \brief Definition of the "openserial" driver. ! ! \author Min Ting , October 2012. ! \author Fabien Chraim , October 2012. ! */ ! ! #include "openhdlc.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! uint16_t crcIteration(uint16_t crc, uint8_t byte) { ! return (crc >> 8) ^ fcstab[(crc ^ byte) & 0xff]; ! } ! ! //=========================== private ========================================= diff -crB openwsn/openhdlc.h ../../../sys/net/openwsn/openhdlc.h *** openwsn/openhdlc.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/openhdlc.h Wed Jan 15 13:48:27 2014 *************** *** 1,75 **** ! /** ! \brief Declaraion of the "openserial" driver. ! ! \author Min Ting , October 2012. ! \author Fabien Chraim , October 2012. ! */ ! ! #ifndef __OPENHDLC_H ! #define __OPENHDLC_H ! ! #include "openwsn.h" ! ! /** ! \addtogroup cross-layers ! \{ ! \addtogroup HDLC ! \{ ! */ ! ! //=========================== define ========================================== ! ! #define HDLC_FLAG 0x7e ! #define HDLC_ESCAPE 0x7d ! #define HDLC_ESCAPE_MASK 0x20 ! #define HDLC_CRCINIT 0xffff ! #define HDLC_CRCGOOD 0xf0b8 ! ! //this table is used to expedite execution (at the expense of memory usage) ! static const uint16_t fcstab[256] = { ! 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, ! 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, ! 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, ! 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, ! 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, ! 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, ! 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, ! 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, ! 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, ! 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, ! 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, ! 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, ! 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, ! 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, ! 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, ! 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, ! 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, ! 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, ! 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, ! 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, ! 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, ! 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, ! 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, ! 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, ! 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, ! 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, ! 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, ! 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, ! 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, ! 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, ! 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, ! 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 ! }; ! ! //=========================== typedef ========================================= ! ! //=========================== prototypes ====================================== ! ! uint16_t crcIteration(uint16_t crc, uint8_t byte); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,75 ---- ! /** ! \brief Declaraion of the "openserial" driver. ! ! \author Min Ting , October 2012. ! \author Fabien Chraim , October 2012. ! */ ! ! #ifndef __OPENHDLC_H ! #define __OPENHDLC_H ! ! #include "openwsn.h" ! ! /** ! \addtogroup drivers ! \{ ! \addtogroup HDLC ! \{ ! */ ! ! //=========================== define ========================================== ! ! #define HDLC_FLAG 0x7e ! #define HDLC_ESCAPE 0x7d ! #define HDLC_ESCAPE_MASK 0x20 ! #define HDLC_CRCINIT 0xffff ! #define HDLC_CRCGOOD 0xf0b8 ! ! //this table is used to expedite execution (at the expense of memory usage) ! static const uint16_t fcstab[256] = { ! 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, ! 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, ! 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, ! 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, ! 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, ! 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, ! 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, ! 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, ! 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, ! 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, ! 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, ! 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, ! 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, ! 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, ! 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, ! 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, ! 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, ! 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, ! 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, ! 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, ! 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, ! 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, ! 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, ! 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, ! 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, ! 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, ! 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, ! 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, ! 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, ! 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, ! 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, ! 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 ! }; ! ! //=========================== typedef ========================================= ! ! //=========================== prototypes ====================================== ! ! uint16_t crcIteration(uint16_t crc, uint8_t byte); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/openserial.c ../../../sys/net/openwsn/openserial.c *** openwsn/openserial.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/openserial.c Wed Jan 15 13:48:27 2014 *************** *** 1,633 **** ! /** ! \brief Definition of the "openserial" driver. ! ! \author Fabien Chraim , March 2012. ! */ ! ! #include "openwsn.h" ! #include "openserial.h" ! #include "IEEE802154E.h" ! #include "neighbors.h" ! #include "res.h" ! #include "icmpv6echo.h" ! #include "idmanager.h" ! #include "openqueue.h" ! #include "tcpinject.h" ! #include "udpinject.h" ! #include "openbridge.h" ! #include "leds.h" ! #include "schedule.h" ! #include "uart.h" ! #include "opentimers.h" ! #include "openhdlc.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! // admin ! uint8_t mode; ! uint8_t debugPrintCounter; ! // input ! uint8_t reqFrame[1+1+2+1]; // flag (1B), command (2B), CRC (2B), flag (1B) ! uint8_t reqFrameIdx; ! uint8_t lastRxByte; ! bool busyReceiving; ! bool inputEscaping; ! uint16_t inputCrc; ! uint8_t inputBufFill; ! uint8_t inputBuf[SERIAL_INPUT_BUFFER_SIZE]; ! // output ! bool outputBufFilled; ! uint16_t outputCrc; ! uint8_t outputBufIdxW; ! uint8_t outputBufIdxR; ! uint8_t outputBuf[SERIAL_OUTPUT_BUFFER_SIZE]; ! } openserial_vars_t; ! ! openserial_vars_t openserial_vars; ! ! //=========================== prototypes ====================================== ! ! error_t openserial_printInfoErrorCritical( ! char severity, ! uint8_t calling_component, ! uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2 ! ); ! // HDLC output ! void outputHdlcOpen(); ! void outputHdlcWrite(uint8_t b); ! void outputHdlcClose(); ! // HDLC input ! void inputHdlcOpen(); ! void inputHdlcWrite(uint8_t b); ! void inputHdlcClose(); ! ! //=========================== public ========================================== ! ! void openserial_init() { ! uint16_t crc; ! ! // reset variable ! memset(&openserial_vars,0,sizeof(openserial_vars_t)); ! ! // admin ! openserial_vars.mode = MODE_OFF; ! openserial_vars.debugPrintCounter = 0; ! ! // input ! openserial_vars.reqFrame[0] = HDLC_FLAG; ! openserial_vars.reqFrame[1] = SERFRAME_MOTE2PC_REQUEST; ! crc = HDLC_CRCINIT; ! crc = crcIteration(crc,openserial_vars.reqFrame[1]); ! crc = ~crc; ! openserial_vars.reqFrame[2] = (crc>>0)&0xff; ! openserial_vars.reqFrame[3] = (crc>>8)&0xff; ! openserial_vars.reqFrame[4] = HDLC_FLAG; ! openserial_vars.reqFrameIdx = 0; ! openserial_vars.lastRxByte = HDLC_FLAG; ! openserial_vars.busyReceiving = FALSE; ! openserial_vars.inputEscaping = FALSE; ! openserial_vars.inputBufFill = 0; ! ! // ouput ! openserial_vars.outputBufFilled = FALSE; ! openserial_vars.outputBufIdxR = 0; ! openserial_vars.outputBufIdxW = 0; ! ! // set callbacks ! uart_setCallbacks(isr_openserial_tx, ! isr_openserial_rx); ! } ! ! error_t openserial_printStatus(uint8_t statusElement,uint8_t* buffer, uint16_t length) { ! uint8_t i; ! INTERRUPT_DECLARATION(); ! ! DISABLE_INTERRUPTS(); ! openserial_vars.outputBufFilled = TRUE; ! outputHdlcOpen(); ! outputHdlcWrite(SERFRAME_MOTE2PC_STATUS); ! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); ! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); ! outputHdlcWrite(statusElement); ! for (i=0;iaddr_16b[0]); ! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); ! outputHdlcWrite(calling_component); ! outputHdlcWrite(error_code); ! outputHdlcWrite((uint8_t)((arg1 & 0xff00)>>8)); ! outputHdlcWrite((uint8_t) (arg1 & 0x00ff)); ! outputHdlcWrite((uint8_t)((arg2 & 0xff00)>>8)); ! outputHdlcWrite((uint8_t) (arg2 & 0x00ff)); ! outputHdlcClose(); ! ENABLE_INTERRUPTS(); ! ! return E_SUCCESS; ! } ! ! error_t openserial_printData(uint8_t* buffer, uint8_t length) { ! uint8_t i; ! uint8_t asn[5]; ! INTERRUPT_DECLARATION(); ! ! // retrieve ASN ! asnWriteToSerial(asn);// byte01,byte23,byte4 ! ! DISABLE_INTERRUPTS(); ! openserial_vars.outputBufFilled = TRUE; ! outputHdlcOpen(); ! outputHdlcWrite(SERFRAME_MOTE2PC_DATA); ! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); ! outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); ! outputHdlcWrite(asn[0]); ! outputHdlcWrite(asn[1]); ! outputHdlcWrite(asn[2]); ! outputHdlcWrite(asn[3]); ! outputHdlcWrite(asn[4]); ! for (i=0;i0) { ! openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUTBUFFER_LENGTH, ! (errorparameter_t)openserial_vars.inputBufFill, ! (errorparameter_t)0); ! openserial_vars.inputBufFill = 0; ! } ! ! uart_clearTxInterrupts(); ! uart_clearRxInterrupts(); // clear possible pending interrupts ! uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt ! ! DISABLE_INTERRUPTS(); ! openserial_vars.mode = MODE_INPUT; ! openserial_vars.reqFrameIdx = 0; ! uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]); ! ENABLE_INTERRUPTS(); ! } ! ! void openserial_startOutput() { ! //schedule a task to get new status in the output buffer ! uint8_t debugPrintCounter; ! ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! openserial_vars.debugPrintCounter = (openserial_vars.debugPrintCounter+1)%STATUS_MAX; ! debugPrintCounter = openserial_vars.debugPrintCounter; ! ENABLE_INTERRUPTS(); ! ! // print debug information ! switch (debugPrintCounter) { ! case STATUS_ISSYNC: ! if (debugPrint_isSync()==TRUE) { ! break; ! } ! case STATUS_ID: ! if (debugPrint_id()==TRUE) { ! break; ! } ! case STATUS_DAGRANK: ! if (debugPrint_myDAGrank()==TRUE) { ! break; ! } ! case STATUS_OUTBUFFERINDEXES: ! if (debugPrint_outBufferIndexes()==TRUE) { ! break; ! } ! case STATUS_ASN: ! if (debugPrint_asn()==TRUE) { ! break; ! } ! case STATUS_MACSTATS: ! if (debugPrint_macStats()==TRUE) { ! break; ! } ! case STATUS_SCHEDULE: ! if(debugPrint_schedule()==TRUE) { ! break; ! } ! case STATUS_BACKOFF: ! if(debugPrint_backoff()==TRUE) { ! break; ! } ! case STATUS_QUEUE: ! if(debugPrint_queue()==TRUE) { ! break; ! } ! case STATUS_NEIGHBORS: ! if (debugPrint_neighbors()==TRUE) { ! break; ! } ! default: ! DISABLE_INTERRUPTS(); ! openserial_vars.debugPrintCounter=0; ! ENABLE_INTERRUPTS(); ! } ! ! // flush buffer ! uart_clearTxInterrupts(); ! uart_clearRxInterrupts(); // clear possible pending interrupts ! uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt ! DISABLE_INTERRUPTS(); ! openserial_vars.mode=MODE_OUTPUT; ! if (openserial_vars.outputBufFilled) { ! uart_writeByte(openserial_vars.outputBuf[openserial_vars.outputBufIdxR++]); ! } else { ! openserial_stop(); ! } ! ENABLE_INTERRUPTS(); ! } ! ! void openserial_stop() { ! uint8_t inputBufFill; ! uint8_t cmdByte; ! INTERRUPT_DECLARATION(); ! ! DISABLE_INTERRUPTS(); ! inputBufFill = openserial_vars.inputBufFill; ! ENABLE_INTERRUPTS(); ! ! // disable USCI_A1 TX & RX interrupt ! uart_disableInterrupts(); ! ! DISABLE_INTERRUPTS(); ! openserial_vars.mode=MODE_OFF; ! ENABLE_INTERRUPTS(); ! ! if (inputBufFill>0) { ! DISABLE_INTERRUPTS(); ! cmdByte = openserial_vars.inputBuf[0]; ! ENABLE_INTERRUPTS(); ! switch (cmdByte) { ! case SERFRAME_PC2MOTE_SETROOT: ! idmanager_triggerAboutRoot(); ! break; ! case SERFRAME_PC2MOTE_SETBRIDGE: ! idmanager_triggerAboutBridge(); ! break; ! case SERFRAME_PC2MOTE_DATA: ! openbridge_triggerData(); ! break; ! case SERFRAME_PC2MOTE_TRIGGERTCPINJECT: ! tcpinject_trigger(); ! break; ! case SERFRAME_PC2MOTE_TRIGGERUDPINJECT: ! udpinject_trigger(); ! break; ! case SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO: ! icmpv6echo_trigger(); ! break; ! case SERFRAME_PC2MOTE_TRIGGERSERIALECHO: ! openserial_echo(&openserial_vars.inputBuf[1],inputBufFill-1); ! break; ! default: ! openserial_printError(COMPONENT_OPENSERIAL,ERR_UNSUPPORTED_COMMAND, ! (errorparameter_t)cmdByte, ! (errorparameter_t)0); ! DISABLE_INTERRUPTS(); ! openserial_vars.inputBufFill = 0; ! ENABLE_INTERRUPTS(); ! break; ! } ! DISABLE_INTERRUPTS(); ! openserial_vars.inputBufFill = 0; ! ENABLE_INTERRUPTS(); ! } ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_outBufferIndexes() { ! uint16_t temp_buffer[2]; ! INTERRUPT_DECLARATION(); ! DISABLE_INTERRUPTS(); ! temp_buffer[0] = openserial_vars.outputBufIdxW; ! temp_buffer[1] = openserial_vars.outputBufIdxR; ! ENABLE_INTERRUPTS(); ! openserial_printStatus(STATUS_OUTBUFFERINDEXES,(uint8_t*)temp_buffer,sizeof(temp_buffer)); ! return TRUE; ! } ! ! //=========================== private ========================================= ! ! //===== hdlc (output) ! ! /** ! \brief Start an HDLC frame in the output buffer. ! */ ! inline void outputHdlcOpen() { ! // initialize the value of the CRC ! openserial_vars.outputCrc = HDLC_CRCINIT; ! ! // write the opening HDLC flag ! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; ! } ! /** ! \brief Add a byte to the outgoing HDLC frame being built. ! ! \todo escape 0x7e and 0x7d. ! */ ! inline void outputHdlcWrite(uint8_t b) { ! ! // iterate through CRC calculator ! openserial_vars.outputCrc = crcIteration(openserial_vars.outputCrc,b); ! ! // add byte to buffer ! if (b==HDLC_FLAG || b==HDLC_ESCAPE) { ! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_ESCAPE; ! b = b^HDLC_ESCAPE_MASK; ! } ! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = b; ! ! } ! /** ! \brief Finalize the outgoing HDLC frame. ! */ ! inline void outputHdlcClose() { ! // finalize the calculation of the CRC ! openserial_vars.outputCrc = ~openserial_vars.outputCrc; ! ! // write the CRC value ! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = (openserial_vars.outputCrc>>0)&0xff; ! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = (openserial_vars.outputCrc>>8)&0xff; ! ! // write the closing HDLC flag ! openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; ! } ! ! //===== hdlc (input) ! ! /** ! \brief Start an HDLC frame in the input buffer. ! */ ! inline void inputHdlcOpen() { ! // reset the input buffer index ! openserial_vars.inputBufFill = 0; ! ! // initialize the value of the CRC ! openserial_vars.inputCrc = HDLC_CRCINIT; ! } ! /** ! \brief Add a byte to the incoming HDLC frame. ! ! \todo escape 0x7e and 0x7d. ! */ ! inline void inputHdlcWrite(uint8_t b) { ! if (b==HDLC_ESCAPE) { ! openserial_vars.inputEscaping = TRUE; ! } else { ! if (openserial_vars.inputEscaping==TRUE) { ! b = b^HDLC_ESCAPE_MASK; ! openserial_vars.inputEscaping = FALSE; ! } ! ! // add byte to input buffer ! openserial_vars.inputBuf[openserial_vars.inputBufFill] = b; ! openserial_vars.inputBufFill++; ! ! // iterate through CRC calculator ! openserial_vars.inputCrc = crcIteration(openserial_vars.inputCrc,b); ! } ! } ! /** ! \brief Finalize the incoming HDLC frame. ! */ ! inline void inputHdlcClose() { ! ! // verify the validity of the frame ! if (openserial_vars.inputCrc==HDLC_CRCGOOD) { ! // the CRC is correct ! ! // remove the CRC from the input buffer ! openserial_vars.inputBufFill -= 2; ! } else { ! // the CRC is incorrect ! ! // drop the incoming fram ! openserial_vars.inputBufFill = 0; ! } ! } ! ! //=========================== interrupt handlers ============================== ! ! //executed in ISR, called from scheduler.c ! void isr_openserial_tx() { ! switch (openserial_vars.mode) { ! case MODE_INPUT: ! openserial_vars.reqFrameIdx++; ! if (openserial_vars.reqFrameIdxSERIAL_INPUT_BUFFER_SIZE){ ! // input buffer overflow ! openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUT_BUFFER_OVERFLOW, ! (errorparameter_t)0, ! (errorparameter_t)0); ! openserial_vars.inputBufFill = 0; ! openserial_vars.busyReceiving = FALSE; ! openserial_stop(); ! } ! } else if ( ! openserial_vars.busyReceiving==TRUE && ! rxbyte==HDLC_FLAG ! ) { ! // end of frame ! ! // finalize the HDLC frame ! inputHdlcClose(); ! ! if (openserial_vars.inputBufFill==0){ ! // invalid HDLC frame ! openserial_printError(COMPONENT_OPENSERIAL,ERR_INVALIDSERIALFRAME, ! (errorparameter_t)0, ! (errorparameter_t)0); ! ! } ! ! openserial_vars.busyReceiving = FALSE; ! openserial_stop(); ! } ! ! openserial_vars.lastRxByte = rxbyte; ! } ! ! ! //======== SERIAL ECHO ============= ! ! void openserial_echo(uint8_t* buf, uint8_t bufLen){ ! // echo back what you received ! openserial_printData( ! buf, ! bufLen ! ); ! } --- 1,648 ---- ! /** ! \brief Definition of the "openserial" driver. ! ! \author Fabien Chraim , March 2012. ! */ ! ! #include "openwsn.h" ! #include "openserial.h" ! #include "IEEE802154E.h" ! #include "neighbors.h" ! #include "res.h" ! #include "icmpv6echo.h" ! #include "idmanager.h" ! #include "openqueue.h" ! #include "tcpinject.h" ! #include "udpinject.h" ! #include "openbridge.h" ! #include "leds.h" ! #include "schedule.h" ! #include "uart_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;iaddr_16b[0]); ! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); ! // outputHdlcWrite(calling_component); ! // outputHdlcWrite(error_code); ! // outputHdlcWrite((uint8_t)((arg1 & 0xff00)>>8)); ! // outputHdlcWrite((uint8_t) (arg1 & 0x00ff)); ! // outputHdlcWrite((uint8_t)((arg2 & 0xff00)>>8)); ! // outputHdlcWrite((uint8_t) (arg2 & 0x00ff)); ! // outputHdlcClose(); ! // ENABLE_INTERRUPTS(); ! ! return E_SUCCESS; ! } ! ! owerror_t openserial_printData(uint8_t* buffer, uint8_t length) { ! (void)length; ! puts(buffer); ! // uint8_t i; ! // uint8_t asn[5]; ! // INTERRUPT_DECLARATION(); ! // ! // // retrieve ASN ! // ieee154e_getAsn(asn);// byte01,byte23,byte4 ! // ! // DISABLE_INTERRUPTS(); ! // openserial_vars.outputBufFilled = TRUE; ! // outputHdlcOpen(); ! // outputHdlcWrite(SERFRAME_MOTE2PC_DATA); ! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[1]); ! // outputHdlcWrite(idmanager_getMyID(ADDR_16B)->addr_16b[0]); ! // outputHdlcWrite(asn[0]); ! // outputHdlcWrite(asn[1]); ! // outputHdlcWrite(asn[2]); ! // outputHdlcWrite(asn[3]); ! // outputHdlcWrite(asn[4]); ! // for (i=0;i0) { ! // openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUTBUFFER_LENGTH, ! // (errorparameter_t)openserial_vars.inputBufFill, ! // (errorparameter_t)0); ! // DISABLE_INTERRUPTS(); ! // openserial_vars.inputBufFill=0; ! // ENABLE_INTERRUPTS(); ! // } ! // ! // uart_clearTxInterrupts(); ! // uart_clearRxInterrupts(); // clear possible pending interrupts ! // uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt ! // ! // DISABLE_INTERRUPTS(); ! // openserial_vars.busyReceiving = FALSE; ! // openserial_vars.mode = MODE_INPUT; ! // openserial_vars.reqFrameIdx = 0; ! // #ifdef FASTSIM ! // uart_writeBufferByLen_FASTSIM( ! // openserial_vars.reqFrame, ! // sizeof(openserial_vars.reqFrame) ! // ); ! // openserial_vars.reqFrameIdx = sizeof(openserial_vars.reqFrame); ! // #else ! // uart_writeByte(openserial_vars.reqFrame[openserial_vars.reqFrameIdx]); ! // #endif ! // ENABLE_INTERRUPTS(); ! } ! ! void openserial_startOutput(void) { ! // //schedule a task to get new status in the output buffer ! // uint8_t debugPrintCounter; ! // ! // INTERRUPT_DECLARATION(); ! // DISABLE_INTERRUPTS(); ! // openserial_vars.debugPrintCounter = (openserial_vars.debugPrintCounter+1)%STATUS_MAX; ! // debugPrintCounter = openserial_vars.debugPrintCounter; ! // ENABLE_INTERRUPTS(); ! // ! // // print debug information ! // switch (debugPrintCounter) { ! // case STATUS_ISSYNC: ! // if (debugPrint_isSync()==TRUE) { ! // break; ! // } ! // case STATUS_ID: ! // if (debugPrint_id()==TRUE) { ! // break; ! // } ! // case STATUS_DAGRANK: ! // if (debugPrint_myDAGrank()==TRUE) { ! // break; ! // } ! // case STATUS_OUTBUFFERINDEXES: ! // if (debugPrint_outBufferIndexes()==TRUE) { ! // break; ! // } ! // case STATUS_ASN: ! // if (debugPrint_asn()==TRUE) { ! // break; ! // } ! // case STATUS_MACSTATS: ! // if (debugPrint_macStats()==TRUE) { ! // break; ! // } ! // case STATUS_SCHEDULE: ! // if(debugPrint_schedule()==TRUE) { ! // break; ! // } ! // case STATUS_BACKOFF: ! // if(debugPrint_backoff()==TRUE) { ! // break; ! // } ! // case STATUS_QUEUE: ! // if(debugPrint_queue()==TRUE) { ! // break; ! // } ! // case STATUS_NEIGHBORS: ! // if (debugPrint_neighbors()==TRUE) { ! // break; ! // } ! // default: ! // DISABLE_INTERRUPTS(); ! // openserial_vars.debugPrintCounter=0; ! // ENABLE_INTERRUPTS(); ! // } ! // ! // // flush buffer ! // uart_clearTxInterrupts(); ! // uart_clearRxInterrupts(); // clear possible pending interrupts ! // uart_enableInterrupts(); // Enable USCI_A1 TX & RX interrupt ! // DISABLE_INTERRUPTS(); ! // openserial_vars.mode=MODE_OUTPUT; ! // if (openserial_vars.outputBufFilled) { ! // #ifdef FASTSIM ! // uart_writeCircularBuffer_FASTSIM( ! // openserial_vars.outputBuf, ! // &openserial_vars.outputBufIdxR, ! // &openserial_vars.outputBufIdxW ! // ); ! // #else ! // uart_writeByte(openserial_vars.outputBuf[openserial_vars.outputBufIdxR++]); ! // #endif ! // } else { ! // openserial_stop(); ! // } ! // ENABLE_INTERRUPTS(); ! } ! ! void openserial_stop(void) { ! // uint8_t inputBufFill; ! // uint8_t cmdByte; ! // bool busyReceiving; ! // INTERRUPT_DECLARATION(); ! // ! // DISABLE_INTERRUPTS(); ! // busyReceiving = openserial_vars.busyReceiving; ! // inputBufFill = openserial_vars.inputBufFill; ! // ENABLE_INTERRUPTS(); ! // ! // // disable USCI_A1 TX & RX interrupt ! // uart_disableInterrupts(); ! // ! // DISABLE_INTERRUPTS(); ! // openserial_vars.mode=MODE_OFF; ! // ENABLE_INTERRUPTS(); ! // //the inputBuffer has to be reset if it is not reset where the data is read. ! // //or the function openserial_getInputBuffer is called (which resets the buffer) ! // if (busyReceiving==TRUE){ ! // openserial_printError(COMPONENT_OPENSERIAL,ERR_BUSY_RECEIVING, ! // (errorparameter_t)0, ! // (errorparameter_t)inputBufFill); ! // } ! // ! // if (busyReceiving == FALSE && inputBufFill>0) { ! // DISABLE_INTERRUPTS(); ! // cmdByte = openserial_vars.inputBuf[0]; ! // ENABLE_INTERRUPTS(); ! // switch (cmdByte) { ! // case SERFRAME_PC2MOTE_SETROOT: ! // idmanager_triggerAboutRoot(); ! // break; ! // case SERFRAME_PC2MOTE_SETBRIDGE: ! // idmanager_triggerAboutBridge(); ! // break; ! // case SERFRAME_PC2MOTE_DATA: ! // openbridge_triggerData(); ! // break; ! // case SERFRAME_PC2MOTE_TRIGGERTCPINJECT: ! // tcpinject_trigger(); ! // break; ! // case SERFRAME_PC2MOTE_TRIGGERUDPINJECT: ! // udpinject_trigger(); ! // break; ! // case SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO: ! // icmpv6echo_trigger(); ! // break; ! // case SERFRAME_PC2MOTE_TRIGGERSERIALECHO: ! // //echo function must reset input buffer after reading the data. ! // openserial_echo(&openserial_vars.inputBuf[1],inputBufFill-1); ! // break; ! // default: ! // openserial_printError(COMPONENT_OPENSERIAL,ERR_UNSUPPORTED_COMMAND, ! // (errorparameter_t)cmdByte, ! // (errorparameter_t)0); ! // //reset here as it is not being reset in any other callback ! // DISABLE_INTERRUPTS(); ! // openserial_vars.inputBufFill = 0; ! // ENABLE_INTERRUPTS(); ! // break; ! // } ! // } ! // ! // DISABLE_INTERRUPTS(); ! // openserial_vars.inputBufFill = 0; ! // openserial_vars.busyReceiving = FALSE; ! // ENABLE_INTERRUPTS(); ! } ! ! /** ! \brief Trigger this module to print status information, over serial. ! ! debugPrint_* functions are used by the openserial module to continuously print ! status information about several modules in the OpenWSN stack. ! ! \returns TRUE if this function printed something, FALSE otherwise. ! */ ! bool debugPrint_outBufferIndexes(void) { ! // uint16_t temp_buffer[2]; ! // INTERRUPT_DECLARATION(); ! // DISABLE_INTERRUPTS(); ! // temp_buffer[0] = openserial_vars.outputBufIdxW; ! // temp_buffer[1] = openserial_vars.outputBufIdxR; ! // ENABLE_INTERRUPTS(); ! // openserial_printStatus(STATUS_OUTBUFFERINDEXES,(uint8_t*)temp_buffer,sizeof(temp_buffer)); ! return TRUE; ! } ! ! //=========================== private ========================================= ! ! //===== hdlc (output) ! ! /** ! \brief Start an HDLC frame in the output buffer. ! */ ! // inline void outputHdlcOpen(void) { ! // // initialize the value of the CRC ! // openserial_vars.outputCrc = HDLC_CRCINIT; ! // ! // // write the opening HDLC flag ! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; ! // } ! /** ! \brief Add a byte to the outgoing HDLC frame being built. ! */ ! // inline void outputHdlcWrite(uint8_t b) { ! // ! // // iterate through CRC calculator ! // openserial_vars.outputCrc = crcIteration(openserial_vars.outputCrc,b); ! // ! // // add byte to buffer ! // if (b==HDLC_FLAG || b==HDLC_ESCAPE) { ! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_ESCAPE; ! // b = b^HDLC_ESCAPE_MASK; ! // } ! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = b; ! // ! // } ! /** ! \brief Finalize the outgoing HDLC frame. ! */ ! // inline void outputHdlcClose(void) { ! // uint16_t finalCrc; ! // ! // // finalize the calculation of the CRC ! // finalCrc = ~openserial_vars.outputCrc; ! // ! // // write the CRC value ! // outputHdlcWrite((finalCrc>>0)&0xff); ! // outputHdlcWrite((finalCrc>>8)&0xff); ! // ! // // write the closing HDLC flag ! // openserial_vars.outputBuf[openserial_vars.outputBufIdxW++] = HDLC_FLAG; ! // } ! ! //===== hdlc (input) ! ! /** ! \brief Start an HDLC frame in the input buffer. ! */ ! // inline void inputHdlcOpen(void) { ! // // reset the input buffer index ! // openserial_vars.inputBufFill = 0; ! // ! // // initialize the value of the CRC ! // openserial_vars.inputCrc = HDLC_CRCINIT; ! // } ! /** ! \brief Add a byte to the incoming HDLC frame. ! */ ! // inline void inputHdlcWrite(uint8_t b) { ! // if (b==HDLC_ESCAPE) { ! // openserial_vars.inputEscaping = TRUE; ! // } else { ! // if (openserial_vars.inputEscaping==TRUE) { ! // b = b^HDLC_ESCAPE_MASK; ! // openserial_vars.inputEscaping = FALSE; ! // } ! // ! // // add byte to input buffer ! // openserial_vars.inputBuf[openserial_vars.inputBufFill] = b; ! // openserial_vars.inputBufFill++; ! // ! // // iterate through CRC calculator ! // openserial_vars.inputCrc = crcIteration(openserial_vars.inputCrc,b); ! // } ! // } ! /** ! \brief Finalize the incoming HDLC frame. ! */ ! // inline void inputHdlcClose(void) { ! // ! // // verify the validity of the frame ! // if (openserial_vars.inputCrc==HDLC_CRCGOOD) { ! // // the CRC is correct ! // ! // // remove the CRC from the input buffer ! // openserial_vars.inputBufFill -= 2; ! // } else { ! // // the CRC is incorrect ! // ! // // drop the incoming fram ! // openserial_vars.inputBufFill = 0; ! // } ! // } ! ! //=========================== interrupt handlers ============================== ! ! // executed in ISR, called from scheduler.c ! // void isr_openserial_tx(void) { ! // switch (openserial_vars.mode) { ! // case MODE_INPUT: ! // openserial_vars.reqFrameIdx++; ! // if (openserial_vars.reqFrameIdxSERIAL_INPUT_BUFFER_SIZE){ ! // // input buffer overflow ! // openserial_printError(COMPONENT_OPENSERIAL,ERR_INPUT_BUFFER_OVERFLOW, ! // (errorparameter_t)0, ! // (errorparameter_t)0); ! // openserial_vars.inputBufFill = 0; ! // openserial_vars.busyReceiving = FALSE; ! // openserial_stop(); ! // } ! // } else if ( ! // openserial_vars.busyReceiving==TRUE && ! // rxbyte==HDLC_FLAG ! // ) { ! // // end of frame ! // ! // // finalize the HDLC frame ! // inputHdlcClose(); ! // ! // if (openserial_vars.inputBufFill==0){ ! // // invalid HDLC frame ! // openserial_printError(COMPONENT_OPENSERIAL,ERR_WRONG_CRC_INPUT, ! // (errorparameter_t)inputBufFill, ! // (errorparameter_t)0); ! // ! // } ! // ! // openserial_vars.busyReceiving = FALSE; ! // openserial_stop(); ! // } ! // ! // openserial_vars.lastRxByte = rxbyte; ! // } ! ! //======== SERIAL ECHO ============= ! ! void openserial_echo(uint8_t* buf, uint8_t bufLen){ ! INTERRUPT_DECLARATION(); ! // echo back what you received ! openserial_printData( ! buf, ! bufLen ! ); ! ! DISABLE_INTERRUPTS(); ! openserial_vars.inputBufFill = 0; ! ENABLE_INTERRUPTS(); ! } diff -crB openwsn/openserial.h ../../../sys/net/openwsn/openserial.h *** openwsn/openserial.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/openserial.h Wed Jan 15 13:48:27 2014 *************** *** 1,94 **** ! /** ! \brief Declaration of the "openserial" driver. ! ! \author Fabien Chraim , March 2012. ! */ ! ! #ifndef __OPENSERIAL_H ! #define __OPENSERIAL_H ! ! #include "openwsn.h" ! ! /** ! \addtogroup cross-layers ! \{ ! \addtogroup OpenSerial ! \{ ! */ ! ! //=========================== define ========================================== ! ! /** ! \brief Number of bytes of the serial output buffer, in bytes. ! ! \warning should be exactly 256 so wrap-around on the index does not require ! the use of a slow modulo operator. ! */ ! #define SERIAL_OUTPUT_BUFFER_SIZE 256 // leave at 256! ! ! /** ! \brief Number of bytes of the serial input buffer, in bytes. ! ! \warning Do not pick a number greater than 255, since its filling level is ! encoded by a single byte in the code. ! */ ! #define SERIAL_INPUT_BUFFER_SIZE 200 ! ! /// Modes of the openserial module. ! enum { ! MODE_OFF = 0, ///< The module is off, no serial activity. ! MODE_INPUT = 1, ///< The serial is listening or receiving bytes. ! MODE_OUTPUT = 2 ///< The serial is transmitting bytes. ! }; ! ! // frames sent mote->PC ! #define SERFRAME_MOTE2PC_DATA ((uint8_t)'D') ! #define SERFRAME_MOTE2PC_STATUS ((uint8_t)'S') ! #define SERFRAME_MOTE2PC_INFO ((uint8_t)'I') ! #define SERFRAME_MOTE2PC_ERROR ((uint8_t)'E') ! #define SERFRAME_MOTE2PC_CRITICAL ((uint8_t)'C') ! #define SERFRAME_MOTE2PC_REQUEST ((uint8_t)'R') ! ! // frames sent PC->mote ! #define SERFRAME_PC2MOTE_SETROOT ((uint8_t)'R') ! #define SERFRAME_PC2MOTE_SETBRIDGE ((uint8_t)'B') ! #define SERFRAME_PC2MOTE_DATA ((uint8_t)'D') ! #define SERFRAME_PC2MOTE_TRIGGERTCPINJECT ((uint8_t)'T') ! #define SERFRAME_PC2MOTE_TRIGGERUDPINJECT ((uint8_t)'U') ! #define SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO ((uint8_t)'E') ! #define SERFRAME_PC2MOTE_TRIGGERSERIALECHO ((uint8_t)'S') ! ! //=========================== typedef ========================================= ! ! //=========================== prototypes ====================================== ! ! void openserial_init(); ! error_t openserial_printStatus(uint8_t statusElement, uint8_t* buffer, uint16_t length); ! error_t openserial_printInfo(uint8_t calling_component, uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2); ! error_t openserial_printError(uint8_t calling_component, uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2); ! error_t openserial_printCritical(uint8_t calling_component, uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2); ! error_t openserial_printData(uint8_t* buffer, uint8_t length); ! uint8_t openserial_getNumDataBytes(); ! uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes); ! void openserial_startInput(); ! void openserial_startOutput(); ! void openserial_stop(); ! bool debugPrint_outBufferIndexes(); ! void openserial_echo(uint8_t* but, uint8_t bufLen); ! ! // interrupt handlers ! void isr_openserial_rx(); ! void isr_openserial_tx(); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file --- 1,117 ---- ! /** ! \brief Declaration of the "openserial" driver. ! ! \author Fabien Chraim , March 2012. ! */ ! ! #ifndef __OPENSERIAL_H ! #define __OPENSERIAL_H ! ! #include "openwsn.h" ! ! /** ! \addtogroup drivers ! \{ ! \addtogroup OpenSerial ! \{ ! */ ! ! //=========================== define ========================================== ! ! /** ! \brief Number of bytes of the serial output buffer, in bytes. ! ! \warning should be exactly 256 so wrap-around on the index does not require ! the use of a slow modulo operator. ! */ ! #define SERIAL_OUTPUT_BUFFER_SIZE 256 // leave at 256! ! ! /** ! \brief Number of bytes of the serial input buffer, in bytes. ! ! \warning Do not pick a number greater than 255, since its filling level is ! encoded by a single byte in the code. ! */ ! #define SERIAL_INPUT_BUFFER_SIZE 200 ! ! /// Modes of the openserial module. ! enum { ! MODE_OFF = 0, ///< The module is off, no serial activity. ! MODE_INPUT = 1, ///< The serial is listening or receiving bytes. ! MODE_OUTPUT = 2 ///< The serial is transmitting bytes. ! }; ! ! // frames sent mote->PC ! #define SERFRAME_MOTE2PC_DATA ((uint8_t)'D') ! #define SERFRAME_MOTE2PC_STATUS ((uint8_t)'S') ! #define SERFRAME_MOTE2PC_INFO ((uint8_t)'I') ! #define SERFRAME_MOTE2PC_ERROR ((uint8_t)'E') ! #define SERFRAME_MOTE2PC_CRITICAL ((uint8_t)'C') ! #define SERFRAME_MOTE2PC_REQUEST ((uint8_t)'R') ! ! // frames sent PC->mote ! #define SERFRAME_PC2MOTE_SETROOT ((uint8_t)'R') ! #define SERFRAME_PC2MOTE_SETBRIDGE ((uint8_t)'B') ! #define SERFRAME_PC2MOTE_DATA ((uint8_t)'D') ! #define SERFRAME_PC2MOTE_TRIGGERTCPINJECT ((uint8_t)'T') ! #define SERFRAME_PC2MOTE_TRIGGERUDPINJECT ((uint8_t)'U') ! #define SERFRAME_PC2MOTE_TRIGGERICMPv6ECHO ((uint8_t)'E') ! #define SERFRAME_PC2MOTE_TRIGGERSERIALECHO ((uint8_t)'S') ! ! //=========================== typedef ========================================= ! ! //=========================== module variables ================================ ! ! typedef struct { ! // admin ! uint8_t mode; ! uint8_t debugPrintCounter; ! // input ! uint8_t reqFrame[1+1+2+1]; // flag (1B), command (2B), CRC (2B), flag (1B) ! uint8_t reqFrameIdx; ! uint8_t lastRxByte; ! bool busyReceiving; ! bool inputEscaping; ! uint16_t inputCrc; ! uint8_t inputBufFill; ! uint8_t inputBuf[SERIAL_INPUT_BUFFER_SIZE]; ! // output ! bool outputBufFilled; ! uint16_t outputCrc; ! uint8_t outputBufIdxW; ! uint8_t outputBufIdxR; ! uint8_t outputBuf[SERIAL_OUTPUT_BUFFER_SIZE]; ! } openserial_vars_t; ! ! //=========================== prototypes ====================================== ! ! void openserial_init(void); ! owerror_t openserial_printStatus(uint8_t statusElement, uint8_t* buffer, uint8_t length); ! owerror_t openserial_printInfo(uint8_t calling_component, uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2); ! owerror_t openserial_printError(uint8_t calling_component, uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2); ! owerror_t openserial_printCritical(uint8_t calling_component, uint8_t error_code, ! errorparameter_t arg1, ! errorparameter_t arg2); ! owerror_t openserial_printData(uint8_t* buffer, uint8_t length); ! uint8_t openserial_getNumDataBytes(void); ! uint8_t openserial_getInputBuffer(uint8_t* bufferToWrite, uint8_t maxNumBytes); ! void openserial_startInput(void); ! void openserial_startOutput(void); ! void openserial_stop(void); ! bool debugPrint_outBufferIndexes(void); ! void openserial_echo(uint8_t* but, uint8_t bufLen); ! ! // interrupt handlers ! void isr_openserial_rx(void); ! void isr_openserial_tx(void); ! ! /** ! \} ! \} ! */ ! #endif \ No newline at end of file diff -crB openwsn/opentimers.c ../../../sys/net/openwsn/opentimers.c *** openwsn/opentimers.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/opentimers.c Wed Jan 15 13:48:27 2014 *************** *** 1,284 **** ! /** ! \brief Definition of the "opentimers" driver. ! ! This driver uses a single hardware timer, which it virtualizes to support ! at most MAX_NUM_TIMERS timers. ! ! \author Xavi Vilajosana , March 2012. ! */ ! ! #include "openwsn.h" ! #include "opentimers.h" ! #include "bsp_timer.h" ! #include "leds.h" ! ! //=========================== define ========================================== ! ! //=========================== variables ======================================= ! ! typedef struct { ! opentimers_t timersBuf[MAX_NUM_TIMERS]; ! bool running; ! PORT_TIMER_WIDTH currentTimeout; // current timeout, in ticks ! } opentimers_vars_t; ! ! opentimers_vars_t opentimers_vars; ! //uint32_t counter; //counts the elapsed time. ! ! //=========================== prototypes ====================================== ! ! void opentimers_timer_callback(); ! ! //=========================== public ========================================== ! ! /** ! \brief Initialize this module. ! ! Initializes data structures and hardware timer. ! */ ! void opentimers_init(){ ! uint8_t i; ! ! // initialize local variables ! opentimers_vars.running=FALSE; ! for (i=0;i= opentimers_vars.timersBuf[id].ticks_remaining) { ! // this timer has expired ! //check to see if we have completed the whole timer, or we're just wrapping around the max 16bit value ! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ ! // declare as so ! opentimers_vars.timersBuf[id].hasExpired = TRUE; ! }else{ ! opentimers_vars.timersBuf[id].wraps_remaining--; ! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ ! //if we have fully wrapped around, then set the remainring ticks to the modulus of the total ticks and the max clock value ! opentimers_vars.timersBuf[id].ticks_remaining = (opentimers_vars.timersBuf[id].period_ticks) % MAX_TICKS_IN_SINGLE_CLOCK; ! }else{ ! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK; ! } ! } ! } else { ! // this timer is not expired ! ! // update its counter ! opentimers_vars.timersBuf[id].ticks_remaining -= opentimers_vars.currentTimeout; ! } ! } ! } ! ! // step 2. call callbacks of expired timers ! for(id=0; id, March 2012. ! */ ! ! #include "openwsn.h" ! #include "opentimers.h" ! //#include "bsp_timer.h" ! #include "leds.h" ! ! #include "hwtimer_arch.h" ! #include "hwtimer_cpu.h" ! ! //=========================== define ========================================== ! ! //=========================== variables ======================================= ! ! opentimers_vars_t opentimers_vars; ! //uint32_t counter; //counts the elapsed time. ! ! //=========================== prototypes ====================================== ! ! void opentimers_int_handler(int); ! void opentimers_timer_callback(void); ! ! //=========================== public ========================================== ! ! /** ! \brief Initialize this module. ! ! Initializes data structures and hardware timer. ! */ ! void opentimers_init(void){ ! uint8_t i; ! ! // initialize local variables ! opentimers_vars.running=FALSE; ! for (i=0;iduration: ! - #TIME_MS when duration is in ms. ! - #TIME_TICS when duration is in clock ticks. ! \param callback The function to call when the timer fires. ! ! \returns The id of the timer (which serves as a handler to stop it) if the ! timer could be started. ! \returns TOO_MANY_TIMERS_ERROR if the timer could NOT be started. ! */ ! opentimer_id_t opentimers_start(uint32_t duration, timer_type_t type, time_type_t timetype, opentimers_cbt callback) { ! ! uint8_t id; ! ! // find an unused timer ! for (id=0; id= opentimers_vars.timersBuf[id].ticks_remaining) { ! // this timer has expired ! //check to see if we have completed the whole timer, or we're just wrapping around the max 16bit value ! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ ! // declare as so ! opentimers_vars.timersBuf[id].hasExpired = TRUE; ! }else{ ! opentimers_vars.timersBuf[id].wraps_remaining--; ! if(opentimers_vars.timersBuf[id].wraps_remaining == 0){ ! //if we have fully wrapped around, then set the remainring ticks to the modulus of the total ticks and the max clock value ! opentimers_vars.timersBuf[id].ticks_remaining = (opentimers_vars.timersBuf[id].period_ticks) % MAX_TICKS_IN_SINGLE_CLOCK; ! }else{ ! opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK; ! } ! } ! } else { ! // this timer is not expired ! ! // update its counter ! opentimers_vars.timersBuf[id].ticks_remaining -= opentimers_vars.currentTimeout; ! } ! } ! } ! ! // step 2. call callbacks of expired timers ! for(id=0; id sleepTime) ! { ! opentimers_vars.timersBuf[id].ticks_remaining -= sleepTime; ! } ! else ! { ! if(opentimers_vars.timersBuf[id].wraps_remaining > 0) ! { ! opentimers_vars.timersBuf[id].wraps_remaining--; ! opentimers_vars.timersBuf[id].ticks_remaining += (MAX_TICKS_IN_SINGLE_CLOCK - sleepTime); ! } ! else ! { ! opentimers_vars.timersBuf[id].hasExpired = TRUE; ! } ! } ! } ! } ! ! // step 2. call callbacks of expired timers ! for(id=0; id, March 2012. ! */ ! ! #ifndef __OPENTIMERS_H ! #define __OPENTIMERS_H ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! /// Maximum number of timers that can run concurrently ! #define MAX_NUM_TIMERS 10 ! ! #define MAX_TICKS_IN_SINGLE_CLOCK ((PORT_TIMER_WIDTH)0xFFFFFFFF) ! ! #define TOO_MANY_TIMERS_ERROR 255 ! ! #define opentimer_id_t uint8_t ! ! typedef void (*opentimers_cbt)(void); ! ! //=========================== typedef ========================================= ! ! typedef enum { ! TIMER_PERIODIC, ! TIMER_ONESHOT, ! } timer_type_t; ! ! /*the time can be in tics or in ms*/ ! typedef enum { ! TIME_MS, ! TIME_TICS, ! } time_type_t; ! ! typedef struct { ! uint32_t period_ticks; // total number of clock ticks ! PORT_TIMER_WIDTH ticks_remaining; // ticks remaining before elapses ! uint16_t wraps_remaining; // the clock register is 16 bit, and can't count beyond 32k... ! // so period_ticks = wraps_remaining*(32k or uint16_t) ! timer_type_t type; // periodic or one-shot ! bool isrunning; // is running? ! opentimers_cbt callback; // function to call when elapses ! bool hasExpired; // whether the callback has to be called ! } opentimers_t; ! ! //=========================== prototypes ====================================== ! ! void opentimers_init(); ! opentimer_id_t opentimers_start(uint32_t duration, ! timer_type_t type, ! time_type_t timetype, ! opentimers_cbt callback); ! void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype, uint32_t newPeriod); ! void opentimers_stop(opentimer_id_t id); ! void opentimers_restart(opentimer_id_t id); ! ! #endif --- 1,86 ---- ! /** ! \brief Declaration of the "opentimers" driver. ! ! \author Xavi Vilajosana , March 2012. ! */ ! ! #ifndef __OPENTIMERS_H ! #define __OPENTIMERS_H ! ! #include "openwsn.h" ! ! #include "hwtimer_cpu.h" ! ! /** ! \addtogroup drivers ! \{ ! \addtogroup OpenTimers ! \{ ! */ ! ! //=========================== define ========================================== ! ! /// Maximum number of timers that can run concurrently ! #define MAX_NUM_TIMERS 10 ! ! #define MAX_TICKS_IN_SINGLE_CLOCK ((PORT_TIMER_WIDTH)0xFFFFFFFF) ! ! #define TOO_MANY_TIMERS_ERROR 255 ! ! #define opentimer_id_t uint8_t ! ! typedef void (*opentimers_cbt)(void); ! ! #define OPENTIMERS_HWTIMER_ID (ARCH_MAXTIMERS - 1) ! ! //=========================== typedef ========================================= ! ! typedef enum { ! TIMER_PERIODIC, ! TIMER_ONESHOT, ! } timer_type_t; ! ! /*the time can be in tics or in ms*/ ! typedef enum { ! TIME_MS, ! TIME_TICS, ! } time_type_t; ! ! typedef struct { ! uint32_t period_ticks; // total number of clock ticks ! PORT_TIMER_WIDTH ticks_remaining; // ticks remaining before elapses ! uint16_t wraps_remaining; // the clock register is 16 bit, and can't count beyond 32k... ! // so period_ticks = wraps_remaining*(32k or uint16_t) ! timer_type_t type; // periodic or one-shot ! bool isrunning; // is running? ! opentimers_cbt callback; // function to call when elapses ! bool hasExpired; // whether the callback has to be called ! } opentimers_t; ! ! //=========================== module variables ================================ ! ! typedef struct { ! opentimers_t timersBuf[MAX_NUM_TIMERS]; ! bool running; ! PORT_TIMER_WIDTH currentTimeout; // current timeout, in ticks ! } opentimers_vars_t; ! ! //=========================== prototypes ====================================== ! ! void opentimers_init(void); ! opentimer_id_t opentimers_start(uint32_t duration, ! timer_type_t type, ! time_type_t timetype, ! opentimers_cbt callback); ! void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype, uint32_t newPeriod); ! void opentimers_stop(opentimer_id_t id); ! void opentimers_restart(opentimer_id_t id); ! ! void opentimers_sleepTimeCompesation(uint16_t sleepTime); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/openwsn.c ../../../sys/net/openwsn/openwsn.c *** openwsn/openwsn.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/openwsn.c Wed Jan 15 13:48:27 2014 *************** *** 1,134 **** ! /** ! \brief General OpenWSN definitions ! ! \author Thomas Watteyne , September 2012 ! */ ! ! #include "openwsn.h" ! //===== drivers ! #include "openserial.h" ! //===== stack ! //-- cross-layer ! #include "idmanager.h" ! #include "openqueue.h" ! #include "openrandom.h" ! #include "opentimers.h" ! //-- 02a-TSCH ! #include "IEEE802154E.h" ! //-- 02b-RES ! #include "schedule.h" ! #include "res.h" ! #include "neighbors.h" ! //-- 03a-IPHC ! #include "openbridge.h" ! #include "iphc.h" ! //-- 03b-IPv6 ! #include "forwarding.h" ! #include "icmpv6.h" ! #include "icmpv6echo.h" ! #include "icmpv6rpl.h" ! //-- 04-TRAN ! #include "opentcp.h" ! #include "openudp.h" ! #include "opencoap.h" ! //-- app (common) ! //#include "rreg.h" ! //#include "rwellknown.h" ! //#include "rinfo.h" ! //===== applications ! //-- TCP ! #include "tcpecho.h" ! #include "tcpinject.h" ! #include "tcpprint.h" ! #include "ohlone.h" ! //-- UDP ! #include "udpecho.h" ! #include "udpinject.h" ! #include "udpprint.h" ! //#include "udprand.h" ! //#include "udplatency.h" ! //#include "udpstorm.h" ! //-- CoAP ! //#include "rleds.h" ! //#include "rt.h" ! //#include "rex.h" ! //#include "rheli.h" ! //#include "rrube.h" ! //#include "rxl1.h" ! //#include "layerdebug.h" ! //-- misc ! //#include "heli.h" ! //#include "imu.h" ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void openwsn_init(); ! ! //=========================== public ========================================== ! ! //=========================== private ========================================= ! ! void openwsn_init() { ! //===== drivers ! openserial_init(); ! ! //===== stack ! //-- cross-layer ! idmanager_init(); // call first since initializes EUI64 and isDAGroot ! openqueue_init(); ! openrandom_init(); ! opentimers_init(); ! //-- 02a-TSCH ! ieee154e_init(); ! //-- 02b-RES ! schedule_init(); ! res_init(); ! neighbors_init(); ! //-- 03a-IPHC ! openbridge_init(); ! iphc_init(); ! //-- 03b-IPv6 ! forwarding_init(); ! icmpv6_init(); ! icmpv6echo_init(); ! icmpv6rpl_init(); ! //-- 04-TRAN ! opentcp_init(); ! openudp_init(); ! opencoap_init(); // initialize before any of the CoAP applications ! //-- app (common) ! //rreg_init(); ! //rwellknown_init(); ! //rinfo_init(); ! ! //===== applications ! //-- TCP ! tcpecho_init(); ! tcpinject_init(); ! tcpprint_init(); ! ohlone_init(); ! //-- UDP ! udpecho_init(); ! udpinject_init(); ! udpprint_init(); ! //udprand_init(); ! //udplatency_init(); ! //udpstorm_init(); ! //-- CoAP ! //rleds_init(); ! //rt_init(); ! //rex_init(); ! //rheli_init(); ! //rrube_init(); ! //rxl1_init(); ! //layerdebug_init(); ! //-- misc ! //heli_init(); ! //imu_init(); ! ! openserial_printInfo(COMPONENT_OPENWSN,ERR_BOOTED, ! (errorparameter_t)0, ! (errorparameter_t)0); } \ No newline at end of file --- 1,158 ---- ! /** ! \brief General OpenWSN definitions ! ! \author Thomas Watteyne , September 2012 ! */ ! ! #include "openwsn.h" ! #include "scheduler.h" ! #include "thread.h" ! #include "board_ow.h" ! //===== drivers ! #include "openserial.h" ! //===== stack ! //-- cross-layer ! #include "idmanager.h" ! #include "openqueue.h" ! #include "openrandom.h" ! #include "opentimers.h" ! //-- 02a-TSCH ! #include "IEEE802154E.h" ! //-- 02b-RES ! #include "schedule.h" ! #include "res.h" ! #include "neighbors.h" ! //-- 03a-IPHC ! #include "openbridge.h" ! #include "iphc.h" ! //-- 03b-IPv6 ! #include "forwarding.h" ! #include "icmpv6.h" ! #include "icmpv6echo.h" ! #include "icmpv6rpl.h" ! //-- 04-TRAN ! #include "opentcp.h" ! #include "openudp.h" ! #include "opencoap.h" ! //-- app (common) ! //#include "rreg.h" ! #include "rwellknown.h" ! #include "rinfo.h" ! //===== applications ! //-- TCP ! //#include "tcpecho.h" ! //#include "tcpinject.h" ! //#include "tcpprint.h" ! #include "ohlone.h" ! //-- UDP ! #include "udpecho.h" ! #include "udpinject.h" ! #include "udpprint.h" ! //#include "udprand.h" ! //#include "udplatency.h" ! //#include "udpstorm.h" ! //-- CoAP ! //#include "rleds.h" ! //#include "rt.h" ! //#include "rex.h" ! //#include "rheli.h" ! //#include "rrube.h" ! //#include "rxl1.h" ! //#include "layerdebug.h" ! //#include "r6tus.h" ! //-- misc ! //#include "heli.h" ! //#include "imu.h" ! ! //=========================== variables ======================================= ! ! static char openwsn_stack[KERNEL_CONF_STACKSIZE_MAIN]; ! ! //=========================== prototypes ====================================== ! ! void openwsn_init(void); ! void openwsn_start(void); ! ! //=========================== public ========================================== ! ! void openwsn_start_thread(void) { ! puts(__PRETTY_FUNCTION__); ! thread_create(openwsn_stack, KERNEL_CONF_STACKSIZE_MAIN, ! PRIORITY_OPENWSN, CREATE_STACKTEST, ! openwsn_start, "openwsn thread"); ! } ! ! void openwsn_start(void) { ! puts(__PRETTY_FUNCTION__); ! //board_init_ow(); ! scheduler_init(); ! openwsn_init(); ! scheduler_start(); ! } ! ! //=========================== private ========================================= ! ! void openwsn_init(void) { ! puts(__PRETTY_FUNCTION__); ! //===== drivers ! openserial_init(); ! ! //===== stack ! //-- cross-layer ! idmanager_init(); // call first since initializes EUI64 and isDAGroot ! openqueue_init(); ! openrandom_init(); ! opentimers_init(); ! //-- 02a-TSCH ! ieee154e_init(); ! //-- 02b-RES ! schedule_init(); ! res_init(); ! neighbors_init(); ! //-- 03a-IPHC ! openbridge_init(); ! iphc_init(); ! //-- 03b-IPv6 ! forwarding_init(); ! icmpv6_init(); ! icmpv6echo_init(); ! icmpv6rpl_init(); ! //-- 04-TRAN ! opentcp_init(); ! openudp_init(); ! opencoap_init(); // initialize before any of the CoAP applications ! //-- app (common) ! //rreg_init(); ! rwellknown_init(); ! rinfo_init(); ! ! //===== applications ! //-- TCP ! //tcpecho_init(); ! //tcpinject_init(); ! //tcpprint_init(); ! //ohlone_init(); ! //-- UDP ! udpecho_init(); ! udpinject_init(); ! udpprint_init(); ! //udprand_init(); ! //udplatency_init(); ! //udpstorm_init(); ! //-- CoAP ! //rleds_init(); ! //rt_init(); ! //rex_init(); ! //rheli_init(); ! //rrube_init(); ! //rxl1_init(); ! //layerdebug_init(); ! //r6tus_init(); ! //-- misc ! //heli_init(); ! //imu_init(); ! ! openserial_printInfo(COMPONENT_OPENWSN,ERR_BOOTED, ! (errorparameter_t)0, ! (errorparameter_t)0); } \ No newline at end of file diff -crB openwsn/openwsn.h ../../../sys/net/openwsn/openwsn.h *** openwsn/openwsn.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/openwsn.h Wed Jan 15 13:48:27 2014 *************** *** 1,314 **** ! /** ! \brief General OpenWSN definitions ! ! \author Thomas Watteyne , August 2010 ! \author Ankur Mehta , September 2010 ! */ ! ! #ifndef __OPENWSN_H ! #define __OPENWSN_H ! ! //general ! #include // needed for uin8_t, uint16_t ! #include "board_info.h" ! ! //=========================== define ========================================== ! ! static const uint8_t infoStackName[] = "OpenWSN "; ! #define OPENWSN_VERSION_MAJOR 1 ! #define OPENWSN_VERSION_MINOR 2 ! #define OPENWSN_VERSION_PATCH 1 ! ! // enter the last byte of your mote's address if you want it to be an LBR ! #define DEBUG_MOTEID_MASTER 0xe8 ! ! #ifndef TRUE ! #define TRUE 1 ! #endif ! ! #ifndef FALSE ! #define FALSE 0 ! #endif ! ! #define LENGTH_ADDR16b 2 ! #define LENGTH_ADDR64b 8 ! #define LENGTH_ADDR128b 16 ! ! enum { ! E_SUCCESS = 0, ! E_FAIL = 1, ! }; ! ! // types of addresses ! enum { ! ADDR_NONE = 0, ! ADDR_16B = 1, ! ADDR_64B = 2, ! ADDR_128B = 3, ! ADDR_PANID = 4, ! ADDR_PREFIX = 5, ! ADDR_ANYCAST = 6, ! }; ! ! enum { ! LITTLE_ENDIAN = TRUE, ! BIG_ENDIAN = FALSE, ! }; ! ! // protocol numbers, as defined by the IANA ! enum { ! IANA_UNDEFINED = 0x00, ! IANA_TCP = 0x06, ! IANA_UDP = 0x11, ! IANA_IPv6ROUTE = 43, ! IANA_ICMPv6 = 0x3a, ! IANA_ICMPv6_ECHO_REQUEST = 128, ! IANA_ICMPv6_ECHO_REPLY = 129, ! IANA_ICMPv6_RS = 133, ! IANA_ICMPv6_RA = 134, ! IANA_ICMPv6_RA_PREFIX_INFORMATION = 3, ! IANA_ICMPv6_RPL = 155, ! IANA_ICMPv6_RPL_DIO = 0x01, ! IANA_ICMPv6_RPL_DAO = 0x04, ! IANA_RSVP = 46, ! }; ! ! // well known ports (which we define) ! enum { ! //TCP ! WKP_TCP_HTTP = 80, ! WKP_TCP_ECHO = 7, ! WKP_TCP_INJECT = 2188, ! WKP_TCP_DISCARD = 9, ! //UDP ! WKP_UDP_COAP = 5683, ! WKP_UDP_HELI = 2192, ! WKP_UDP_IMU = 2190, ! WKP_UDP_ECHO = 7, ! WKP_UDP_INJECT = 2188, ! WKP_UDP_DISCARD = 9, ! WKP_UDP_RAND = 61000, ! WKP_UDP_LATENCY = 61001, ! }; ! ! //status elements ! enum { ! STATUS_ISSYNC = 0, ! STATUS_ID = 1, ! STATUS_DAGRANK = 2, ! STATUS_OUTBUFFERINDEXES = 3, ! STATUS_ASN = 4, ! STATUS_MACSTATS = 5, ! STATUS_SCHEDULE = 6, ! STATUS_BACKOFF = 7, ! STATUS_QUEUE = 8, ! STATUS_NEIGHBORS = 9, ! STATUS_MAX = 10, ! }; ! ! //component identifiers ! //the order is important because ! enum { ! COMPONENT_NULL = 0x00, ! COMPONENT_OPENWSN = 0x01, ! //cross-layers ! COMPONENT_IDMANAGER = 0x02, ! COMPONENT_OPENQUEUE = 0x03, ! COMPONENT_OPENSERIAL = 0x04, ! COMPONENT_PACKETFUNCTIONS = 0x05, ! COMPONENT_RANDOM = 0x06, ! //PHY ! COMPONENT_RADIO = 0x07, ! //MAClow ! COMPONENT_IEEE802154 = 0x08, ! COMPONENT_IEEE802154E = 0x09, ! ! //All components with higher component id than COMPONENT_IEEE802154E ! //won't be able to get free packets from the queue ! //when the mote is not synch ! ! //MAClow<->MAChigh ("virtual components") ! COMPONENT_RES_TO_IEEE802154E = 0x0a, ! COMPONENT_IEEE802154E_TO_RES = 0x0b, ! //MAChigh ! COMPONENT_RES = 0x0c, ! COMPONENT_NEIGHBORS = 0x0d, ! COMPONENT_SCHEDULE = 0x0e, ! //IPHC ! COMPONENT_OPENBRIDGE = 0x0f, ! COMPONENT_IPHC = 0x10, ! //IPv6 ! COMPONENT_FORWARDING = 0x11, ! COMPONENT_ICMPv6 = 0x12, ! COMPONENT_ICMPv6ECHO = 0x13, ! COMPONENT_ICMPv6ROUTER = 0x14, ! COMPONENT_ICMPv6RPL = 0x15, ! //TRAN ! COMPONENT_OPENTCP = 0x16, ! COMPONENT_OPENUDP = 0x17, ! COMPONENT_OPENCOAP = 0x18, ! //App test ! COMPONENT_TCPECHO = 0x19, ! COMPONENT_TCPINJECT = 0x1a, ! COMPONENT_TCPPRINT = 0x1b, ! COMPONENT_UDPECHO = 0x1c, ! COMPONENT_UDPINJECT = 0x1d, ! COMPONENT_UDPPRINT = 0x1e, ! COMPONENT_RSVP = 0x1f, ! //App ! COMPONENT_OHLONE = 0x20, ! COMPONENT_HELI = 0x21, ! COMPONENT_IMU = 0x22, ! COMPONENT_RLEDS = 0x23, ! COMPONENT_RREG = 0x24, ! COMPONENT_RWELLKNOWN = 0x25, ! COMPONENT_RT = 0x26, ! COMPONENT_REX = 0x27, ! COMPONENT_RXL1 = 0x28, ! COMPONENT_RINFO = 0x29, ! COMPONENT_RHELI = 0x2a, ! COMPONENT_RRUBE = 0x2b, ! COMPONENT_LAYERDEBUG = 0x2c, ! COMPONENT_UDPRAND = 0x2d, ! COMPONENT_UDPSTORM = 0x2e, ! COMPONENT_UDPLATENCY = 0x2f, ! COMPONENT_TEST = 0x30, ! }; ! ! /** ! \brief error codes used throughout the OpenWSN stack ! ! \note The comments are used in the Python parsing tool: ! - {0} refers to the value of the first argument, ! - {1} refers to the value of the second argument, ! */ ! enum { ! // l7 ! ERR_RCVD_ECHO_REQUEST = 0x01, // received an echo request ! ERR_RCVD_ECHO_REPLY = 0x02, // received an echo reply ! ERR_GETDATA_ASKS_TOO_FEW_BYTES = 0x03, // getData asks for too few bytes, maxNumBytes={0}, fill level={1} ! ERR_INPUT_BUFFER_OVERFLOW = 0x04, // the input buffer has overflown ! // l4 ! ERR_WRONG_TRAN_PROTOCOL = 0x05, // unknown transport protocol {0} (code location {1}) ! ERR_WRONG_TCP_STATE = 0x06, // wrong TCP state {0} (code location {1}) ! ERR_TCP_RESET = 0x07, // TCP reset while in state {0} (code location {1}) ! ERR_UNSUPPORTED_PORT_NUMBER = 0x08, // unsupported port number {0} (code location {1}) ! // l3 ! ERR_UNEXPECTED_DAO = 0x09, // unexpected DAO (code location {0}) ! ERR_UNSUPPORTED_ICMPV6_TYPE = 0x0a, // unsupported ICMPv6 type {0} (code location {1}) ! ERR_6LOWPAN_UNSUPPORTED = 0x0b, // unsupported 6LoWPAN parameter {1} at location {0} ! ERR_NO_NEXTHOP = 0x0c, // no next hop ! ERR_INVALID_PARAM = 0x0d, // invalid parameter ! ERR_INVALID_FWDMODE = 0x0e, // invalid forward mode ! ERR_LARGE_DAGRANK = 0x0f, // large DAGrank {0}, set to {1} ! ERR_HOP_LIMIT_REACHED = 0x10, // packet discarded hop limit reached ! // l2b ! ERR_NEIGHBORS_FULL = 0x11, // neighbors table is full (max number of neighbor is {0}) ! ERR_NO_SENT_PACKET = 0x12, // there is no sent packet in queue ! ERR_NO_RECEIVED_PACKET = 0x13, // there is no received packet in queue ! ERR_SCHEDULE_OVERFLOWN = 0x14, // schedule overflown ! // l2a ! ERR_WRONG_CELLTYPE = 0x15, // wrong celltype {0} at slotOffset {1} ! ERR_IEEE154_UNSUPPORTED = 0x16, // unsupported IEEE802.15.4 parameter {1} at location {0} ! ERR_DESYNCHRONIZED = 0x17, // got desynchronized at slotOffset {0} ! ERR_SYNCHRONIZED = 0x18, // synchronized at slotOffset {0} ! ERR_LARGE_TIMECORRECTION = 0x19, // large timeCorr.: {0} ticks (code loc. {1}) ! ERR_WRONG_STATE_IN_ENDFRAME_SYNC = 0x1a, // wrong state {0} in end of frame+sync ! ERR_WRONG_STATE_IN_STARTSLOT = 0x1b, // wrong state {0} in startSlot, at slotOffset {1} ! ERR_WRONG_STATE_IN_TIMERFIRES = 0x1c, // wrong state {0} in timer fires, at slotOffset {1} ! ERR_WRONG_STATE_IN_NEWSLOT = 0x1d, // wrong state {0} in start of frame, at slotOffset {1} ! ERR_WRONG_STATE_IN_ENDOFFRAME = 0x1e, // wrong state {0} in end of frame, at slotOffset {1} ! ERR_MAXTXDATAPREPARE_OVERFLOW = 0x1f, // maxTxDataPrepare overflows while at state {0} in slotOffset {1} ! ERR_MAXRXACKPREPARE_OVERFLOWS = 0x20, // maxRxAckPrepapare overflows while at state {0} in slotOffset {1} ! ERR_MAXRXDATAPREPARE_OVERFLOWS = 0x21, // maxRxDataPrepapre overflows while at state {0} in slotOffset {1} ! ERR_MAXTXACKPREPARE_OVERFLOWS = 0x22, // maxTxAckPrepapre overflows while at state {0} in slotOffset {1} ! ERR_WDDATADURATION_OVERFLOWS = 0x23, // wdDataDuration overflows while at state {0} in slotOffset {1} ! ERR_WDRADIO_OVERFLOWS = 0x24, // wdRadio overflows while at state {0} in slotOffset {1} ! ERR_WDRADIOTX_OVERFLOWS = 0x25, // wdRadioTx overflows while at state {0} in slotOffset {1} ! ERR_WDACKDURATION_OVERFLOWS = 0x26, // wdAckDuration overflows while at state {0} in slotOffset {1} ! // general ! ERR_BUSY_SENDING = 0x27, // busy sending ! ERR_UNEXPECTED_SENDDONE = 0x28, // sendDone for packet I didn't send ! ERR_NO_FREE_PACKET_BUFFER = 0x29, // no free packet buffer (code location {0}) ! ERR_FREEING_UNUSED = 0x2a, // freeing unused memory ! ERR_FREEING_ERROR = 0x2b, // freeing memory unsupported memory ! ERR_UNSUPPORTED_COMMAND = 0x2c, // unsupported command {0} ! ERR_MSG_UNKNOWN_TYPE = 0x2d, // unknown message type {0} ! ERR_WRONG_ADDR_TYPE = 0x2e, // wrong address type {0} (code location {1}) ! ERR_BRIDGE_MISMATCH = 0x2f, // isBridge mismatch (code location {0}) ! ERR_HEADER_TOO_LONG = 0x30, // header too long, length {1} (code location {0}) ! ERR_INPUTBUFFER_LENGTH = 0x31, // input length problem, length={0} ! ERR_BOOTED = 0x32, // booted ! ERR_INVALIDSERIALFRAME = 0x33, // invalid serial frame ! ERR_INVALIDPACKETFROMRADIO = 0x34, // invalid packet from radio, length {1} (code location {0}) ! }; ! ! //=========================== typedef ========================================= ! ! typedef uint16_t errorparameter_t; ! typedef uint16_t dagrank_t; ! typedef uint8_t error_t; ! #define bool uint8_t ! ! PRAGMA(pack(1)); ! typedef struct { ! uint8_t byte4; ! uint16_t bytes2and3; ! uint16_t bytes0and1; ! } asn_t; ! PRAGMA(pack()); ! ! PRAGMA(pack(1)); ! typedef struct { // always written big endian, i.e. MSB in addr[0] ! uint8_t type; ! union { ! uint8_t addr_16b[2]; ! uint8_t addr_64b[8]; ! uint8_t addr_128b[16]; ! uint8_t panid[2]; ! uint8_t prefix[8]; ! }; ! } open_addr_t; ! PRAGMA(pack()); ! ! typedef struct { ! //admin ! uint8_t creator; // the component which called getFreePacketBuffer() ! uint8_t owner; // the component which currently owns the entry ! uint8_t* payload; // pointer to the start of the payload within 'packet' ! uint8_t length; // length in bytes of the payload ! //l4 ! uint8_t l4_protocol; // l4 protocol to be used ! bool l4_protocol_compressed; // is the l4 protocol header compressed? ! uint16_t l4_sourcePortORicmpv6Type; // l4 source port ! uint16_t l4_destination_port; // l4 destination port ! uint8_t* l4_payload; // pointer to the start of the payload of l4 (used for retransmits) ! uint8_t l4_length; // length of the payload of l4 (used for retransmits) ! //l3 ! open_addr_t l3_destinationAdd; // 128b IPv6 destination (down stack) ! open_addr_t l3_sourceAdd; // 128b IPv6 source address ! //l2 ! error_t l2_sendDoneError; // outcome of trying to send this packet ! open_addr_t l2_nextORpreviousHop; // 64b IEEE802.15.4 next (down stack) or previous (up) hop address ! uint8_t l2_frameType; // beacon, data, ack, cmd ! uint8_t l2_dsn; // sequence number of the received frame ! uint8_t l2_retriesLeft; // number Tx retries left before packet dropped (dropped when hits 0) ! uint8_t l2_numTxAttempts; // number Tx attempts ! asn_t l2_asn; // at what ASN the packet was Tx'ed or Rx'ed ! uint8_t* l2_payload; // pointer to the start of the payload of l2 (used for MAC to fill in ASN in ADV) ! //l1 (drivers) ! uint8_t l1_txPower; // power for packet to Tx at ! int8_t l1_rssi; // RSSI of received packet ! uint8_t l1_lqi; // LQI of received packet ! bool l1_crc; // did received packet pass CRC check? ! //the packet ! uint8_t packet[1+1+125+2+1]; // 1B spi address, 1B length, 125B data, 2B CRC, 1B LQI ! } OpenQueueEntry_t; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void openwsn_init(); ! ! #endif --- 1,330 ---- ! /** ! \brief General OpenWSN definitions ! ! \author Thomas Watteyne , August 2010 ! \author Ankur Mehta , September 2010 ! */ ! ! #ifndef __OPENWSN_H ! #define __OPENWSN_H ! ! //general ! #include // needed for uin8_t, uint16_t ! #include "board_info.h" ! ! #include ! #include "kernel.h" ! //========================= prototypes ======================================== ! void openwsn_start_thread(void); ! ! //=========================== define ========================================== ! ! #define PRIORITY_OPENWSN PRIORITY_MAIN-1 ! ! static const uint8_t infoStackName[] = "OpenWSN "; ! #define OPENWSN_VERSION_MAJOR 1 ! #define OPENWSN_VERSION_MINOR 4 ! #define OPENWSN_VERSION_PATCH 1 ! ! #ifndef TRUE ! #define TRUE 1 ! #endif ! ! #ifndef FALSE ! #define FALSE 0 ! #endif ! ! #define LENGTH_ADDR16b 2 ! #define LENGTH_ADDR64b 8 ! #define LENGTH_ADDR128b 16 ! ! enum { ! E_SUCCESS = 0, ! E_FAIL = 1, ! }; ! ! // types of addresses ! enum { ! ADDR_NONE = 0, ! ADDR_16B = 1, ! ADDR_64B = 2, ! ADDR_128B = 3, ! ADDR_PANID = 4, ! ADDR_PREFIX = 5, ! ADDR_ANYCAST = 6, ! }; ! ! enum { ! OW_LITTLE_ENDIAN = TRUE, ! OW_BIG_ENDIAN = FALSE, ! }; ! ! // protocol numbers, as defined by the IANA ! enum { ! IANA_IPv6HOPOPT = 0x00, ! IANA_TCP = 0x06, ! IANA_UDP = 0x11, ! IANA_IPv6ROUTE = 0x2b, ! IANA_ICMPv6 = 0x3a, ! IANA_ICMPv6_ECHO_REQUEST = 128, ! IANA_ICMPv6_ECHO_REPLY = 129, ! IANA_ICMPv6_RS = 133, ! IANA_ICMPv6_RA = 134, ! IANA_ICMPv6_RA_PREFIX_INFORMATION = 3, ! IANA_ICMPv6_RPL = 155, ! IANA_ICMPv6_RPL_DIO = 0x01, ! IANA_ICMPv6_RPL_DAO = 0x02, ! IANA_RSVP = 46, ! IANA_UNDEFINED = 250, //use an unassigned ! }; ! ! // well known ports (which we define) ! // warning: first 4 MSB of 2° octect may coincide with previous protocol number ! enum { ! //TCP ! WKP_TCP_HTTP = 80, ! WKP_TCP_ECHO = 7, ! WKP_TCP_INJECT = 2188, ! WKP_TCP_DISCARD = 9, ! //UDP ! WKP_UDP_COAP = 5683, ! WKP_UDP_HELI = 2192, ! WKP_UDP_IMU = 2190, ! WKP_UDP_ECHO = 7, ! WKP_UDP_INJECT = 2188, ! WKP_UDP_DISCARD = 9, ! WKP_UDP_RAND = 61000, ! WKP_UDP_LATENCY = 61001, ! }; ! ! //status elements ! enum { ! STATUS_ISSYNC = 0, ! STATUS_ID = 1, ! STATUS_DAGRANK = 2, ! STATUS_OUTBUFFERINDEXES = 3, ! STATUS_ASN = 4, ! STATUS_MACSTATS = 5, ! STATUS_SCHEDULE = 6, ! STATUS_BACKOFF = 7, ! STATUS_QUEUE = 8, ! STATUS_NEIGHBORS = 9, ! STATUS_MAX = 10, ! }; ! ! //component identifiers ! //the order is important because ! enum { ! COMPONENT_NULL = 0x00, ! COMPONENT_OPENWSN = 0x01, ! //cross-layers ! COMPONENT_IDMANAGER = 0x02, ! COMPONENT_OPENQUEUE = 0x03, ! COMPONENT_OPENSERIAL = 0x04, ! COMPONENT_PACKETFUNCTIONS = 0x05, ! COMPONENT_RANDOM = 0x06, ! //PHY ! COMPONENT_RADIO = 0x07, ! //MAClow ! COMPONENT_IEEE802154 = 0x08, ! COMPONENT_IEEE802154E = 0x09, ! ! //All components with higher component id than COMPONENT_IEEE802154E ! //won't be able to get free packets from the queue ! //when the mote is not synch ! ! //MAClow<->MAChigh ("virtual components") ! COMPONENT_RES_TO_IEEE802154E = 0x0a, ! COMPONENT_IEEE802154E_TO_RES = 0x0b, ! //MAChigh ! COMPONENT_RES = 0x0c, ! COMPONENT_NEIGHBORS = 0x0d, ! COMPONENT_SCHEDULE = 0x0e, ! //IPHC ! COMPONENT_OPENBRIDGE = 0x0f, ! COMPONENT_IPHC = 0x10, ! //IPv6 ! COMPONENT_FORWARDING = 0x11, ! COMPONENT_ICMPv6 = 0x12, ! COMPONENT_ICMPv6ECHO = 0x13, ! COMPONENT_ICMPv6ROUTER = 0x14, ! COMPONENT_ICMPv6RPL = 0x15, ! //TRAN ! COMPONENT_OPENTCP = 0x16, ! COMPONENT_OPENUDP = 0x17, ! COMPONENT_OPENCOAP = 0x18, ! //App test ! COMPONENT_TCPECHO = 0x19, ! COMPONENT_TCPINJECT = 0x1a, ! COMPONENT_TCPPRINT = 0x1b, ! COMPONENT_UDPECHO = 0x1c, ! COMPONENT_UDPINJECT = 0x1d, ! COMPONENT_UDPPRINT = 0x1e, ! COMPONENT_RSVP = 0x1f, ! //App ! COMPONENT_OHLONE = 0x20, ! COMPONENT_HELI = 0x21, ! COMPONENT_IMU = 0x22, ! COMPONENT_RLEDS = 0x23, ! COMPONENT_RREG = 0x24, ! COMPONENT_RWELLKNOWN = 0x25, ! COMPONENT_RT = 0x26, ! COMPONENT_REX = 0x27, ! COMPONENT_RXL1 = 0x28, ! COMPONENT_RINFO = 0x29, ! COMPONENT_RHELI = 0x2a, ! COMPONENT_RRUBE = 0x2b, ! COMPONENT_LAYERDEBUG = 0x2c, ! COMPONENT_UDPRAND = 0x2d, ! COMPONENT_UDPSTORM = 0x2e, ! COMPONENT_UDPLATENCY = 0x2f, ! COMPONENT_TEST = 0x30, ! COMPONENT_R6TUS = 0x31, ! }; ! ! /** ! \brief error codes used throughout the OpenWSN stack ! ! \note The comments are used in the Python parsing tool: ! - {0} refers to the value of the first argument, ! - {1} refers to the value of the second argument, ! */ ! enum { ! // l7 ! ERR_RCVD_ECHO_REQUEST = 0x01, // received an echo request ! ERR_RCVD_ECHO_REPLY = 0x02, // received an echo reply ! ERR_GETDATA_ASKS_TOO_FEW_BYTES = 0x03, // getData asks for too few bytes, maxNumBytes={0}, fill level={1} ! ERR_INPUT_BUFFER_OVERFLOW = 0x04, // the input buffer has overflown ! ERR_COMMAND_NOT_ALLOWED = 0x05, // the command is not allowerd, command = {0} ! // l4 ! ERR_WRONG_TRAN_PROTOCOL = 0x06, // unknown transport protocol {0} (code location {1}) ! ERR_WRONG_TCP_STATE = 0x07, // wrong TCP state {0} (code location {1}) ! ERR_TCP_RESET = 0x08, // TCP reset while in state {0} (code location {1}) ! ERR_UNSUPPORTED_PORT_NUMBER = 0x09, // unsupported port number {0} (code location {1}) ! // l3 ! ERR_UNEXPECTED_DAO = 0x0a, // unexpected DAO (code location {0}) ! ERR_UNSUPPORTED_ICMPV6_TYPE = 0x0b, // unsupported ICMPv6 type {0} (code location {1}) ! ERR_6LOWPAN_UNSUPPORTED = 0x0c, // unsupported 6LoWPAN parameter {1} at location {0} ! ERR_NO_NEXTHOP = 0x0d, // no next hop ! ERR_INVALID_PARAM = 0x0e, // invalid parameter ! ERR_INVALID_FWDMODE = 0x0f, // invalid forward mode ! ERR_LARGE_DAGRANK = 0x10, // large DAGrank {0}, set to {1} ! ERR_HOP_LIMIT_REACHED = 0x11, // packet discarded hop limit reached ! ERR_LOOP_DETECTED = 0x12, // loop detected due to previous rank {0} lower than current node rank {1} ! ERR_WRONG_DIRECTION = 0x13, // upstream packet set to be downstream, possible loop. ! // l2b ! ERR_NEIGHBORS_FULL = 0x14, // neighbors table is full (max number of neighbor is {0}) ! ERR_NO_SENT_PACKET = 0x15, // there is no sent packet in queue ! ERR_NO_RECEIVED_PACKET = 0x16, // there is no received packet in queue ! ERR_SCHEDULE_OVERFLOWN = 0x17, // schedule overflown ! // l2a ! ERR_WRONG_CELLTYPE = 0x18, // wrong celltype {0} at slotOffset {1} ! ERR_IEEE154_UNSUPPORTED = 0x19, // unsupported IEEE802.15.4 parameter {1} at location {0} ! ERR_DESYNCHRONIZED = 0x1a, // got desynchronized at slotOffset {0} ! ERR_SYNCHRONIZED = 0x1b, // synchronized at slotOffset {0} ! ERR_LARGE_TIMECORRECTION = 0x1c, // large timeCorr.: {0} ticks (code loc. {1}) ! ERR_WRONG_STATE_IN_ENDFRAME_SYNC = 0x1d, // wrong state {0} in end of frame+sync ! ERR_WRONG_STATE_IN_STARTSLOT = 0x1e, // wrong state {0} in startSlot, at slotOffset {1} ! ERR_WRONG_STATE_IN_TIMERFIRES = 0x1f, // wrong state {0} in timer fires, at slotOffset {1} ! ERR_WRONG_STATE_IN_NEWSLOT = 0x20, // wrong state {0} in start of frame, at slotOffset {1} ! ERR_WRONG_STATE_IN_ENDOFFRAME = 0x21, // wrong state {0} in end of frame, at slotOffset {1} ! ERR_MAXTXDATAPREPARE_OVERFLOW = 0x22, // maxTxDataPrepare overflows while at state {0} in slotOffset {1} ! ERR_MAXRXACKPREPARE_OVERFLOWS = 0x23, // maxRxAckPrepapare overflows while at state {0} in slotOffset {1} ! ERR_MAXRXDATAPREPARE_OVERFLOWS = 0x24, // maxRxDataPrepapre overflows while at state {0} in slotOffset {1} ! ERR_MAXTXACKPREPARE_OVERFLOWS = 0x25, // maxTxAckPrepapre overflows while at state {0} in slotOffset {1} ! ERR_WDDATADURATION_OVERFLOWS = 0x26, // wdDataDuration overflows while at state {0} in slotOffset {1} ! ERR_WDRADIO_OVERFLOWS = 0x27, // wdRadio overflows while at state {0} in slotOffset {1} ! ERR_WDRADIOTX_OVERFLOWS = 0x28, // wdRadioTx overflows while at state {0} in slotOffset {1} ! ERR_WDACKDURATION_OVERFLOWS = 0x29, // wdAckDuration overflows while at state {0} in slotOffset {1} ! // general ! ERR_BUSY_SENDING = 0x2a, // busy sending ! ERR_UNEXPECTED_SENDDONE = 0x2b, // sendDone for packet I didn't send ! ERR_NO_FREE_PACKET_BUFFER = 0x2c, // no free packet buffer (code location {0}) ! ERR_FREEING_UNUSED = 0x2d, // freeing unused memory ! ERR_FREEING_ERROR = 0x2e, // freeing memory unsupported memory ! ERR_UNSUPPORTED_COMMAND = 0x2f, // unsupported command {0} ! ERR_MSG_UNKNOWN_TYPE = 0x30, // unknown message type {0} ! ERR_WRONG_ADDR_TYPE = 0x31, // wrong address type {0} (code location {1}) ! ERR_BRIDGE_MISMATCH = 0x32, // isBridge mismatch (code location {0}) ! ERR_HEADER_TOO_LONG = 0x33, // header too long, length {1} (code location {0}) ! ERR_INPUTBUFFER_LENGTH = 0x34, // input length problem, length={0} ! ERR_BOOTED = 0x35, // booted ! ERR_INVALIDSERIALFRAME = 0x36, // invalid serial frame ! ERR_INVALIDPACKETFROMRADIO = 0x37, // invalid packet frome radio, length {1} (code location {0}) ! ERR_BUSY_RECEIVING = 0x38, // busy receiving when stop of serial activity, buffer input length {1} (code location {0}) ! ERR_WRONG_CRC_INPUT = 0x39, // wrong CRC in input Buffer (input length {0}) ! }; ! ! //=========================== typedef ========================================= ! ! ! typedef uint16_t errorparameter_t; ! typedef uint16_t dagrank_t; ! typedef uint8_t owerror_t; ! //#define bool uint8_t ! ! //PRAGMA(pack(1)); ! typedef struct { ! uint8_t byte4; ! uint16_t bytes2and3; ! uint16_t bytes0and1; ! } asn_t; ! //PRAGMA(pack()); ! ! //PRAGMA(pack(1)); ! typedef struct { // always written big endian, i.e. MSB in addr[0] ! uint8_t type; ! union { ! uint8_t addr_16b[2]; ! uint8_t addr_64b[8]; ! uint8_t addr_128b[16]; ! uint8_t panid[2]; ! uint8_t prefix[8]; ! }; ! } open_addr_t; ! //PRAGMA(pack()); ! ! typedef struct { ! //admin ! uint8_t creator; // the component which called getFreePacketBuffer() ! uint8_t owner; // the component which currently owns the entry ! uint8_t* payload; // pointer to the start of the payload within 'packet' ! uint8_t length; // length in bytes of the payload ! //l4 ! uint8_t l4_protocol; // l4 protocol to be used ! bool l4_protocol_compressed; // is the l4 protocol header compressed? ! uint16_t l4_sourcePortORicmpv6Type; // l4 source port ! uint16_t l4_destination_port; // l4 destination port ! uint8_t* l4_payload; // pointer to the start of the payload of l4 (used for retransmits) ! uint8_t l4_length; // length of the payload of l4 (used for retransmits) ! //l3 ! open_addr_t l3_destinationAdd; // 128b IPv6 destination (down stack) ! open_addr_t l3_sourceAdd; // 128b IPv6 source address ! //l2 ! owerror_t l2_sendDoneError; // outcome of trying to send this packet ! open_addr_t l2_nextORpreviousHop; // 64b IEEE802.15.4 next (down stack) or previous (up) hop address ! uint8_t l2_frameType; // beacon, data, ack, cmd ! uint8_t l2_dsn; // sequence number of the received frame ! uint8_t l2_retriesLeft; // number Tx retries left before packet dropped (dropped when hits 0) ! uint8_t l2_numTxAttempts; // number Tx attempts ! asn_t l2_asn; // at what ASN the packet was Tx'ed or Rx'ed ! uint8_t* l2_payload; // pointer to the start of the payload of l2 (used for MAC to fill in ASN in ADV) ! uint8_t* l2_ASNpayload; // pointer to the ASN in EB ! uint8_t l2_joinPriority; // the join priority received in EB ! bool l2_joinPriorityPresent; ! //l1 (drivers) ! uint8_t l1_txPower; // power for packet to Tx at ! int8_t l1_rssi; // RSSI of received packet ! uint8_t l1_lqi; // LQI of received packet ! bool l1_crc; // did received packet pass CRC check? ! //the packet ! uint8_t packet[1+1+125+2+1]; // 1B spi address, 1B length, 125B data, 2B CRC, 1B LQI ! } OpenQueueEntry_t; ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! extern void openwsn_init(void); ! ! #endif diff -crB openwsn/radio.c ../../../sys/net/openwsn/radio.c *** openwsn/radio.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/radio.c Wed Jan 15 13:48:27 2014 *************** *** 1,409 **** ! /** ! \brief CC2420-specific definition of the "radio" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "board.h" ! #include "radio.h" ! #include "cc2420.h" ! #include "spi.h" ! #include "debugpins.h" ! #include "leds.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! typedef struct { ! cc2420_status_t radioStatusByte; ! radio_state_t state; ! } radio_vars_t; ! ! radio_vars_t radio_vars; ! ! //=========================== prototypes ====================================== ! ! void radio_spiStrobe (uint8_t strobe, cc2420_status_t* statusRead); ! void radio_spiWriteReg (uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite); ! void radio_spiReadReg (uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead); ! void radio_spiWriteTxFifo( cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t lenToWrite); ! void radio_spiReadRxFifo ( cc2420_status_t* statusRead, uint8_t* bufRead, uint8_t* lenRead, uint8_t maxBufLen); ! ! //=========================== public ========================================== ! ! //===== admin ! ! void radio_init() { ! // clear variables ! memset(&radio_vars,0,sizeof(radio_vars_t)); ! ! // change state ! radio_vars.state = RADIOSTATE_STOPPED; ! ! // reset radio ! radio_reset(); ! ! // change state ! radio_vars.state = RADIOSTATE_RFOFF; ! ! // start radiotimer with dummy setting to activate SFD pin interrupt ! radiotimer_start(0xffff); ! } ! ! void radio_setOverflowCb(radiotimer_compare_cbt cb) { ! radiotimer_setOverflowCb(cb); ! } ! ! void radio_setCompareCb(radiotimer_compare_cbt cb) { ! radiotimer_setCompareCb(cb); ! } ! ! void radio_setStartFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_setStartFrameCb(cb); ! } ! ! void radio_setEndFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_setEndFrameCb(cb); ! } ! ! //===== reset ! ! void radio_reset() { ! volatile uint16_t delay; ! cc2420_MDMCTRL0_reg_t cc2420_MDMCTRL0_reg; ! cc2420_TXCTRL_reg_t cc2420_TXCTRL_reg; ! cc2420_RXCTRL1_reg_t cc2420_RXCTRL1_reg; ! ! // set radio VREG pin high ! PORT_PIN_RADIO_VREG_HIGH(); ! for (delay=0xffff;delay>0;delay--); // max. VREG start-up time is 0.6ms ! ! // set radio RESET pin low ! PORT_PIN_RADIO_RESET_LOW(); ! for (delay=0xffff;delay>0;delay--); ! ! // set radio RESET pin high ! PORT_PIN_RADIO_RESET_HIGH(); ! for (delay=0xffff;delay>0;delay--); ! ! // disable address recognition ! cc2420_MDMCTRL0_reg.PREAMBLE_LENGTH = 2; // 3 leading zero's (IEEE802.15.4 compliant) ! cc2420_MDMCTRL0_reg.AUTOACK = 0; ! cc2420_MDMCTRL0_reg.AUTOCRC = 1; ! cc2420_MDMCTRL0_reg.CCA_MODE = 3; ! cc2420_MDMCTRL0_reg.CCA_HYST = 2; ! cc2420_MDMCTRL0_reg.ADR_DECODE = 0; // turn OFF address recognition ! cc2420_MDMCTRL0_reg.PAN_COORDINATOR = 0; ! cc2420_MDMCTRL0_reg.RESERVED_FRAME_MODE = 1; // accept all frame types ! cc2420_MDMCTRL0_reg.reserved_w0 = 0; ! radio_spiWriteReg(CC2420_MDMCTRL0_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_MDMCTRL0_reg); ! ! // speed up time to TX ! cc2420_TXCTRL_reg.PA_LEVEL = 31;// max. TX power (~0dBm) ! cc2420_TXCTRL_reg.reserved_w1 = 1; ! cc2420_TXCTRL_reg.PA_CURRENT = 3; ! cc2420_TXCTRL_reg.TXMIX_CURRENT = 0; ! cc2420_TXCTRL_reg.TXMIX_CAP_ARRAY = 0; ! cc2420_TXCTRL_reg.TX_TURNAROUND = 0; // faster STXON->SFD timing (128us) ! cc2420_TXCTRL_reg.TXMIXBUF_CUR = 2; ! radio_spiWriteReg(CC2420_TXCTRL_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_TXCTRL_reg); ! ! // apply correction recommended in datasheet ! cc2420_RXCTRL1_reg.RXMIX_CURRENT = 2; ! cc2420_RXCTRL1_reg.RXMIX_VCM = 1; ! cc2420_RXCTRL1_reg.RXMIX_TAIL = 1; ! cc2420_RXCTRL1_reg.LNA_CAP_ARRAY = 1; ! cc2420_RXCTRL1_reg.MED_HGM = 0; ! cc2420_RXCTRL1_reg.HIGH_HGM = 1; ! cc2420_RXCTRL1_reg.MED_LOWGAIN = 0; ! cc2420_RXCTRL1_reg.LOW_LOWGAIN = 1; ! cc2420_RXCTRL1_reg.RXBPF_MIDCUR = 0; ! cc2420_RXCTRL1_reg.RXBPF_LOCUR = 1; // use this setting as per datasheet ! cc2420_RXCTRL1_reg.reserved_w0 = 0; ! radio_spiWriteReg(CC2420_RXCTRL1_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_RXCTRL1_reg); ! } ! ! //===== timer ! ! void radio_startTimer(uint16_t period) { ! radiotimer_start(period); ! } ! ! uint16_t radio_getTimerValue() { ! return radiotimer_getValue(); ! } ! ! void radio_setTimerPeriod(uint16_t period) { ! radiotimer_setPeriod(period); ! } ! ! uint16_t radio_getTimerPeriod() { ! return radiotimer_getPeriod(); ! } ! ! //===== RF admin ! ! void radio_setFrequency(uint8_t frequency) { ! cc2420_FSCTRL_reg_t cc2420_FSCTRL_reg; ! ! // change state ! radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; ! ! cc2420_FSCTRL_reg.FREQ = frequency-11; ! cc2420_FSCTRL_reg.FREQ *= 5; ! cc2420_FSCTRL_reg.FREQ += 357; ! cc2420_FSCTRL_reg.LOCK_STATUS = 0; ! cc2420_FSCTRL_reg.LOCK_LENGTH = 0; ! cc2420_FSCTRL_reg.CAL_RUNNING = 0; ! cc2420_FSCTRL_reg.CAL_DONE = 0; ! cc2420_FSCTRL_reg.LOCK_THR = 1; ! ! radio_spiWriteReg(CC2420_FSCTRL_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_FSCTRL_reg); ! ! // change state ! radio_vars.state = RADIOSTATE_FREQUENCY_SET; ! } ! ! void radio_rfOn() { ! radio_spiStrobe(CC2420_SXOSCON, &radio_vars.radioStatusByte); ! while (radio_vars.radioStatusByte.xosc16m_stable==0) { ! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); ! } ! } ! ! void radio_rfOff() { ! ! // change state ! radio_vars.state = RADIOSTATE_TURNING_OFF; ! ! radio_spiStrobe(CC2420_SRFOFF, &radio_vars.radioStatusByte); ! // poipoipoi wait until off ! ! // wiggle debug pin ! debugpins_radio_clr(); ! leds_radio_off(); ! ! // change state ! radio_vars.state = RADIOSTATE_RFOFF; ! } ! ! //===== TX ! ! void radio_loadPacket(uint8_t* packet, uint8_t len) { ! // change state ! radio_vars.state = RADIOSTATE_LOADING_PACKET; ! ! radio_spiStrobe(CC2420_SFLUSHTX, &radio_vars.radioStatusByte); ! radio_spiWriteTxFifo(&radio_vars.radioStatusByte, packet, len); ! ! // change state ! radio_vars.state = RADIOSTATE_PACKET_LOADED; ! } ! ! void radio_txEnable() { ! // change state ! radio_vars.state = RADIOSTATE_ENABLING_TX; ! ! // wiggle debug pin ! debugpins_radio_set(); ! leds_radio_on(); ! ! // I don't fully understand how the CC2420_STXCA the can be used here. ! ! // change state ! radio_vars.state = RADIOSTATE_TX_ENABLED; ! } ! ! void radio_txNow() { ! // change state ! radio_vars.state = RADIOSTATE_TRANSMITTING; ! ! radio_spiStrobe(CC2420_STXON, &radio_vars.radioStatusByte); ! } ! ! //===== RX ! ! void radio_rxEnable() { ! // change state ! radio_vars.state = RADIOSTATE_ENABLING_RX; ! ! // put radio in reception mode ! radio_spiStrobe(CC2420_SRXON, &radio_vars.radioStatusByte); ! radio_spiStrobe(CC2420_SFLUSHRX, &radio_vars.radioStatusByte); ! ! // wiggle debug pin ! debugpins_radio_set(); ! leds_radio_on(); ! ! // busy wait until radio really listening ! while (radio_vars.radioStatusByte.rssi_valid==0) { ! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); ! } ! ! // change state ! radio_vars.state = RADIOSTATE_LISTENING; ! } ! ! void radio_rxNow() { ! // nothing to do, the radio is already listening. ! } ! ! void radio_getReceivedFrame(uint8_t* bufRead, ! uint8_t* lenRead, ! uint8_t maxBufLen, ! int8_t* rssi, ! uint8_t* lqi, ! uint8_t* crc) { ! // read the received packet from the RXFIFO ! radio_spiReadRxFifo(&radio_vars.radioStatusByte, bufRead, lenRead, maxBufLen); ! ! // On reception, when MODEMCTRL0.AUTOCRC is set, the CC2420 replaces the ! // received CRC by: ! // - [1B] the rssi, a signed value. The actual value in dBm is that - 45. ! // - [1B] whether CRC checked (bit 7) and LQI (bit 6-0) ! *rssi = *(bufRead+*lenRead-2); ! *rssi -= 45; ! *crc = ((*(bufRead+*lenRead-1))&0x80)>>7; ! *lqi = (*(bufRead+*lenRead-1))&0x7f; ! } ! ! //=========================== private ========================================= ! ! void radio_spiStrobe(uint8_t strobe, cc2420_status_t* statusRead) { ! uint8_t spi_tx_buffer[1]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | strobe); ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_FIRSTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_FIRST, ! SPI_LAST); ! } ! ! void radio_spiWriteReg(uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite) { ! uint8_t spi_tx_buffer[3]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | reg); ! spi_tx_buffer[1] = regValueToWrite/256; ! spi_tx_buffer[2] = regValueToWrite%256; ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_FIRSTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_FIRST, ! SPI_LAST); ! } ! ! void radio_spiReadReg(uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead) { ! uint8_t spi_tx_buffer[3]; ! uint8_t spi_rx_buffer[3]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | reg); ! spi_tx_buffer[1] = 0x00; ! spi_tx_buffer[2] = 0x00; ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_BUFFER, ! spi_rx_buffer, ! sizeof(spi_rx_buffer), ! SPI_FIRST, ! SPI_LAST); ! ! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; ! *(regValueRead+0) = spi_rx_buffer[2]; ! *(regValueRead+1) = spi_rx_buffer[1]; ! } ! ! void radio_spiWriteTxFifo(cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t len) { ! uint8_t spi_tx_buffer[2]; ! ! // step 1. send SPI address and length byte ! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | CC2420_TXFIFO_ADDR); ! spi_tx_buffer[1] = len; ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_FIRSTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_FIRST, ! SPI_NOTLAST); ! ! // step 2. send payload ! spi_txrx(bufToWrite, ! len, ! SPI_LASTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_NOTFIRST, ! SPI_LAST); ! } ! ! void radio_spiReadRxFifo(cc2420_status_t* statusRead, ! uint8_t* pBufRead, ! uint8_t* pLenRead, ! uint8_t maxBufLen) { ! // when reading the packet over SPI from the RX buffer, you get the following: ! // - *[1B] dummy byte because of SPI ! // - *[1B] length byte ! // - [0-125B] packet (excluding CRC) ! // - *[2B] CRC ! uint8_t spi_tx_buffer[125]; ! uint8_t spi_rx_buffer[3]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | CC2420_RXFIFO_ADDR); ! ! // 2 first bytes ! spi_txrx(spi_tx_buffer, ! 2, ! SPI_BUFFER, ! spi_rx_buffer, ! sizeof(spi_rx_buffer), ! SPI_FIRST, ! SPI_NOTLAST); ! ! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; ! *pLenRead = spi_rx_buffer[1]; ! ! if (*pLenRead>2 && *pLenRead<=127) { ! // valid length ! ! //read packet ! spi_txrx(spi_tx_buffer, ! *pLenRead, ! SPI_BUFFER, ! pBufRead, ! 125, ! SPI_NOTFIRST, ! SPI_LAST); ! ! } else { ! // invalid length ! ! // read a just byte to close spi ! spi_txrx(spi_tx_buffer, ! 1, ! SPI_BUFFER, ! spi_rx_buffer, ! sizeof(spi_rx_buffer), ! SPI_NOTFIRST, ! SPI_LAST); ! } ! } ! ! //=========================== callbacks ======================================= --- 1,409 ---- ! /** ! \brief CC2420-specific definition of the "radio" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "board.h" ! #include "radio.h" ! #include "cc2420.h" ! #include "spi.h" ! #include "debugpins.h" ! #include "leds.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! typedef struct { ! cc2420_status_t radioStatusByte; ! radio_state_t state; ! } radio_vars_t; ! ! radio_vars_t radio_vars; ! ! //=========================== prototypes ====================================== ! ! void radio_spiStrobe (uint8_t strobe, cc2420_status_t* statusRead); ! void radio_spiWriteReg (uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite); ! void radio_spiReadReg (uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead); ! void radio_spiWriteTxFifo( cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t lenToWrite); ! void radio_spiReadRxFifo ( cc2420_status_t* statusRead, uint8_t* bufRead, uint8_t* lenRead, uint8_t maxBufLen); ! ! //=========================== public ========================================== ! ! //===== admin ! ! void radio_init(void) { ! // clear variables ! memset(&radio_vars,0,sizeof(radio_vars_t)); ! ! // change state ! radio_vars.state = RADIOSTATE_STOPPED; ! ! // reset radio ! radio_reset(); ! ! // change state ! radio_vars.state = RADIOSTATE_RFOFF; ! ! // start radiotimer with dummy setting to activate SFD pin interrupt ! radiotimer_start(0xffff); ! } ! ! void radio_setOverflowCb(radiotimer_compare_cbt cb) { ! radiotimer_setOverflowCb(cb); ! } ! ! void radio_setCompareCb(radiotimer_compare_cbt cb) { ! radiotimer_setCompareCb(cb); ! } ! ! void radio_setStartFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_setStartFrameCb(cb); ! } ! ! void radio_setEndFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_setEndFrameCb(cb); ! } ! ! //===== reset ! ! void radio_reset(void) { ! volatile uint16_t delay; ! cc2420_MDMCTRL0_reg_t cc2420_MDMCTRL0_reg; ! cc2420_TXCTRL_reg_t cc2420_TXCTRL_reg; ! cc2420_RXCTRL1_reg_t cc2420_RXCTRL1_reg; ! ! // set radio VREG pin high ! PORT_PIN_RADIO_VREG_HIGH(); ! for (delay=0xffff;delay>0;delay--); // max. VREG start-up time is 0.6ms ! ! // set radio RESET pin low ! PORT_PIN_RADIO_RESET_LOW(); ! for (delay=0xffff;delay>0;delay--); ! ! // set radio RESET pin high ! PORT_PIN_RADIO_RESET_HIGH(); ! for (delay=0xffff;delay>0;delay--); ! ! // disable address recognition ! cc2420_MDMCTRL0_reg.PREAMBLE_LENGTH = 2; // 3 leading zero's (IEEE802.15.4 compliant) ! cc2420_MDMCTRL0_reg.AUTOACK = 0; ! cc2420_MDMCTRL0_reg.AUTOCRC = 1; ! cc2420_MDMCTRL0_reg.CCA_MODE = 3; ! cc2420_MDMCTRL0_reg.CCA_HYST = 2; ! cc2420_MDMCTRL0_reg.ADR_DECODE = 0; // turn OFF address recognition ! cc2420_MDMCTRL0_reg.PAN_COORDINATOR = 0; ! cc2420_MDMCTRL0_reg.RESERVED_FRAME_MODE = 1; // accept all frame types ! cc2420_MDMCTRL0_reg.reserved_w0 = 0; ! radio_spiWriteReg(CC2420_MDMCTRL0_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_MDMCTRL0_reg); ! ! // speed up time to TX ! cc2420_TXCTRL_reg.PA_LEVEL = 31;// max. TX power (~0dBm) ! cc2420_TXCTRL_reg.reserved_w1 = 1; ! cc2420_TXCTRL_reg.PA_CURRENT = 3; ! cc2420_TXCTRL_reg.TXMIX_CURRENT = 0; ! cc2420_TXCTRL_reg.TXMIX_CAP_ARRAY = 0; ! cc2420_TXCTRL_reg.TX_TURNAROUND = 0; // faster STXON->SFD timing (128us) ! cc2420_TXCTRL_reg.TXMIXBUF_CUR = 2; ! radio_spiWriteReg(CC2420_TXCTRL_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_TXCTRL_reg); ! ! // apply correction recommended in datasheet ! cc2420_RXCTRL1_reg.RXMIX_CURRENT = 2; ! cc2420_RXCTRL1_reg.RXMIX_VCM = 1; ! cc2420_RXCTRL1_reg.RXMIX_TAIL = 1; ! cc2420_RXCTRL1_reg.LNA_CAP_ARRAY = 1; ! cc2420_RXCTRL1_reg.MED_HGM = 0; ! cc2420_RXCTRL1_reg.HIGH_HGM = 1; ! cc2420_RXCTRL1_reg.MED_LOWGAIN = 0; ! cc2420_RXCTRL1_reg.LOW_LOWGAIN = 1; ! cc2420_RXCTRL1_reg.RXBPF_MIDCUR = 0; ! cc2420_RXCTRL1_reg.RXBPF_LOCUR = 1; // use this setting as per datasheet ! cc2420_RXCTRL1_reg.reserved_w0 = 0; ! radio_spiWriteReg(CC2420_RXCTRL1_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_RXCTRL1_reg); ! } ! ! //===== timer ! ! void radio_startTimer(uint16_t period) { ! radiotimer_start(period); ! } ! ! uint16_t radio_getTimerValue(void) { ! return radiotimer_getValue(); ! } ! ! void radio_setTimerPeriod(uint16_t period) { ! radiotimer_setPeriod(period); ! } ! ! uint16_t radio_getTimerPeriod(void) { ! return radiotimer_getPeriod(); ! } ! ! //===== RF admin ! ! void radio_setFrequency(uint8_t frequency) { ! cc2420_FSCTRL_reg_t cc2420_FSCTRL_reg; ! ! // change state ! radio_vars.state = RADIOSTATE_SETTING_FREQUENCY; ! ! cc2420_FSCTRL_reg.FREQ = frequency-11; ! cc2420_FSCTRL_reg.FREQ *= 5; ! cc2420_FSCTRL_reg.FREQ += 357; ! cc2420_FSCTRL_reg.LOCK_STATUS = 0; ! cc2420_FSCTRL_reg.LOCK_LENGTH = 0; ! cc2420_FSCTRL_reg.CAL_RUNNING = 0; ! cc2420_FSCTRL_reg.CAL_DONE = 0; ! cc2420_FSCTRL_reg.LOCK_THR = 1; ! ! radio_spiWriteReg(CC2420_FSCTRL_ADDR, ! &radio_vars.radioStatusByte, ! *(uint16_t*)&cc2420_FSCTRL_reg); ! ! // change state ! radio_vars.state = RADIOSTATE_FREQUENCY_SET; ! } ! ! void radio_rfOn(void) { ! radio_spiStrobe(CC2420_SXOSCON, &radio_vars.radioStatusByte); ! while (radio_vars.radioStatusByte.xosc16m_stable==0) { ! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); ! } ! } ! ! void radio_rfOff(void) { ! ! // change state ! radio_vars.state = RADIOSTATE_TURNING_OFF; ! ! radio_spiStrobe(CC2420_SRFOFF, &radio_vars.radioStatusByte); ! // poipoipoi wait until off ! ! // wiggle debug pin ! debugpins_radio_clr(); ! leds_radio_off(); ! ! // change state ! radio_vars.state = RADIOSTATE_RFOFF; ! } ! ! //===== TX ! ! void radio_loadPacket(uint8_t* packet, uint8_t len) { ! // change state ! radio_vars.state = RADIOSTATE_LOADING_PACKET; ! ! radio_spiStrobe(CC2420_SFLUSHTX, &radio_vars.radioStatusByte); ! radio_spiWriteTxFifo(&radio_vars.radioStatusByte, packet, len); ! ! // change state ! radio_vars.state = RADIOSTATE_PACKET_LOADED; ! } ! ! void radio_txEnable(void) { ! // change state ! radio_vars.state = RADIOSTATE_ENABLING_TX; ! ! // wiggle debug pin ! debugpins_radio_set(); ! leds_radio_on(); ! ! // I don't fully understand how the CC2420_STXCA the can be used here. ! ! // change state ! radio_vars.state = RADIOSTATE_TX_ENABLED; ! } ! ! void radio_txNow(void) { ! // change state ! radio_vars.state = RADIOSTATE_TRANSMITTING; ! ! radio_spiStrobe(CC2420_STXON, &radio_vars.radioStatusByte); ! } ! ! //===== RX ! ! void radio_rxEnable(void) { ! // change state ! radio_vars.state = RADIOSTATE_ENABLING_RX; ! ! // put radio in reception mode ! radio_spiStrobe(CC2420_SRXON, &radio_vars.radioStatusByte); ! radio_spiStrobe(CC2420_SFLUSHRX, &radio_vars.radioStatusByte); ! ! // wiggle debug pin ! debugpins_radio_set(); ! leds_radio_on(); ! ! // busy wait until radio really listening ! while (radio_vars.radioStatusByte.rssi_valid==0) { ! radio_spiStrobe(CC2420_SNOP, &radio_vars.radioStatusByte); ! } ! ! // change state ! radio_vars.state = RADIOSTATE_LISTENING; ! } ! ! void radio_rxNow(void) { ! // nothing to do, the radio is already listening. ! } ! ! void radio_getReceivedFrame(uint8_t* bufRead, ! uint8_t* lenRead, ! uint8_t maxBufLen, ! int8_t* rssi, ! uint8_t* lqi, ! uint8_t* crc) { ! // read the received packet from the RXFIFO ! radio_spiReadRxFifo(&radio_vars.radioStatusByte, bufRead, lenRead, maxBufLen); ! ! // On reception, when MODEMCTRL0.AUTOCRC is set, the CC2420 replaces the ! // received CRC by: ! // - [1B] the rssi, a signed value. The actual value in dBm is that - 45. ! // - [1B] whether CRC checked (bit 7) and LQI (bit 6-0) ! *rssi = *(bufRead+*lenRead-2); ! *rssi -= 45; ! *crc = ((*(bufRead+*lenRead-1))&0x80)>>7; ! *lqi = (*(bufRead+*lenRead-1))&0x7f; ! } ! ! //=========================== private ========================================= ! ! void radio_spiStrobe(uint8_t strobe, cc2420_status_t* statusRead) { ! uint8_t spi_tx_buffer[1]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | strobe); ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_FIRSTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_FIRST, ! SPI_LAST); ! } ! ! void radio_spiWriteReg(uint8_t reg, cc2420_status_t* statusRead, uint16_t regValueToWrite) { ! uint8_t spi_tx_buffer[3]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | reg); ! spi_tx_buffer[1] = regValueToWrite/256; ! spi_tx_buffer[2] = regValueToWrite%256; ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_FIRSTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_FIRST, ! SPI_LAST); ! } ! ! void radio_spiReadReg(uint8_t reg, cc2420_status_t* statusRead, uint8_t* regValueRead) { ! uint8_t spi_tx_buffer[3]; ! uint8_t spi_rx_buffer[3]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | reg); ! spi_tx_buffer[1] = 0x00; ! spi_tx_buffer[2] = 0x00; ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_BUFFER, ! spi_rx_buffer, ! sizeof(spi_rx_buffer), ! SPI_FIRST, ! SPI_LAST); ! ! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; ! *(regValueRead+0) = spi_rx_buffer[2]; ! *(regValueRead+1) = spi_rx_buffer[1]; ! } ! ! void radio_spiWriteTxFifo(cc2420_status_t* statusRead, uint8_t* bufToWrite, uint8_t len) { ! uint8_t spi_tx_buffer[2]; ! ! // step 1. send SPI address and length byte ! spi_tx_buffer[0] = (CC2420_FLAG_WRITE | CC2420_FLAG_REG | CC2420_TXFIFO_ADDR); ! spi_tx_buffer[1] = len; ! ! spi_txrx(spi_tx_buffer, ! sizeof(spi_tx_buffer), ! SPI_FIRSTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_FIRST, ! SPI_NOTLAST); ! ! // step 2. send payload ! spi_txrx(bufToWrite, ! len, ! SPI_LASTBYTE, ! (uint8_t*)statusRead, ! 1, ! SPI_NOTFIRST, ! SPI_LAST); ! } ! ! void radio_spiReadRxFifo(cc2420_status_t* statusRead, ! uint8_t* pBufRead, ! uint8_t* pLenRead, ! uint8_t maxBufLen) { ! // when reading the packet over SPI from the RX buffer, you get the following: ! // - *[1B] dummy byte because of SPI ! // - *[1B] length byte ! // - [0-125B] packet (excluding CRC) ! // - *[2B] CRC ! uint8_t spi_tx_buffer[125]; ! uint8_t spi_rx_buffer[3]; ! ! spi_tx_buffer[0] = (CC2420_FLAG_READ | CC2420_FLAG_REG | CC2420_RXFIFO_ADDR); ! ! // 2 first bytes ! spi_txrx(spi_tx_buffer, ! 2, ! SPI_BUFFER, ! spi_rx_buffer, ! sizeof(spi_rx_buffer), ! SPI_FIRST, ! SPI_NOTLAST); ! ! *statusRead = *(cc2420_status_t*)&spi_rx_buffer[0]; ! *pLenRead = spi_rx_buffer[1]; ! ! if (*pLenRead>2 && *pLenRead<=127) { ! // valid length ! ! //read packet ! spi_txrx(spi_tx_buffer, ! *pLenRead, ! SPI_BUFFER, ! pBufRead, ! 125, ! SPI_NOTFIRST, ! SPI_LAST); ! ! } else { ! // invalid length ! ! // read a just byte to close spi ! spi_txrx(spi_tx_buffer, ! 1, ! SPI_BUFFER, ! spi_rx_buffer, ! sizeof(spi_rx_buffer), ! SPI_NOTFIRST, ! SPI_LAST); ! } ! } ! ! //=========================== callbacks ======================================= diff -crB openwsn/radio.h ../../../sys/net/openwsn/radio.h *** openwsn/radio.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/radio.h Wed Jan 15 13:48:27 2014 *************** *** 1,80 **** ! /** ! \brief Cross-platform declaration "radio" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __RADIO_H ! #define __RADIO_H ! ! #include "radiotimer.h" ! ! //=========================== define ========================================== ! ! #define LENGTH_CRC 2 ! ! /** ! \brief Current state of the radio. ! ! \note This radio driver is very minimal in that it does not follow a state machine. ! It is up to the MAC layer to ensure that the different radio operations ! are called in the righr order. The radio keeps a state for debugging purposes only. ! */ ! typedef enum { ! RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. ! RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. ! RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. ! RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. ! RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. ! RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. ! RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). ! RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. ! RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. ! RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). ! RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. ! RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. ! RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. ! RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. ! } radio_state_t; ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void radio_init(); ! void radio_setOverflowCb(radiotimer_compare_cbt cb); ! void radio_setCompareCb(radiotimer_compare_cbt cb); ! void radio_setStartFrameCb(radiotimer_capture_cbt cb); ! void radio_setEndFrameCb(radiotimer_capture_cbt cb); ! // reset ! void radio_reset(); ! // timer ! void radio_startTimer(PORT_TIMER_WIDTH period); ! PORT_TIMER_WIDTH radio_getTimerValue(); ! void radio_setTimerPeriod(PORT_TIMER_WIDTH period); ! PORT_TIMER_WIDTH radio_getTimerPeriod(); ! // RF admin ! void radio_setFrequency(uint8_t frequency); ! void radio_rfOn(); ! void radio_rfOff(); ! // TX ! void radio_loadPacket(uint8_t* packet, uint8_t len); ! void radio_txEnable(); ! void radio_txNow(); ! // RX ! void radio_rxEnable(); ! void radio_rxNow(); ! void radio_getReceivedFrame(uint8_t* bufRead, ! uint8_t* lenRead, ! uint8_t maxBufLen, ! int8_t* rssi, ! uint8_t* lqi, ! uint8_t* crc); ! ! // interrupt handlers ! kick_scheduler_t radio_isr(); ! ! #endif --- 1,90 ---- ! #ifndef __RADIO_H ! #define __RADIO_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup radio ! \{ ! ! \brief Cross-platform declaration "radio" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "radiotimer.h" ! ! //=========================== define ========================================== ! ! #define LENGTH_CRC 2 ! ! /** ! \brief Current state of the radio. ! ! \note This radio driver is very minimal in that it does not follow a state machine. ! It is up to the MAC layer to ensure that the different radio operations ! are called in the righr order. The radio keeps a state for debugging purposes only. ! */ ! typedef enum { ! RADIOSTATE_STOPPED = 0x00, ///< Completely stopped. ! RADIOSTATE_RFOFF = 0x01, ///< Listening for commands, but RF chain is off. ! RADIOSTATE_SETTING_FREQUENCY = 0x02, ///< Configuring the frequency. ! RADIOSTATE_FREQUENCY_SET = 0x03, ///< Done configuring the frequency. ! RADIOSTATE_LOADING_PACKET = 0x04, ///< Loading packet into the radio's TX buffer. ! RADIOSTATE_PACKET_LOADED = 0x05, ///< Packet is fully loaded in the radio's TX buffer. ! RADIOSTATE_ENABLING_TX = 0x06, ///< The RF TX chaing is being enabled (includes locking the PLL). ! RADIOSTATE_TX_ENABLED = 0x07, ///< Radio ready to transmit. ! RADIOSTATE_TRANSMITTING = 0x08, ///< Busy transmitting bytes. ! RADIOSTATE_ENABLING_RX = 0x09, ///< The RF RX chain is being enabled (includes locking the PLL). ! RADIOSTATE_LISTENING = 0x0a, ///< RF chain is on, listening, but no packet received yet. ! RADIOSTATE_RECEIVING = 0x0b, ///< Busy receiving bytes. ! RADIOSTATE_TXRX_DONE = 0x0c, ///< Frame has been sent/received completely. ! RADIOSTATE_TURNING_OFF = 0x0d, ///< Turning the RF chain off. ! } radio_state_t; ! ! //=========================== typedef ========================================= ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void radio_init(void); ! void radio_setOverflowCb(radiotimer_compare_cbt cb); ! void radio_setCompareCb(radiotimer_compare_cbt cb); ! void radio_setStartFrameCb(radiotimer_capture_cbt cb); ! void radio_setEndFrameCb(radiotimer_capture_cbt cb); ! // reset ! void radio_reset(void); ! // timer ! void radio_startTimer(PORT_TIMER_WIDTH period); ! PORT_TIMER_WIDTH radio_getTimerValue(void); ! void radio_setTimerPeriod(PORT_TIMER_WIDTH period); ! PORT_TIMER_WIDTH radio_getTimerPeriod(void); ! // RF admin ! void radio_setFrequency(uint8_t frequency); ! void radio_rfOn(void); ! void radio_rfOff(void); ! // TX ! void radio_loadPacket(uint8_t* packet, uint8_t len); ! void radio_txEnable(void); ! void radio_txNow(void); ! // RX ! void radio_rxEnable(void); ! void radio_rxNow(void); ! void radio_getReceivedFrame(uint8_t* bufRead, ! uint8_t* lenRead, ! uint8_t maxBufLen, ! int8_t* rssi, ! uint8_t* lqi, ! uint8_t* crc); ! ! // interrupt handlers ! kick_scheduler_t radio_isr(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/radiotimer.c ../../../sys/net/openwsn/radiotimer.c *** openwsn/radiotimer.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/radiotimer.c Wed Jan 15 13:48:27 2014 *************** *** 1,176 **** ! /** ! \brief TelosB-specific definition of the "radiotimer" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "radiotimer.h" ! #include "leds.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! radiotimer_compare_cbt overflowCb; ! radiotimer_compare_cbt compareCb; ! radiotimer_capture_cbt startFrameCb; ! radiotimer_capture_cbt endFrameCb; ! } radiotimer_vars_t; ! ! radiotimer_vars_t radiotimer_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! //===== admin ! ! void radiotimer_init() { ! // clear local variables ! memset(&radiotimer_vars,0,sizeof(radiotimer_vars_t)); ! } ! ! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb) { ! radiotimer_vars.overflowCb = cb; ! } ! ! void radiotimer_setCompareCb(radiotimer_compare_cbt cb) { ! radiotimer_vars.compareCb = cb; ! } ! ! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_vars.startFrameCb = cb; ! } ! ! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_vars.endFrameCb = cb; ! } ! ! void radiotimer_start(uint16_t period) { ! // radio's SFD pin connected to P4.1 ! P4DIR &= ~0x02; // input ! P4SEL |= 0x02; // in CCI1a/B mode ! ! // CCR0 contains period of counter ! // do not interrupt when counter reaches TBCCR0, but when it resets ! TBCCR0 = period-1; ! ! // CCR1 in capture mode ! TBCCTL1 = CM_3+SCS+CAP+CCIE; ! TBCCR1 = 0; ! ! // CCR2 in compare mode (disabled for now) ! TBCCTL2 = 0; ! TBCCR2 = 0; ! ! // start counting ! TBCTL = TBIE+TBCLR; // interrupt when counter resets ! TBCTL |= MC_1+TBSSEL_1; // up mode, clocked from ACLK ! } ! ! //===== direct access ! ! uint16_t radiotimer_getValue() { ! return TBR; ! } ! ! void radiotimer_setPeriod(uint16_t period) { ! TBCCR0 = period; ! } ! ! uint16_t radiotimer_getPeriod() { ! return TBCCR0; ! } ! ! //===== compare ! ! void radiotimer_schedule(uint16_t offset) { ! // offset when to fire ! TBCCR2 = offset; ! ! // enable compare interrupt (this also cancels any pending interrupts) ! TBCCTL2 = CCIE; ! } ! ! void radiotimer_cancel() { ! // reset compare value (also resets interrupt flag) ! TBCCR2 = 0; ! ! // disable compare interrupt ! TBCCTL2 &= ~CCIE; ! } ! ! //===== capture ! ! inline uint16_t radiotimer_getCapturedTime() { ! // this should never happpen! ! ! // we can not print from within the BSP. Instead: ! // blink the error LED ! leds_error_blink(); ! // reset the board ! board_reset(); ! ! return 0;// this line is never reached, but here to satisfy compiler ! } ! ! //=========================== private ========================================= ! ! //=========================== interrupt handlers ============================== ! ! /** ! \brief TimerB CCR1-6 interrupt service routine ! */ ! kick_scheduler_t radiotimer_isr() { ! uint16_t tbiv_local; ! ! // reading TBIV returns the value of the highest pending interrupt flag ! // and automatically resets that flag. We therefore copy its value to the ! // tbiv_local local variable exactly once. If there is more than one ! // interrupt pending, we will reenter this function after having just left ! // it. ! tbiv_local = TBIV; ! ! switch (tbiv_local) { ! case 0x0002: // CCR1 fires ! if (TBCCTL1 & CCI) { ! // SFD pin is high: this was the start of a frame ! if (radiotimer_vars.startFrameCb!=NULL) { ! radiotimer_vars.startFrameCb(TBCCR1); ! // kick the OS ! return KICK_SCHEDULER; ! } ! } else { ! // SFD pin is low: this was the end of a frame ! if (radiotimer_vars.endFrameCb!=NULL) { ! radiotimer_vars.endFrameCb(TBCCR1); ! // kick the OS ! return KICK_SCHEDULER; ! } ! } ! break; ! case 0x0004: // CCR2 fires ! if (radiotimer_vars.compareCb!=NULL) { ! radiotimer_vars.compareCb(); ! // kick the OS ! return KICK_SCHEDULER; ! } ! break; ! case 0x0006: // CCR3 fires ! break; ! case 0x0008: // CCR4 fires ! break; ! case 0x000a: // CCR5 fires ! break; ! case 0x000c: // CCR6 fires ! break; ! case 0x000e: // timer overflow ! if (radiotimer_vars.overflowCb!=NULL) { ! radiotimer_vars.overflowCb(); ! // kick the OS ! return KICK_SCHEDULER; ! } ! break; ! } ! return DO_NOT_KICK_SCHEDULER; ! } --- 1,176 ---- ! /** ! \brief TelosB-specific definition of the "radiotimer" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "radiotimer.h" ! #include "leds.h" ! ! //=========================== variables ======================================= ! ! typedef struct { ! radiotimer_compare_cbt overflowCb; ! radiotimer_compare_cbt compareCb; ! radiotimer_capture_cbt startFrameCb; ! radiotimer_capture_cbt endFrameCb; ! } radiotimer_vars_t; ! ! radiotimer_vars_t radiotimer_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! //===== admin ! ! void radiotimer_init(void) { ! // clear local variables ! memset(&radiotimer_vars,0,sizeof(radiotimer_vars_t)); ! } ! ! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb) { ! radiotimer_vars.overflowCb = cb; ! } ! ! void radiotimer_setCompareCb(radiotimer_compare_cbt cb) { ! radiotimer_vars.compareCb = cb; ! } ! ! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_vars.startFrameCb = cb; ! } ! ! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb) { ! radiotimer_vars.endFrameCb = cb; ! } ! ! void radiotimer_start(PORT_RADIOTIMER_WIDTH period) { ! // radio's SFD pin connected to P4.1 ! P4DIR &= ~0x02; // input ! P4SEL |= 0x02; // in CCI1a/B mode ! ! // CCR0 contains period of counter ! // do not interrupt when counter reaches TBCCR0, but when it resets ! TBCCR0 = period-1; ! ! // CCR1 in capture mode ! TBCCTL1 = CM_3+SCS+CAP+CCIE; ! TBCCR1 = 0; ! ! // CCR2 in compare mode (disabled for now) ! TBCCTL2 = 0; ! TBCCR2 = 0; ! ! // start counting ! TBCTL = TBIE+TBCLR; // interrupt when counter resets ! TBCTL |= MC_1+TBSSEL_1; // up mode, clocked from ACLK ! } ! ! //===== direct access ! ! PORT_RADIOTIMER_WIDTH radiotimer_getValue(void) { ! return TBR; ! } ! ! void radiotimer_setPeriod(PORT_RADIOTIMER_WIDTH period) { ! TBCCR0 = period; ! } ! ! PORT_RADIOTIMER_WIDTH radiotimer_getPeriod(void) { ! return TBCCR0; ! } ! ! //===== compare ! ! void radiotimer_schedule(PORT_RADIOTIMER_WIDTH offset) { ! // offset when to fire ! TBCCR2 = offset; ! ! // enable compare interrupt (this also cancels any pending interrupts) ! TBCCTL2 = CCIE; ! } ! ! void radiotimer_cancel(void) { ! // reset compare value (also resets interrupt flag) ! TBCCR2 = 0; ! ! // disable compare interrupt ! TBCCTL2 &= ~CCIE; ! } ! ! //===== capture ! ! inline PORT_RADIOTIMER_WIDTH radiotimer_getCapturedTime(void) { ! // this should never happpen! ! ! // we can not print from within the BSP. Instead: ! // blink the error LED ! leds_error_blink(); ! // reset the board ! board_reset(); ! ! return 0;// this line is never reached, but here to satisfy compiler ! } ! ! //=========================== private ========================================= ! ! //=========================== interrupt handlers ============================== ! ! /** ! \brief TimerB CCR1-6 interrupt service routine ! */ ! kick_scheduler_t radiotimer_isr(void) { ! PORT_RADIOTIMER_WIDTH tbiv_local; ! ! // reading TBIV returns the value of the highest pending interrupt flag ! // and automatically resets that flag. We therefore copy its value to the ! // tbiv_local local variable exactly once. If there is more than one ! // interrupt pending, we will reenter this function after having just left ! // it. ! tbiv_local = TBIV; ! ! switch (tbiv_local) { ! case 0x0002: // CCR1 fires ! if (TBCCTL1 & CCI) { ! // SFD pin is high: this was the start of a frame ! if (radiotimer_vars.startFrameCb!=NULL) { ! radiotimer_vars.startFrameCb(TBCCR1); ! // kick the OS ! return KICK_SCHEDULER; ! } ! } else { ! // SFD pin is low: this was the end of a frame ! if (radiotimer_vars.endFrameCb!=NULL) { ! radiotimer_vars.endFrameCb(TBCCR1); ! // kick the OS ! return KICK_SCHEDULER; ! } ! } ! break; ! case 0x0004: // CCR2 fires ! if (radiotimer_vars.compareCb!=NULL) { ! radiotimer_vars.compareCb(); ! // kick the OS ! return KICK_SCHEDULER; ! } ! break; ! case 0x0006: // CCR3 fires ! break; ! case 0x0008: // CCR4 fires ! break; ! case 0x000a: // CCR5 fires ! break; ! case 0x000c: // CCR6 fires ! break; ! case 0x000e: // timer overflow ! if (radiotimer_vars.overflowCb!=NULL) { ! radiotimer_vars.overflowCb(); ! // kick the OS ! return KICK_SCHEDULER; ! } ! break; ! } ! return DO_NOT_KICK_SCHEDULER; ! } diff -crB openwsn/radiotimer.h ../../../sys/net/openwsn/radiotimer.h *** openwsn/radiotimer.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/radiotimer.h Wed Jan 15 13:48:27 2014 *************** *** 1,44 **** ! /** ! \brief Cross-platform declaration "radiotimer" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __RADIOTIMER_H ! #define __RADIOTIMER_H ! ! #include "stdint.h" ! #include "board.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! typedef void (*radiotimer_compare_cbt)(); ! typedef void (*radiotimer_capture_cbt)(PORT_TIMER_WIDTH timestamp); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void radiotimer_init(); ! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb); ! void radiotimer_setCompareCb(radiotimer_compare_cbt cb); ! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb); ! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb); ! void radiotimer_start(PORT_TIMER_WIDTH period); ! // direct access ! PORT_TIMER_WIDTH radiotimer_getValue(); ! void radiotimer_setPeriod(PORT_TIMER_WIDTH period); ! PORT_TIMER_WIDTH radiotimer_getPeriod(); ! // compare ! void radiotimer_schedule(PORT_TIMER_WIDTH offset); ! void radiotimer_cancel(); ! // capture ! PORT_TIMER_WIDTH radiotimer_getCapturedTime(); ! ! // interrupt handlers ! kick_scheduler_t radiotimer_isr(); ! ! #endif --- 1,54 ---- ! #ifndef __RADIOTIMER_H ! #define __RADIOTIMER_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup radiotimer ! \{ ! ! \brief Cross-platform declaration "radiotimer" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "stdint.h" ! #include "board_ow.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! typedef void (*radiotimer_compare_cbt)(void); ! typedef void (*radiotimer_capture_cbt)(PORT_TIMER_WIDTH timestamp); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // admin ! void radiotimer_init(void); ! void radiotimer_setOverflowCb(radiotimer_compare_cbt cb); ! void radiotimer_setCompareCb(radiotimer_compare_cbt cb); ! void radiotimer_setStartFrameCb(radiotimer_capture_cbt cb); ! void radiotimer_setEndFrameCb(radiotimer_capture_cbt cb); ! void radiotimer_start(PORT_RADIOTIMER_WIDTH period); ! // direct access ! PORT_RADIOTIMER_WIDTH radiotimer_getValue(void); ! void radiotimer_setPeriod(PORT_RADIOTIMER_WIDTH period); ! PORT_RADIOTIMER_WIDTH radiotimer_getPeriod(void); ! // compare ! void radiotimer_schedule(PORT_RADIOTIMER_WIDTH offset); ! void radiotimer_cancel(void); ! // capture ! PORT_RADIOTIMER_WIDTH radiotimer_getCapturedTime(void); ! ! // interrupt handlers ! kick_scheduler_t radiotimer_isr(void); ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/scheduler.c ../../../sys/net/openwsn/scheduler.c *** openwsn/scheduler.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/scheduler.c Wed Jan 15 13:48:27 2014 *************** *** 1,124 **** ! /** ! \brief OpenOS scheduler. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "openwsn.h" ! #include "scheduler.h" ! #include "board.h" ! #include "debugpins.h" ! #include "leds.h" ! ! //=========================== variables ======================================= ! ! typedef struct task_llist_t { ! task_cbt cb; ! task_prio_t prio; ! void* next; ! } taskList_item_t; ! ! typedef struct { ! taskList_item_t taskBuf[TASK_LIST_DEPTH]; ! taskList_item_t* task_list; ! uint8_t numTasksCur; ! uint8_t numTasksMax; ! } scheduler_vars_t; ! ! scheduler_vars_t scheduler_vars; ! ! typedef struct { ! uint8_t numTasksCur; ! uint8_t numTasksMax; ! } scheduler_dbg_t; ! ! scheduler_dbg_t scheduler_dbg; ! ! //=========================== prototypes ====================================== ! ! void consumeTask(uint8_t taskId); ! ! //=========================== public ========================================== ! ! void scheduler_init() { ! ! // initialization module variables ! memset(&scheduler_vars,0,sizeof(scheduler_vars_t)); ! memset(&scheduler_dbg,0,sizeof(scheduler_dbg_t)); ! ! // enable the scheduler's interrupt so SW can wake up the scheduler ! SCHEDULER_ENABLE_INTERRUPT(); ! } ! ! void scheduler_start() { ! taskList_item_t* pThisTask; ! while (1) { ! while(scheduler_vars.task_list!=NULL) { ! // there is still at least one task in the linked-list of tasks ! ! // the task to execute is the one at the head of the queue ! pThisTask = scheduler_vars.task_list; ! ! // shift the queue by one task ! scheduler_vars.task_list = pThisTask->next; ! ! // execute the current task ! pThisTask->cb(); ! ! // free up this task container ! pThisTask->cb = NULL; ! pThisTask->prio = TASKPRIO_NONE; ! pThisTask->next = NULL; ! scheduler_dbg.numTasksCur--; ! } ! debugpins_task_clr(); ! board_sleep(); ! debugpins_task_set(); // IAR should halt here if nothing to do ! } ! } ! ! void scheduler_push_task(task_cbt cb, task_prio_t prio) { ! taskList_item_t* taskContainer; ! taskList_item_t** taskListWalker; ! INTERRUPT_DECLARATION(); ! ! DISABLE_INTERRUPTS(); ! ! // find an empty task container ! taskContainer = &scheduler_vars.taskBuf[0]; ! while (taskContainer->cb!=NULL && ! taskContainer<=&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { ! taskContainer++; ! } ! if (taskContainer>&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { ! // task list has overflown. This should never happpen! ! ! // we can not print from within the kernel. Instead: ! // blink the error LED ! leds_error_blink(); ! // reset the board ! board_reset(); ! } ! // fill that task container with this task ! taskContainer->cb = cb; ! taskContainer->prio = prio; ! ! // find position in queue ! taskListWalker = &scheduler_vars.task_list; ! while (*taskListWalker!=NULL && ! (*taskListWalker)->prio < taskContainer->prio) { ! taskListWalker = (taskList_item_t**)&((*taskListWalker)->next); ! } ! // insert at that position ! taskContainer->next = *taskListWalker; ! *taskListWalker = taskContainer; ! // maintain debug stats ! scheduler_dbg.numTasksCur++; ! if (scheduler_dbg.numTasksCur>scheduler_dbg.numTasksMax) { ! scheduler_dbg.numTasksMax = scheduler_dbg.numTasksCur; ! } ! ! ENABLE_INTERRUPTS(); ! } ! ! //=========================== private ========================================= --- 1,108 ---- ! /** ! \brief OpenOS scheduler. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "openwsn.h" ! #include "scheduler.h" ! #include "board.h" ! #include "debugpins.h" ! #include "leds.h" ! ! //=========================== variables ======================================= ! ! scheduler_vars_t scheduler_vars; ! scheduler_dbg_t scheduler_dbg; ! ! //=========================== prototypes ====================================== ! ! void consumeTask(uint8_t taskId); ! ! //=========================== public ========================================== ! ! void scheduler_init() { ! // initialization module variables ! memset(&scheduler_vars,0,sizeof(scheduler_vars_t)); ! memset(&scheduler_dbg,0,sizeof(scheduler_dbg_t)); ! ! // enable the scheduler's interrupt so SW can wake up the scheduler ! //SCHEDULER_ENABLE_INTERRUPT(); ! puts(__PRETTY_FUNCTION__); ! } ! ! void scheduler_start() { ! puts(__PRETTY_FUNCTION__); ! taskList_item_t* pThisTask; ! while (1) { ! while(scheduler_vars.task_list!=NULL) { ! // there is still at least one task in the linked-list of tasks ! ! // the task to execute is the one at the head of the queue ! pThisTask = scheduler_vars.task_list; ! printf("run task %p with prio %d\n", pThisTask->cb, pThisTask->prio); ! // shift the queue by one task ! scheduler_vars.task_list = pThisTask->next; ! ! // execute the current task ! pThisTask->cb(); ! ! // free up this task container ! pThisTask->cb = NULL; ! pThisTask->prio = TASKPRIO_NONE; ! pThisTask->next = NULL; ! scheduler_dbg.numTasksCur--; ! } ! //debugpins_task_clr(); ! board_sleep(); ! //debugpins_task_set(); // IAR should halt here if nothing to do ! } ! puts("leaving... WTF?!"); ! } ! ! void scheduler_push_task(task_cbt cb, task_prio_t prio) { ! puts(__PRETTY_FUNCTION__); ! taskList_item_t* taskContainer; ! taskList_item_t** taskListWalker; ! INTERRUPT_DECLARATION(); ! ! DISABLE_INTERRUPTS(); ! ! // find an empty task container ! taskContainer = &scheduler_vars.taskBuf[0]; ! while (taskContainer->cb!=NULL && ! taskContainer<=&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { ! taskContainer++; ! } ! if (taskContainer>&scheduler_vars.taskBuf[TASK_LIST_DEPTH-1]) { ! // task list has overflown. This should never happpen! ! ! // we can not print from within the kernel. Instead: ! // blink the error LED ! leds_error_blink(); ! // reset the board ! board_reset(); ! } ! // fill that task container with this task ! taskContainer->cb = cb; ! taskContainer->prio = prio; ! ! // find position in queue ! taskListWalker = &scheduler_vars.task_list; ! while (*taskListWalker!=NULL && ! (*taskListWalker)->prio < taskContainer->prio) { ! taskListWalker = (taskList_item_t**)&((*taskListWalker)->next); ! } ! // insert at that position ! taskContainer->next = *taskListWalker; ! *taskListWalker = taskContainer; ! // maintain debug stats ! scheduler_dbg.numTasksCur++; ! if (scheduler_dbg.numTasksCur>scheduler_dbg.numTasksMax) { ! scheduler_dbg.numTasksMax = scheduler_dbg.numTasksCur; ! } ! ! ENABLE_INTERRUPTS(); ! } ! ! //=========================== private ========================================= diff -crB openwsn/scheduler.h ../../../sys/net/openwsn/scheduler.h *** openwsn/scheduler.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/scheduler.h Wed Jan 15 13:48:27 2014 *************** *** 1,64 **** ! #ifndef __SCHEDULER_H ! #define __SCHEDULER_H ! ! /** ! \addtogroup drivers ! \{ ! \addtogroup Scheduler ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! typedef enum { ! TASKPRIO_NONE = 0x00, ! // tasks trigger by radio ! TASKPRIO_RESNOTIF_RX = 0x01, // scheduled by IEEE802.15.4e ! TASKPRIO_RESNOTIF_TXDONE = 0x02, // scheduled by IEEE802.15.4e ! // tasks triggered by timers ! TASKPRIO_RES = 0x03, // scheduled by timerB CCR0 interrupt ! TASKPRIO_RPL = 0x04, // scheduled by timerB CCR1 interrupt ! TASKPRIO_TCP_TIMEOUT = 0x05, // scheduled by timerB CCR2 interrupt ! TASKPRIO_COAP = 0x06, // scheduled by timerB CCR3 interrupt ! // tasks trigger by other interrupts ! TASKPRIO_BUTTON = 0x07, // scheduled by P2.7 interrupt ! TASKPRIO_MAX = 0x08, ! } task_prio_t; ! ! #define TASK_LIST_DEPTH 10 ! ! //=========================== typedef ========================================= ! ! typedef void (*task_cbt)(void); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! // public functions ! void scheduler_init(); ! void scheduler_start(); ! void scheduler_push_task(task_cbt task_cb, task_prio_t prio); ! ! // interrupt handlers ! void isr_ieee154e_newSlot(); ! void isr_ieee154e_timer(); ! void isr_adc(); ! #ifdef ISR_GYRO ! void isr_gyro(); ! #endif ! #ifdef ISR_LARGE_RANGE_ACCEL ! void isr_large_range_accel(); ! #endif ! #ifdef ISR_BUTTON ! void isr_button(); ! #endif ! ! /** ! \} ! \} ! */ ! ! #endif --- 1,82 ---- ! #ifndef __SCHEDULER_H ! #define __SCHEDULER_H ! ! /** ! \addtogroup kernel ! \{ ! \addtogroup Scheduler ! \{ ! */ ! ! #include "openwsn.h" ! ! //=========================== define ========================================== ! ! typedef enum { ! TASKPRIO_NONE = 0x00, ! // tasks trigger by radio ! TASKPRIO_RESNOTIF_RX = 0x01, // scheduled by IEEE802.15.4e ! TASKPRIO_RESNOTIF_TXDONE = 0x02, // scheduled by IEEE802.15.4e ! // tasks triggered by timers ! TASKPRIO_RES = 0x03, // scheduled by timerB CCR0 interrupt ! TASKPRIO_RPL = 0x04, // scheduled by timerB CCR1 interrupt ! TASKPRIO_TCP_TIMEOUT = 0x05, // scheduled by timerB CCR2 interrupt ! TASKPRIO_COAP = 0x06, // scheduled by timerB CCR3 interrupt ! // tasks trigger by other interrupts ! TASKPRIO_BUTTON = 0x07, // scheduled by P2.7 interrupt ! TASKPRIO_MAX = 0x08, ! } task_prio_t; ! ! #define TASK_LIST_DEPTH 10 ! ! //=========================== typedef ========================================= ! ! typedef void (*task_cbt)(void); ! ! typedef struct task_llist_t { ! task_cbt cb; ! task_prio_t prio; ! void* next; ! } taskList_item_t; ! ! //=========================== module variables ================================ ! ! typedef struct { ! taskList_item_t taskBuf[TASK_LIST_DEPTH]; ! taskList_item_t* task_list; ! uint8_t numTasksCur; ! uint8_t numTasksMax; ! } scheduler_vars_t; ! ! typedef struct { ! uint8_t numTasksCur; ! uint8_t numTasksMax; ! } scheduler_dbg_t; ! ! //=========================== prototypes ====================================== ! ! // public functions ! void scheduler_init(void); ! void scheduler_start(void); ! void scheduler_push_task(task_cbt task_cb, task_prio_t prio); ! ! // interrupt handlers ! void isr_ieee154e_newSlot(void); ! void isr_ieee154e_timer(void); ! void isr_adc(void); ! #ifdef ISR_GYRO ! void isr_gyro(); ! #endif ! #ifdef ISR_LARGE_RANGE_ACCEL ! void isr_large_range_accel(); ! #endif ! #ifdef ISR_BUTTON ! void isr_button(); ! #endif ! ! /** ! \} ! \} ! */ ! ! #endif diff -crB openwsn/spi.c ../../../sys/net/openwsn/spi.c *** openwsn/spi.c Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/spi.c Wed Jan 15 13:48:27 2014 *************** *** 1,246 **** ! /** ! \brief TelosB-specific definition of the "spi" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "spi.h" ! #include "leds.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! typedef struct { ! // information about the current transaction ! uint8_t* pNextTxByte; ! uint8_t numTxedBytes; ! uint8_t txBytesLeft; ! spi_return_t returnType; ! uint8_t* pNextRxByte; ! uint8_t maxRxBytes; ! spi_first_t isFirst; ! spi_last_t isLast; ! // state of the module ! uint8_t busy; ! #ifdef SPI_IN_INTERRUPT_MODE ! // callback when module done ! spi_cbt callback; ! #endif ! } spi_vars_t; ! ! spi_vars_t spi_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void spi_init() { ! // clear variables ! memset(&spi_vars,0,sizeof(spi_vars_t)); ! ! // hold USART state machine in reset mode during configuration ! U0CTL = SWRST; // [b0] SWRST=1: Enabled. USART logic held in reset state ! ! // configure SPI-related pins ! P3SEL |= 0x02; // P3.1 in SIMO mode ! P3DIR |= 0x02; // P3.1 as output ! P3SEL |= 0x04; // P3.2 in SOMI mode ! P3DIR |= 0x04; // P3.2 as output ! P3SEL |= 0x08; // P3.3 in SCL mode ! P3DIR |= 0x08; // P3.3 as output ! P4OUT |= 0x04; // P4.2 radio CS, hold high ! P4DIR |= 0x04; // P4.2 radio CS, output ! ! // initialize USART registers ! U0CTL |= CHAR | SYNC | MM ; // [b7] 0: unused ! // [b6] 0: unused ! // [b5] I2C=0: SPI mode (not I2C) ! // [b4] CHAR=1: 8-bit data ! // [b3] LISTEN=0: Disabled ! // [b2] SYNC=1: SPI mode (not UART) ! // [b1] MM=1: USART is master ! // [b0] SWRST=x: don't change ! ! U0TCTL = CKPH | SSEL1 | STC | TXEPT; // [b7] CKPH=1: UCLK is delayed by one half cycle ! // [b6] CKPL=0: normal clock polarity ! // [b5] SSEL1=1: ! // [b4] SSEL0=0: SMCLK ! // [b3] 0: unused ! // [b2] 0: unused ! // [b1] STC=1: 3-pin SPI mode ! // [b0] TXEPT=1: UxTXBUF and TX shift register are empty ! ! U0BR1 = 0x00; ! U0BR0 = 0x02; // U0BR = [U0BR1<<8|U0BR0] = 2 ! U0MCTL = 0x00; // no modulation needed in SPI mode ! ! // enable USART module ! ME1 |= UTXE0 | URXE0; // [b7] UTXE0=1: USART0 transmit enabled ! // [b6] URXE0=1: USART0 receive enabled ! // [b5] x: don't touch! ! // [b4] x: don't touch! ! // [b3] x: don't touch! ! // [b2] x: don't touch! ! // [b1] x: don't touch! ! // [b0] x: don't touch! ! ! // clear USART state machine from reset, starting operation ! U0CTL &= ~SWRST; ! ! // enable interrupts via the IEx SFRs ! #ifdef SPI_IN_INTERRUPT_MODE ! IE1 |= URXIE0; // we only enable the SPI RX interrupt ! // since TX and RX happen concurrently, ! // i.e. an RX completion necessarily ! // implies a TX completion. ! #endif ! } ! ! #ifdef SPI_IN_INTERRUPT_MODE ! void spi_setCb(spi_cbt cb) { ! spi_vars.spi_cb = cb; ! } ! #endif ! ! void spi_txrx(uint8_t* bufTx, ! uint8_t lenbufTx, ! spi_return_t returnType, ! uint8_t* bufRx, ! uint8_t maxLenBufRx, ! spi_first_t isFirst, ! spi_last_t isLast) { ! ! #ifdef SPI_IN_INTERRUPT_MODE ! // disable interrupts ! __disable_interrupt(); ! #endif ! ! // register spi frame to send ! spi_vars.pNextTxByte = bufTx; ! spi_vars.numTxedBytes = 0; ! spi_vars.txBytesLeft = lenbufTx; ! spi_vars.returnType = returnType; ! spi_vars.pNextRxByte = bufRx; ! spi_vars.maxRxBytes = maxLenBufRx; ! spi_vars.isFirst = isFirst; ! spi_vars.isLast = isLast; ! ! // SPI is now busy ! spi_vars.busy = 1; ! ! // lower CS signal to have slave listening ! if (spi_vars.isFirst==SPI_FIRST) { ! P4OUT &= ~0x04; ! } ! ! #ifdef SPI_IN_INTERRUPT_MODE ! // implementation 1. use a callback function when transaction finishes ! ! // write first byte to TX buffer ! U0TXBUF = *spi_vars.pNextTxByte; ! ! // re-enable interrupts ! __enable_interrupt(); ! #else ! // implementation 2. busy wait for each byte to be sent ! ! // send all bytes ! while (spi_vars.txBytesLeft>0) { ! // write next byte to TX buffer ! U0TXBUF = *spi_vars.pNextTxByte; ! // busy wait on the interrupt flag ! while ((IFG1 & URXIFG0)==0); ! // clear the interrupt flag ! IFG1 &= ~URXIFG0; ! // save the byte just received in the RX buffer ! switch (spi_vars.returnType) { ! case SPI_FIRSTBYTE: ! if (spi_vars.numTxedBytes==0) { ! *spi_vars.pNextRxByte = U0RXBUF; ! } ! break; ! case SPI_BUFFER: ! *spi_vars.pNextRxByte = U0RXBUF; ! spi_vars.pNextRxByte++; ! break; ! case SPI_LASTBYTE: ! *spi_vars.pNextRxByte = U0RXBUF; ! break; ! } ! // one byte less to go ! spi_vars.pNextTxByte++; ! spi_vars.numTxedBytes++; ! spi_vars.txBytesLeft--; ! } ! ! // put CS signal high to signal end of transmission to slave ! if (spi_vars.isLast==SPI_LAST) { ! P4OUT |= 0x04; ! } ! ! // SPI is not busy anymore ! spi_vars.busy = 0; ! #endif ! } ! ! //=========================== private ========================================= ! ! //=========================== interrupt handlers ============================== ! ! kick_scheduler_t spi_isr() { ! #ifdef SPI_IN_INTERRUPT_MODE ! // save the byte just received in the RX buffer ! switch (spi_vars.returnType) { ! case SPI_FIRSTBYTE: ! if (spi_vars.numTxedBytes==0) { ! *spi_vars.pNextRxByte = U0RXBUF; ! } ! break; ! case SPI_BUFFER: ! *spi_vars.pNextRxByte = U0RXBUF; ! spi_vars.pNextRxByte++; ! break; ! case SPI_LASTBYTE: ! *spi_vars.pNextRxByte = U0RXBUF; ! break; ! } ! ! // one byte less to go ! spi_vars.pNextTxByte++; ! spi_vars.numTxedBytes++; ! spi_vars.txBytesLeft--; ! ! if (spi_vars.txBytesLeft>0) { ! // write next byte to TX buffer ! U0TXBUF = *spi_vars.pNextTxByte; ! } else { ! // put CS signal high to signal end of transmission to slave ! if (spi_vars.isLast==SPI_LAST) { ! P4OUT |= 0x04; ! } ! // SPI is not busy anymore ! spi_vars.busy = 0; ! ! // SPI is done! ! if (spi_vars.callback!=NULL) { ! // call the callback ! spi_vars.spi_cb(); ! // kick the OS ! return KICK_SCHEDULER; ! } ! } ! return DO_NOT_KICK_SCHEDULER; ! #else ! // this should never happpen! ! ! // we can not print from within the BSP. Instead: ! // blink the error LED ! leds_error_blink(); ! // reset the board ! board_reset(); ! ! return DO_NOT_KICK_SCHEDULER; // we will not get here, statement to please compiler ! #endif ! } --- 1,251 ---- ! /** ! \brief TelosB-specific definition of the "spi" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "spi.h" ! #include "leds.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! typedef struct { ! // information about the current transaction ! uint8_t* pNextTxByte; ! uint8_t numTxedBytes; ! uint8_t txBytesLeft; ! spi_return_t returnType; ! uint8_t* pNextRxByte; ! uint8_t maxRxBytes; ! spi_first_t isFirst; ! spi_last_t isLast; ! // state of the module ! uint8_t busy; ! #ifdef SPI_IN_INTERRUPT_MODE ! // callback when module done ! spi_cbt spi_cb; ! #endif ! } spi_vars_t; ! ! spi_vars_t spi_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void spi_init(void) { ! // clear variables ! memset(&spi_vars,0,sizeof(spi_vars_t)); ! ! // hold USART state machine in reset mode during configuration ! U0CTL = SWRST; // [b0] SWRST=1: Enabled. USART logic held in reset state ! ! // configure SPI-related pins ! P3SEL |= 0x02; // P3.1 in SIMO mode ! P3DIR |= 0x02; // P3.1 as output ! P3SEL |= 0x04; // P3.2 in SOMI mode ! P3DIR |= 0x04; // P3.2 as output ! P3SEL |= 0x08; // P3.3 in SCL mode ! P3DIR |= 0x08; // P3.3 as output ! P4OUT |= 0x04; // P4.2 radio CS, hold high ! P4DIR |= 0x04; // P4.2 radio CS, output ! ! // initialize USART registers ! U0CTL |= CHAR | SYNC | MM ; // [b7] 0: unused ! // [b6] 0: unused ! // [b5] I2C=0: SPI mode (not I2C) ! // [b4] CHAR=1: 8-bit data ! // [b3] LISTEN=0: Disabled ! // [b2] SYNC=1: SPI mode (not UART) ! // [b1] MM=1: USART is master ! // [b0] SWRST=x: don't change ! ! U0TCTL = CKPH | SSEL1 | STC | TXEPT; // [b7] CKPH=1: UCLK is delayed by one half cycle ! // [b6] CKPL=0: normal clock polarity ! // [b5] SSEL1=1: ! // [b4] SSEL0=0: SMCLK ! // [b3] 0: unused ! // [b2] 0: unused ! // [b1] STC=1: 3-pin SPI mode ! // [b0] TXEPT=1: UxTXBUF and TX shift register are empty ! ! U0BR1 = 0x00; ! U0BR0 = 0x02; // U0BR = [U0BR1<<8|U0BR0] = 2 ! U0MCTL = 0x00; // no modulation needed in SPI mode ! ! // enable USART module ! ME1 |= UTXE0 | URXE0; // [b7] UTXE0=1: USART0 transmit enabled ! // [b6] URXE0=1: USART0 receive enabled ! // [b5] x: don't touch! ! // [b4] x: don't touch! ! // [b3] x: don't touch! ! // [b2] x: don't touch! ! // [b1] x: don't touch! ! // [b0] x: don't touch! ! ! // clear USART state machine from reset, starting operation ! U0CTL &= ~SWRST; ! ! // enable interrupts via the IEx SFRs ! #ifdef SPI_IN_INTERRUPT_MODE ! IE1 |= URXIE0; // we only enable the SPI RX interrupt ! // since TX and RX happen concurrently, ! // i.e. an RX completion necessarily ! // implies a TX completion. ! #endif ! } ! ! #ifdef SPI_IN_INTERRUPT_MODE ! void spi_setCb(spi_cbt cb) { ! spi_vars.spi_cb = cb; ! } ! #endif ! ! void spi_txrx(uint8_t* bufTx, ! uint8_t lenbufTx, ! spi_return_t returnType, ! uint8_t* bufRx, ! uint8_t maxLenBufRx, ! spi_first_t isFirst, ! spi_last_t isLast) { ! ! #ifdef SPI_IN_INTERRUPT_MODE ! // disable interrupts ! __disable_interrupt(); ! #endif ! ! // register spi frame to send ! spi_vars.pNextTxByte = bufTx; ! spi_vars.numTxedBytes = 0; ! spi_vars.txBytesLeft = lenbufTx; ! spi_vars.returnType = returnType; ! spi_vars.pNextRxByte = bufRx; ! spi_vars.maxRxBytes = maxLenBufRx; ! spi_vars.isFirst = isFirst; ! spi_vars.isLast = isLast; ! ! // SPI is now busy ! spi_vars.busy = 1; ! ! // lower CS signal to have slave listening ! if (spi_vars.isFirst==SPI_FIRST) { ! P4OUT &= ~0x04; ! } ! ! #ifdef SPI_IN_INTERRUPT_MODE ! // implementation 1. use a callback function when transaction finishes ! ! // write first byte to TX buffer ! U0TXBUF = *spi_vars.pNextTxByte; ! ! // re-enable interrupts ! __enable_interrupt(); ! #else ! // implementation 2. busy wait for each byte to be sent ! ! // send all bytes ! while (spi_vars.txBytesLeft>0) { ! // write next byte to TX buffer ! U0TXBUF = *spi_vars.pNextTxByte; ! // busy wait on the interrupt flag ! uint32_t c = 0; ! while ((IFG1 & URXIFG0)==0) ! if (c++ == 1000) { ! puts("spi_txrx timeout"); ! break; ! } ! // clear the interrupt flag ! IFG1 &= ~URXIFG0; ! // save the byte just received in the RX buffer ! switch (spi_vars.returnType) { ! case SPI_FIRSTBYTE: ! if (spi_vars.numTxedBytes==0) { ! *spi_vars.pNextRxByte = U0RXBUF; ! } ! break; ! case SPI_BUFFER: ! *spi_vars.pNextRxByte = U0RXBUF; ! spi_vars.pNextRxByte++; ! break; ! case SPI_LASTBYTE: ! *spi_vars.pNextRxByte = U0RXBUF; ! break; ! } ! // one byte less to go ! spi_vars.pNextTxByte++; ! spi_vars.numTxedBytes++; ! spi_vars.txBytesLeft--; ! } ! ! // put CS signal high to signal end of transmission to slave ! if (spi_vars.isLast==SPI_LAST) { ! P4OUT |= 0x04; ! } ! ! // SPI is not busy anymore ! spi_vars.busy = 0; ! #endif ! } ! ! //=========================== private ========================================= ! ! //=========================== interrupt handlers ============================== ! ! kick_scheduler_t spi_isr(void) { ! #ifdef SPI_IN_INTERRUPT_MODE ! // save the byte just received in the RX buffer ! switch (spi_vars.returnType) { ! case SPI_FIRSTBYTE: ! if (spi_vars.numTxedBytes==0) { ! *spi_vars.pNextRxByte = U0RXBUF; ! } ! break; ! case SPI_BUFFER: ! *spi_vars.pNextRxByte = U0RXBUF; ! spi_vars.pNextRxByte++; ! break; ! case SPI_LASTBYTE: ! *spi_vars.pNextRxByte = U0RXBUF; ! break; ! } ! ! // one byte less to go ! spi_vars.pNextTxByte++; ! spi_vars.numTxedBytes++; ! spi_vars.txBytesLeft--; ! ! if (spi_vars.txBytesLeft>0) { ! // write next byte to TX buffer ! U0TXBUF = *spi_vars.pNextTxByte; ! } else { ! // put CS signal high to signal end of transmission to slave ! if (spi_vars.isLast==SPI_LAST) { ! P4OUT |= 0x04; ! } ! // SPI is not busy anymore ! spi_vars.busy = 0; ! ! // SPI is done! ! if (spi_vars.spi_cb!=NULL) { ! // call the callback ! spi_vars.spi_cb(); ! // kick the OS ! return KICK_SCHEDULER; ! } ! } ! return DO_NOT_KICK_SCHEDULER; ! #else ! // this should never happpen! ! ! // we can not print from within the BSP. Instead: ! // blink the error LED ! leds_error_blink(); ! // reset the board ! board_reset(); ! ! return DO_NOT_KICK_SCHEDULER; // we will not get here, statement to please compiler ! #endif ! } diff -crB openwsn/spi.h ../../../sys/net/openwsn/spi.h *** openwsn/spi.h Thu Mar 21 21:36:59 2013 --- ../../../sys/net/openwsn/spi.h Wed Jan 15 13:48:27 2014 *************** *** 1,67 **** ! /** ! \brief Cross-platform declaration "spi" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __SPI_H ! #define __SPI_H ! ! #include "stdint.h" ! #include "board.h" ! ! //=========================== define ========================================== ! ! /** ! The SPI module functions in two modes: ! - in "blocking" mode, all calls return only when the module is done. the CPU ! is not available while the module is busy. This is the preferred method is ! low-RAM system which can not run an RTOS ! - in "interrupt" mode, calls are returned after the module has started a ! transaction. When the transaction is done, the module uses a callback ! function to signal this to the caller. This frees up CPU time, allowing for ! other operations to happen concurrently. This is the preferred method when an ! RTOS is present. ! */ ! //#define SPI_IN_INTERRUPT_MODE ! ! //=========================== typedef ========================================= ! ! typedef enum { ! SPI_FIRSTBYTE = 0, ! SPI_BUFFER = 1, ! SPI_LASTBYTE = 2, ! } spi_return_t; ! ! typedef enum { ! SPI_NOTFIRST = 0, ! SPI_FIRST = 1, ! } spi_first_t; ! ! typedef enum { ! SPI_NOTLAST = 0, ! SPI_LAST = 1, ! } spi_last_t; ! ! typedef void (*spi_cbt)(void); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void spi_init(); ! #ifdef SPI_IN_INTERRUPT_MODE ! void spi_setCb(spi_cbt cb); ! #endif ! void spi_txrx(uint8_t* bufTx, ! uint8_t lenbufTx, ! spi_return_t returnType, ! uint8_t* bufRx, ! uint8_t maxLenBufRx, ! spi_first_t isFirst, ! spi_last_t isLast); ! ! // interrupt handlers ! kick_scheduler_t spi_isr(); ! ! #endif --- 1,67 ---- ! /** ! \brief Cross-platform declaration "spi" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #ifndef __SPI_H ! #define __SPI_H ! ! #include "stdint.h" ! #include "board_ow.h" ! ! //=========================== define ========================================== ! ! /** ! The SPI module functions in two modes: ! - in "blocking" mode, all calls return only when the module is done. the CPU ! is not available while the module is busy. This is the preferred method is ! low-RAM system which can not run an RTOS ! - in "interrupt" mode, calls are returned after the module has started a ! transaction. When the transaction is done, the module uses a callback ! function to signal this to the caller. This frees up CPU time, allowing for ! other operations to happen concurrently. This is the preferred method when an ! RTOS is present. ! */ ! //#define SPI_IN_INTERRUPT_MODE ! ! //=========================== typedef ========================================= ! ! typedef enum { ! SPI_FIRSTBYTE = 0, ! SPI_BUFFER = 1, ! SPI_LASTBYTE = 2, ! } spi_return_t; ! ! typedef enum { ! SPI_NOTFIRST = 0, ! SPI_FIRST = 1, ! } spi_first_t; ! ! typedef enum { ! SPI_NOTLAST = 0, ! SPI_LAST = 1, ! } spi_last_t; ! ! typedef void (*spi_cbt)(void); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void spi_init(void); ! #ifdef SPI_IN_INTERRUPT_MODE ! void spi_setCb(spi_cbt cb); ! #endif ! void spi_txrx(uint8_t* bufTx, ! uint8_t lenbufTx, ! spi_return_t returnType, ! uint8_t* bufRx, ! uint8_t maxLenBufRx, ! spi_first_t isFirst, ! spi_last_t isLast); ! ! // interrupt handlers ! kick_scheduler_t spi_isr(void); ! ! #endif diff -crB openwsn/uart_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 , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "uart.h" ! #include "board.h" ! ! //=========================== defines ========================================= ! ! //=========================== variables ======================================= ! ! typedef struct { ! uart_tx_cbt txCb; ! uart_rx_cbt rxCb; ! } uart_vars_t; ! ! uart_vars_t uart_vars; ! ! //=========================== prototypes ====================================== ! ! //=========================== public ========================================== ! ! void uart_init() { ! P3SEL |= 0xc0; // P3.6,7 = UART1TX/RX ! ! UCTL1 = SWRST; // hold UART1 module in reset ! UCTL1 |= CHAR; // 8-bit character ! ! /* ! // 9600 baud, clocked from 32kHz ACLK ! UTCTL1 |= SSEL0; // clocking from ACLK ! UBR01 = 0x03; // 32768/9600 = 3.41 ! UBR11 = 0x00; // ! UMCTL1 = 0x4A; // modulation ! */ ! ! // 115200 baud, clocked from 4.8MHz SMCLK ! UTCTL1 |= SSEL1; // clocking from SMCLK ! UBR01 = 41; // 4.8MHz/115200 - 41.66 ! UBR11 = 0x00; // ! UMCTL1 = 0x4A; // modulation ! ! ! ME2 |= UTXE1 + URXE1; // enable UART1 TX/RX ! UCTL1 &= ~SWRST; // clear UART1 reset bit ! } ! ! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb) { ! uart_vars.txCb = txCb; ! uart_vars.rxCb = rxCb; ! } ! ! void uart_enableInterrupts(){ ! IE2 |= (URXIE1 | UTXIE1); ! } ! ! void uart_disableInterrupts(){ ! IE2 &= ~(URXIE1 | UTXIE1); ! } ! ! void uart_clearRxInterrupts(){ ! IFG2 &= ~URXIFG1; ! } ! ! void uart_clearTxInterrupts(){ ! IFG2 &= ~UTXIFG1; ! } ! ! void uart_writeByte(uint8_t byteToWrite){ ! U1TXBUF = byteToWrite; ! } ! ! uint8_t uart_readByte(){ ! return U1RXBUF; ! } ! ! //=========================== private ========================================= ! ! //=========================== interrupt handlers ============================== ! ! kick_scheduler_t uart_tx_isr() { ! uart_clearTxInterrupts(); // TODO: do not clear, but disable when done ! uart_vars.txCb(); ! return DO_NOT_KICK_SCHEDULER; ! } ! ! kick_scheduler_t uart_rx_isr() { ! uart_clearRxInterrupts(); // TODO: do not clear, but disable when done ! uart_vars.rxCb(); ! return DO_NOT_KICK_SCHEDULER; } \ No newline at end of file --- 1,94 ---- ! /** ! \brief TelosB-specific definition of the "uart" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "msp430f1611.h" ! #include "uart_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 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 , February 2012. ! */ ! ! #ifndef __UART_H ! #define __UART_H ! ! #include "stdint.h" ! #include "board.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! typedef enum { ! UART_EVENT_THRES, ! UART_EVENT_OVERFLOW, ! } uart_event_t; ! ! typedef void (*uart_tx_cbt)(); ! typedef void (*uart_rx_cbt)(); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void uart_init(); ! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb); ! void uart_enableInterrupts(); ! void uart_disableInterrupts(); ! void uart_clearRxInterrupts(); ! void uart_clearTxInterrupts(); ! void uart_writeByte(uint8_t byteToWrite); ! uint8_t uart_readByte(); ! ! // interrupt handlers ! kick_scheduler_t uart_tx_isr(); ! kick_scheduler_t uart_rx_isr(); ! ! #endif \ No newline at end of file --- 1,52 ---- ! #ifndef __UART_H ! #define __UART_H ! ! /** ! \addtogroup BSP ! \{ ! \addtogroup uart ! \{ ! ! \brief Cross-platform declaration "uart" bsp module. ! ! \author Thomas Watteyne , February 2012. ! */ ! ! #include "stdint.h" ! #include "board_ow.h" ! ! //=========================== define ========================================== ! ! //=========================== typedef ========================================= ! ! typedef enum { ! UART_EVENT_THRES, ! UART_EVENT_OVERFLOW, ! } uart_event_t; ! ! typedef void (*uart_tx_cbt)(void); ! typedef void (*uart_rx_cbt)(void); ! ! //=========================== variables ======================================= ! ! //=========================== prototypes ====================================== ! ! void uart_init_ow(void); ! void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb); ! void uart_enableInterrupts(void); ! void uart_disableInterrupts(void); ! void uart_clearRxInterrupts(void); ! void uart_clearTxInterrupts(void); ! void uart_writeByte(uint8_t byteToWrite); ! uint8_t uart_readByte_ow(void); ! ! // interrupt handlers ! kick_scheduler_t uart_tx_isr(void); ! kick_scheduler_t uart_rx_isr(void); ! ! /** ! \} ! \} ! */ ! ! #endif