CmdMessenger 4.0.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/Own Arduino libraries/CmdMessenger/Arduino-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     // **** Private variables ***
    00063
    00064     bool    startCommand;            // Indicates if sending of a command is underway
    00065     uint8_t lastCommandId;          // ID of last received command
    00066     uint8_t bufferIndex;              // Index where to write data in buffer
    00067     uint8_t bufferLength;             // Is set to MESSENGERBUFFERSIZE
    00068     uint8_t bufferLastIndex;          // The last index of the buffer
    00069     char ArglastChar;                 // Bookkeeping of argument escape char
    00070     char CmdlastChar;                 // Bookkeeping of command escape char
    00071     bool pauseProcessing;             // pauses processing of new commands, during sending
    00072     bool print_newlines;              // Indicates if \r\n should be added after send command
    00073     char commandBuffer[MESSENGERBUFFERSIZE]; // Buffer that holds the data
    00074     char streamBuffer[MAXSTREAMBUFFERSIZE]; // Buffer that holds the data
    00075     uint8_t messageState;             // Current state of message processing
    00076     bool dumped;                      // Indicates if last argument has been externally read
    00077     bool ArgOk;                     // Indicated if last fetched argument could be read
    00078     char *current;                    // Pointer to current buffer position
    00079     char *last;                       // Pointer to previous buffer position
    00080     char prevChar;                    // Previous char (needed for unescaping)
    00081     Stream *comms;                    // Serial data stream
    00082
    00083     char command_separator;           // Character indicating end of command (default: ';')
    00084     char field_separator;               // Character indicating end of argument (default: ',')
    00085     char escape_character;          // Character indicating escaping of special chars
    00086
    00087     messengerCallbackFunction default_callback;            // default callback function
    00088     messengerCallbackFunction callbackList[MAXCALLBACKS];  // list of attached callback functions
    00089
    00090
    00091     // **** Initialize ****
    00092
    00093     void init(Stream & comms, const char fld_separator, const char cmd_separator, const char esc_character);
    00094     void reset();
    00095
    00096     // **** Command processing ****
    00097
    00098     inline uint8_t processLine(char serialChar) __attribute__((always_inline));
    00099     inline void handleMessage() __attribute__((always_inline));
    00100     inline bool blockedTillReply(unsigned int timeout = DEFAULT_TIMEOUT, byte ackCmdId = 1) __attribute__((always_inline));
    00101     inline bool checkForAck(byte AckCommand) __attribute__((always_inline));
    00102
    00103     // **** Command sending ****
    00104
    00108     template < class T >
    00109     void writeBin(const T & value)
    00110     {
    00111         const byte *bytePointer = (const byte *)(const void *)&value;
    00112         for (unsigned int i = 0; i < sizeof(value); i++)
    00113         {
    00114             printEsc(*bytePointer);
    00115             bytePointer++;
    00116         }
    00117     }
    00118
    00119     // **** Command receiving ****
    00120
    00121     int findNext(char *str, char delim);
    00122
    00126     template < class T >
    00127     T readBin(char *str)
    00128     {
    00129         T value;
    00130         unescape(str);
    00131         byte *bytePointer = (byte *)(const void *)&value;
    00132         for (unsigned int i = 0; i < sizeof(value); i++)
    00133         {
    00134             *bytePointer = str[i];
    00135             bytePointer++;
    00136         }
    00137         return value;
    00138     }
    00139
    00140     template < class T >
    00141     T empty()
    00142     {
    00143         T value;
    00144         byte *bytePointer = (byte *)(const void *)&value;
    00145         for (unsigned int i = 0; i < sizeof(value); i++)
    00146         {
    00147             *bytePointer = '\0';
    00148             bytePointer++;
    00149         }
    00150         return value;
    00151     }
    00152
    00153     // **** Escaping tools ****
    00154
    00155     char *split_r(char *str, const char delim, char **nextp);
    00156     bool isEscaped(char *currChar, const char escapeChar, char *lastChar);
    00157
    00158     void printEsc(char *str);
    00159     void printEsc(char str);
    00160
    00161 public:
    00162
    00163     // ****** Public functions ******
    00164
    00165     // **** Initialization ****
    00166
    00167     CmdMessenger(Stream & comms, const char fld_separator = ',',
    00168         const char cmd_separator = ';',
    00169         const char esc_character = '/');
    00170
    00171     void printLfCr(bool addNewLine = true);
    00172     void attach(messengerCallbackFunction newFunction);
    00173     void attach(byte msgId, messengerCallbackFunction newFunction);
    00174
    00175     // **** Command processing ****
    00176
    00177     void feedinSerialData();
    00178     bool next();
    00179     bool available();
    00180     bool isArgOk();
    00181     uint8_t commandID();
    00182
    00183     // ****  Command sending ****
    00184
    00189     template < class T >
    00190     bool sendCmd(byte cmdId, T arg, bool reqAc = false, byte ackCmdId = 1,
    00191         unsigned int timeout = DEFAULT_TIMEOUT)
    00192     {
    00193         if (!startCommand) {
    00194             sendCmdStart(cmdId);
    00195             sendCmdArg(arg);
    00196             return sendCmdEnd(reqAc, ackCmdId, timeout);
    00197         }
    00198         return false;
    00199     }
    00200
    00205     template < class T >
    00206     bool sendBinCmd(byte cmdId, T arg, bool reqAc = false, byte ackCmdId = 1,
    00207         unsigned int timeout = DEFAULT_TIMEOUT)
    00208     {
    00209         if (!startCommand) {
    00210             sendCmdStart(cmdId);
    00211             sendCmdBinArg(arg);
    00212             return sendCmdEnd(reqAc, ackCmdId, timeout);
    00213         }
    00214         return false;
    00215     }
    00216
    00217     bool sendCmd(byte cmdId);
    00218     bool sendCmd(byte cmdId, bool reqAc, byte ackCmdId);
    00219     // **** Command sending with multiple arguments ****
    00220
    00221     void sendCmdStart(byte cmdId);
    00222     void sendCmdEscArg(char *arg);
    00223     void sendCmdfArg(char *fmt, ...);
    00224     bool sendCmdEnd(bool reqAc = false, byte ackCmdId = 1, unsigned int timeout = DEFAULT_TIMEOUT);
    00225
    00230     template < class T > void sendCmdArg(T arg)
    00231     {
    00232         if (startCommand) {
    00233             comms->print(field_separator);
    00234             comms->print(arg);
    00235         }
    00236     }
    00237
    00242     template < class T > void sendCmdArg(T arg, unsigned int n)
    00243     {
    00244         if (startCommand) {
    00245             comms->print(field_separator);
    00246             comms->print(arg, n);
    00247         }
    00248     }
    00249
    00254     void sendCmdSciArg(double arg, unsigned int n = 6);
    00255
    00256
    00261     template < class T > void sendCmdBinArg(T arg)
    00262     {
    00263         if (startCommand) {
    00264             comms->print(field_separator);
    00265             writeBin(arg);
    00266         }
    00267     }
    00268
    00269     // **** Command receiving ****
    00270     bool readBoolArg();
    00271     int16_t readInt16Arg();
    00272     int32_t readInt32Arg();
    00273     char readCharArg();
    00274     float readFloatArg();
    00275     double readDoubleArg();
    00276     char *readStringArg();
    00277     void copyStringArg(char *string, uint8_t size);
    00278     uint8_t compareStringArg(char *string);
    00279
    00283     template < class T > T readBinArg()
    00284     {
    00285         if (next()) {
    00286             dumped = true;
    00287             return readBin < T >(current);
    00288         }
    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