]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/diagmsg/DiagMsgM.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / lib / diagmsg / DiagMsgM.nc
diff --git a/tos/lib/diagmsg/DiagMsgM.nc b/tos/lib/diagmsg/DiagMsgM.nc
deleted file mode 100644 (file)
index 669a04b..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- * 
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * 
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <message.h>
-
-module DiagMsgM
-{
-       provides 
-       {
-               interface DiagMsg;
-               interface Init;
-       }
-
-       uses 
-       {
-               interface AMSend;
-               interface Packet;
-       }
-}
-
-#ifndef DIAGMSG_BASE_STATION
-#define        DIAGMSG_BASE_STATION    AM_BROADCAST_ADDR
-#endif
-
-#ifndef DIAGMSG_RETRY_COUNT
-#define        DIAGMSG_RETRY_COUNT     2
-#endif
-
-#ifndef DIAGMSG_RECORDED_MSGS
-#define DIAGMSG_RECORDED_MSGS  10
-#endif
-
-implementation
-{
-       enum
-       {
-               STATE_READY = 1,
-               STATE_RECORDING_FIRST = 2,      // recording the first 4-bit descriptor
-               STATE_RECORDING_SECOND = 3,     // recording the second 4-bit descriptor
-               STATE_MSG_FULL = 4,
-               STATE_BUFFER_FULL = 5,
-       };
-
-       norace volatile uint8_t state;  // the state of the recording
-
-       message_t msgs[DIAGMSG_RECORDED_MSGS];  // circular buffer of messages
-
-       norace message_t *recording;    // the message that is beeing or going to be recorded
-       message_t *sending;     // the message that is beeing sent, or the null pointer
-
-       norace uint8_t nextData;        // points to the next unsued byte
-       norace uint8_t prevType;        // points to the type descriptor
-       norace uint8_t retries; // number of remaining retries
-
-       command error_t Init.init()
-       {
-               state = STATE_READY;
-               recording = msgs;
-               sending = 0;
-
-               return SUCCESS;
-       }
-
-       // two type fields are stored in on byte
-       enum
-       {
-               TYPE_END = 0,
-               TYPE_INT8 = 1,
-               TYPE_UINT8 = 2,
-               TYPE_HEX8 = 3,
-               TYPE_INT16 = 4,
-               TYPE_UINT16 = 5,
-               TYPE_HEX16 = 6,
-               TYPE_INT32 = 7,
-               TYPE_UINT32 = 8,
-               TYPE_HEX32 = 9,
-               TYPE_FLOAT = 10,
-               TYPE_CHAR = 11,
-               TYPE_INT64 = 12,
-               TYPE_UINT64 = 13,
-               TYPE_ARRAY = 15,
-       };
-
-/*
-       The format of the payload is as follows: 
-       
-       Each value has an associated data type descriptor. The descriptor takes 4-bits,
-       and two descriptors are packed into one byte. The double-descriptor is followed
-       by the data bytes needed to store the corresponding value. Two sample layouts are:
-
-       [D2, D1] [V1] ... [V1] [V2] ... [V2]
-       [D2, D1] [V1] ... [V1] [V2] ... [V2] [0, D3] [V3] ... [V3]
-
-       where D1, D2, D3 denotes the data type descriptors, and V1, V2 and V3
-       denotes the bytes where the corresponding values are stored. If there is an odd
-       number of data descriptors, then a zero data descriptor <code>TYPE_END</code> 
-       is inserted.
-
-       Each data type (except arrays) uses a fixed number of bytes to store the value.
-       For arrays, the first byte of the array holds the data type of the array (higer
-       4 bits) and the length of the array (lower 4 bits). The actual data follows 
-       this first byte.
-*/
-
-       async command bool DiagMsg.record()
-       {
-               atomic
-               {
-                       // currently recording or no more space
-                       if( state != STATE_READY )
-                               return FALSE;
-
-                       state = STATE_RECORDING_FIRST;
-                       nextData = 0;
-               }
-
-               return TRUE;
-       }
-
-       /**
-        * Allocates space in the message for <code>size</code> bytes
-        * and sets the type information to <code>type</code>. 
-        * Returns the index in <code>msg.data</code> where the data 
-        * should be stored or <code>-1</code> if no more space is avaliable.
-        */
-       int8_t allocate(uint8_t size, uint8_t type)
-       {
-               int8_t ret = -1;
-
-               if( state == STATE_RECORDING_FIRST )
-               {
-                       if( nextData + 1 + size <= TOSH_DATA_LENGTH )
-                       {
-                               state = STATE_RECORDING_SECOND;
-
-                               prevType = nextData++;
-                               ((uint8_t*) &(recording->data))[prevType] = type;
-                               ret = nextData;
-                               nextData += size;
-                       }
-                       else
-                               state = STATE_MSG_FULL;
-               }
-               else if( state == STATE_RECORDING_SECOND )
-               {
-                       if( nextData + size <= TOSH_DATA_LENGTH )
-                       {
-                               state = STATE_RECORDING_FIRST;
-
-                               ((uint8_t*) &(recording->data))[prevType] += (type << 4);
-                               ret = nextData;
-                               nextData += size;
-                       }
-                       else
-                               state = STATE_MSG_FULL;
-               }
-
-               return ret;
-       }
-
-#define IMPLEMENT(NAME, TYPE, TYPE2) \
-       async command void DiagMsg.NAME(TYPE value) \
-       { \
-               int8_t start = allocate(sizeof(TYPE), TYPE2); \
-               if( start >= 0 ) \
-                       *(TYPE*)((uint8_t*) &(recording->data) + start) = value; \
-       } \
-       async command void DiagMsg.NAME##s(const TYPE *value, uint8_t len) \
-       { \
-               int8_t start; \
-               if( len > 15 ) len = 15; \
-               start = allocate(sizeof(TYPE)*len + 1, TYPE_ARRAY); \
-               if( start >= 0 ) \
-               { \
-                       ((uint8_t*) &(recording->data))[start++] = (TYPE2 << 4) + len; \
-                       while( len-- != 0 ) \
-                               ((TYPE*)((uint8_t*) &(recording->data) + start))[len] = value[len]; \
-               } \
-       }
-
-       IMPLEMENT(int8, int8_t, TYPE_INT8)
-       IMPLEMENT(uint8, uint8_t, TYPE_UINT8)
-       IMPLEMENT(hex8, uint8_t, TYPE_HEX8)
-       IMPLEMENT(int16, int16_t, TYPE_INT16)
-       IMPLEMENT(uint16, uint16_t, TYPE_UINT16)
-       IMPLEMENT(hex16, uint16_t, TYPE_HEX16)
-       IMPLEMENT(int32, int32_t, TYPE_INT32)
-       IMPLEMENT(uint32, uint32_t, TYPE_UINT32)
-       IMPLEMENT(hex32, uint32_t, TYPE_HEX32)
-       IMPLEMENT(int64, int64_t, TYPE_INT64)
-       IMPLEMENT(uint64, uint64_t, TYPE_UINT64)
-       IMPLEMENT(real, float, TYPE_FLOAT)
-       IMPLEMENT(chr, char, TYPE_CHAR)
-
-       async command void DiagMsg.str(const char* str)
-       {
-               int8_t len = 0;
-               while( str[len] != 0 && len < 15 )
-                       ++len;
-               
-               call DiagMsg.chrs(str, len);
-       }
-
-       // TODO: this is a hack because setPayloadLength should be async
-       inline void setPayloadLength(message_t* msg, uint8_t length)
-       {
-               (*(uint8_t*) &(msg->header)) = length;
-       }
-
-       inline uint8_t getPayloadLength(message_t* msg)
-       {
-               return *(uint8_t*) &(msg->header);
-       }
-
-       task void send()
-       {
-               message_t* msg;
-
-               atomic msg = sending;
-
-               if( call AMSend.send(DIAGMSG_BASE_STATION, msg, getPayloadLength(msg)) != SUCCESS )
-                       post send();
-       }
-
-       // calculates the next message_t pointer in the <code>msgs</code> circular buffer
-       static inline message_t* nextPointer(message_t* ptr)
-       {
-               if( ++ptr >= msgs + DIAGMSG_RECORDED_MSGS )
-                       return msgs;
-               else
-                       return ptr;
-       }
-
-       async command void DiagMsg.send()
-       {
-               // no message recorded
-               if( state == STATE_READY )
-                       return;
-
-               // store the length
-               setPayloadLength(recording, nextData);
-
-               atomic
-               {
-                       if( sending == 0 )
-                       {
-                               sending = recording;
-                               retries = DIAGMSG_RETRY_COUNT;
-                               post send();
-                       }
-       
-                       recording = nextPointer(recording);
-
-                       if( recording == sending )
-                               state = STATE_BUFFER_FULL;
-                       else
-                               state = STATE_READY;
-               }
-       }
-
-       event void AMSend.sendDone(message_t* p, error_t error)
-       {
-               atomic
-               {
-                       // retry if not successful
-                       if( error != SUCCESS && --retries > 0 )
-                               post send();
-                       else
-                       {
-                               p = nextPointer(sending);
-                               if( p != recording )
-                               {
-                                       sending = p;
-                                       retries = DIAGMSG_RETRY_COUNT;
-                                       post send();
-                               }
-                               else
-                               {
-                                       sending = 0;
-
-                                       if( state == STATE_BUFFER_FULL )
-                                       {
-                                               state = STATE_READY;
-                                               if( call DiagMsg.record() )
-                                               {
-                                                       call DiagMsg.str("DiagMsgOverflow");
-                                                       call DiagMsg.send();
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-}