CmdMessenger 3.0 CmdMessenger is a messaging library for the Arduino Platform. It has uses the serial port as its transport layer

- Main Page
- Classes
- Files

- File List

D:/My Documents/Github/Arduino-Code-and-Libraries/Libraries/CmdMessenger/CmdMessenger.h

    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