CmdMessenger.h
Go to the documentation of this file.
00001 /*
00002   CmdMessenger - library that provides command based messaging
00003 
00004         Permission is hereby granted, free of charge, to any person obtaining
00005         a copy of this software and associated documentation files (the
00006         "Software"), to deal in the Software without restriction, including
00007         without limitation the rights to use, copy, modify, merge, publish,
00008         distribute, sublicense, and/or sell copies of the Software, and to
00009         permit persons to whom the Software is furnished to do so, subject to
00010         the following conditions:
00011 
00012         The above copyright notice and this permission notice shall be
00013         included in all copies or substantial portions of the Software.
00014 
00015         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00016         EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017         MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00018         NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00019         LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00020         OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00021         WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 
00023  */
00024 
00025 #ifndef CmdMessenger_h
00026 #define CmdMessenger_h
00027 
00028 #include <inttypes.h>
00029 #if ARDUINO >= 100
00030 #include <Arduino.h> 
00031 #else
00032 #include <WProgram.h> 
00033 #endif
00034 
00035 //#include "Stream.h"
00036 
00037 extern "C"
00038 {
00039   // callback functions always follow the signature: void cmd(void);
00040   typedef void (*messengerCallbackFunction) (void);
00041 }
00042 
00043 #define MAXCALLBACKS        50   // The maximum number of commands   (default: 50)
00044 #define MESSENGERBUFFERSIZE 64   // The length of the commandbuffer  (default: 64)
00045 #define MAXSTREAMBUFFERSIZE 512  // The length of the streambuffer   (default: 64)
00046 #define DEFAULT_TIMEOUT     5000 // Time out on unanswered messages. (default: 5s)
00047 
00048 // Message States
00049 enum
00050 {  
00051   kProccesingMessage,            // Message is being received, not reached command separator
00052   kEndOfMessage,                                 // Message is fully received, reached command separator
00053   kProcessingArguments,                  // Message is received, arguments are being read parsed
00054 };
00055 
00056 #define white_space(c) ((c) == ' ' || (c) == '\t')
00057 #define valid_digit(c) ((c) >= '0' && (c) <= '9')
00058 
00059 class CmdMessenger
00060 {
00061 private:
00062 
00063   // **** Private variables *** 
00064   
00065   bool    startCommand;            // Indicates if sending of a command is underway
00066   uint8_t lastCommandId;                    // ID of last received command 
00067   uint8_t bufferIndex;              // Index where to write data in buffer
00068   uint8_t bufferLength;             // Is set to MESSENGERBUFFERSIZE
00069   uint8_t bufferLastIndex;          // The last index of the buffer
00070   char ArglastChar;                 // Bookkeeping of argument escape char 
00071   char CmdlastChar;                 // Bookkeeping of command escape char 
00072   bool pauseProcessing;             // pauses processing of new commands, during sending
00073   bool print_newlines;              // Indicates if \r\n should be added after send command
00074   char commandBuffer[MESSENGERBUFFERSIZE]; // Buffer that holds the data
00075   char streamBuffer[MAXSTREAMBUFFERSIZE]; // Buffer that holds the data
00076   uint8_t messageState;             // Current state of message processing
00077   bool dumped;                      // Indicates if last argument has been externally read 
00078   bool ArgOk;                                           // Indicated if last fetched argument could be read
00079   char *current;                    // Pointer to current buffer position
00080   char *last;                       // Pointer to previous buffer position
00081   char prevChar;                    // Previous char (needed for unescaping)
00082   Stream *comms;                    // Serial data stream
00083   
00084   char command_separator;           // Character indicating end of command (default: ';')
00085   char field_separator;                         // Character indicating end of argument (default: ',')
00086   char escape_character;                    // Character indicating escaping of special chars
00087     
00088   messengerCallbackFunction default_callback;            // default callback function  
00089   messengerCallbackFunction callbackList[MAXCALLBACKS];  // list of attached callback functions 
00090   
00091   
00092   // **** Initialize ****
00093   
00094   void init (Stream & comms, const char fld_separator, const char cmd_separator, const char esc_character);
00095   void reset ();
00096   
00097   // **** Command processing ****
00098   
00099   inline uint8_t processLine (char serialChar) __attribute__((always_inline));
00100   inline void handleMessage() __attribute__((always_inline));
00101   inline bool blockedTillReply (unsigned long timeout = DEFAULT_TIMEOUT, int ackCmdId = 1) __attribute__((always_inline));
00102   inline bool CheckForAck (int AckCommand) __attribute__((always_inline));
00103 
00104   // **** Command sending ****
00105    
00109   template < class T > 
00110     void writeBin (const T & value)
00111   {
00112         const byte *bytePointer = (const byte *) (const void *) &value;
00113     for (unsigned int i = 0; i < sizeof (value); i++)
00114       {
00115         printEsc (*bytePointer); 
00116                 bytePointer++;
00117       }
00118   }
00119     
00120   // **** Command receiving ****
00121   
00122   int findNext (char *str, char delim);
00123 
00127   template < class T > 
00128     T readBin (char *str)
00129   {
00130     T value;
00131     unescape (str);
00132     byte *bytePointer = (byte *) (const void *) &value;
00133     for (unsigned int i = 0; i < sizeof (value); i++)
00134       {
00135         *bytePointer = str[i];
00136                 bytePointer++;
00137       }
00138     return value;
00139   }
00140   
00141   template < class T > 
00142     T empty ()
00143   {
00144     T value;
00145     byte *bytePointer = (byte *) (const void *) &value;
00146     for (unsigned int i = 0; i < sizeof (value); i++)
00147       {
00148         *bytePointer = '\0';
00149                 bytePointer++;
00150       }
00151     return value;
00152   }
00153   
00154   // **** Escaping tools ****
00155   
00156   char *split_r (char *str, const char delim, char **nextp);
00157   bool isEscaped (char *currChar, const char escapeChar, char *lastChar);
00158   
00159   void printEsc (char *str);
00160   void printEsc (char str); 
00161   
00162 public:
00163 
00164   // ****** Public functions ******
00165 
00166   // **** Initialization ****
00167   
00168   CmdMessenger (Stream & comms, const char fld_separator = ',', 
00169                                 const char cmd_separator = ';', 
00170                 const char esc_character = '/');
00171   
00172   void printLfCr (bool addNewLine=true);
00173   void attach (messengerCallbackFunction newFunction);
00174   void attach (byte msgId, messengerCallbackFunction newFunction);
00175   
00176   // **** Command processing ****
00177   
00178   void feedinSerialData ();
00179   bool next ();
00180   bool available ();
00181   bool isArgOk ();
00182   uint8_t CommandID ();
00183   
00184   // ****  Command sending ****
00185   
00190   template < class T >
00191     bool sendCmd (int cmdId, T arg, bool reqAc = false, int ackCmdId = 1, 
00192                                   int timeout = DEFAULT_TIMEOUT)
00193   {
00194     if (!startCommand) {
00195                 sendCmdStart (cmdId);
00196                 sendCmdArg (arg);
00197                 return sendCmdEnd (reqAc, ackCmdId, timeout);
00198         }
00199         return false;
00200   }
00201 
00206   template < class T >
00207     bool sendBinCmd (int cmdId, T arg, bool reqAc = false, int ackCmdId = 1,
00208                      int timeout = DEFAULT_TIMEOUT)
00209   {
00210     if (!startCommand) {
00211                 sendCmdStart (cmdId);
00212                 sendCmdBinArg (arg);
00213                 return sendCmdEnd (reqAc, ackCmdId, timeout);
00214         }
00215         return false;
00216   }
00217 
00218   bool sendCmd (int cmdId);
00219   bool sendCmd (int cmdId, bool reqAc, int ackCmdId );
00220   // **** Command sending with multiple arguments ****
00221   
00222   void sendCmdStart (int cmdId);
00223   void sendCmdEscArg (char *arg);
00224   void sendCmdfArg (char *fmt, ...);
00225   bool sendCmdEnd (bool reqAc = false, int ackCmdId = 1, int timeout = DEFAULT_TIMEOUT);
00226   
00231   template < class T > void sendCmdArg (T arg)
00232   {
00233     if (startCommand) {
00234         comms->print (field_separator);
00235         comms->print (arg);
00236     }
00237   }
00238     
00243   template < class T > void sendCmdArg (T arg, int n)
00244   {
00245     if (startCommand) {
00246         comms->print (field_separator);
00247         comms->print (arg, n);
00248     }
00249   }
00250   
00255   void sendCmdSciArg(double arg, int n=6);
00256 
00257   
00262   template < class T > void sendCmdBinArg (T arg)
00263   {
00264     if (startCommand) {
00265         comms->print (field_separator);
00266         writeBin (arg);
00267     }
00268   }  
00269 
00270   // **** Command receiving ****
00271   bool readBoolArg();
00272   int16_t readInt16Arg ();
00273   int32_t readInt32Arg ();
00274   char readCharArg ();
00275   float readFloatArg ();
00276   double readDoubleArg();
00277   char *readStringArg ();
00278   void copyStringArg (char *string, uint8_t size);
00279   uint8_t compareStringArg (char *string);
00280  
00284   template < class T > T readBinArg ()
00285   {
00286     if (next ()) {
00287         dumped = true;      
00288                 return readBin < T > (current);
00289     } else {
00290                 return empty < T > ();
00291         }
00292   }
00293 
00294   // **** Escaping tools ****
00295   
00296   void unescape (char *fromChar);       
00297   void printSci(double f, unsigned int digits);  
00298   
00299   
00300 };
00301 #endif


ric_mc
Author(s): RoboTiCan
autogenerated on Thu Aug 27 2015 14:39:49