A light Command Dispatcher Library with commands linked to your functions.

Dependents:   Rocket

You can register your commands and the functions linked.
On each execution of a command (char array), it will parse the array and send all the parameters to the functions.

Here is a quick example :

#include "mbed.h"
#include "CommandDispatcher.h"
    
Serial pc(USBTX, USBRX);

void echoCommand(unsigned int argc, char* argv[], char* result);
    
int main() {
    CommandDispatcher disp = CommandDispatcher();
    char buffer[50];
    char result[50];
    int i=0;
    
    // register a command
    disp.addCommand("echo", echoCommand);
    pc.printf("Example Command Dispatcher\n\n");

    while(true) {
        // get a complete line from serial
        buffer[i++] = pc.getc();
        if (buffer[i-1]=='\n') {
            buffer[i-1]='\0';
            i=0;
        
            // send it to the dispatcher and print result
            if (disp.executeCommand(buffer, result)) {
                pc.printf("%s\n", result); 
            } else {
                pc.printf("Command not found.\n");  
            }
        }
    }
}

// the actual function called
void echoCommand(unsigned int argc, char* argv[], char* result) {
    int i;
    sprintf(result, "");
    for (i=1; i<argc; i++) {
        sprintf(result, "%s %s", result, argv[i]);
    }
    sprintf(result, "%s\n", result);
}

Files at this revision

API Documentation at this revision

Comitter:
rominos2
Date:
Tue Sep 02 22:07:18 2014 +0000
Child:
1:855efbf6d7ae
Commit message:
Initial Release

Changed in this revision

CommandServer.cpp Show annotated file Show diff for this revision Revisions of this file
CommandServer.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CommandServer.cpp	Tue Sep 02 22:07:18 2014 +0000
@@ -0,0 +1,98 @@
+#include "mbed.h"
+#include "CommandServer.h"
+
+extern Serial pc;
+
+CommandServer::CommandServer() : _first_command(NULL) {
+}
+
+void CommandServer::addCommand(char* commandName, void(*command_function)(int argc, char* argv[], char* result)) {
+    CommandServer::Command* com = new CommandServer::Command();
+    strcpy(com->_name, commandName);
+    com->_function = command_function;
+    com->_next = _first_command;
+    _first_command = com;
+}
+
+void CommandServer::cleanCommands() {
+    CommandServer::Command* com = _first_command;
+    while (com!=NULL) {
+        _first_command = com->_next;
+        delete com;
+    }
+}
+
+bool CommandServer::executeCommand(char* command, char* result) {
+    CommandServer::Command* command_ptr;
+    bool function_return = false;
+    int argc;
+    char** argv;
+    char* buffer;
+    
+    buffer = new char[strlen(command)+1]; // + 1 for the \0
+    strcpy(buffer, command);
+    
+    argc = parse_buffer(buffer, &argv);
+    toLowerCase(argv[0]);
+
+    for (command_ptr=_first_command; command_ptr!=NULL; command_ptr = command_ptr->_next) {
+        if (strcmp(argv[0], command_ptr->_name)==0) {
+            command_ptr->_function(argc, argv, result);
+            function_return = true;
+            break;
+        }    
+    }
+    
+    delete[] argv;
+    delete[] buffer;
+    return function_return;
+}
+
+int CommandServer::parse_buffer(char* buffer, char*** argv) {
+    int i;
+    int word_count;
+    int letter_found;
+    int buffer_size = strlen(buffer);
+    int argc;
+    char** argv_tab;
+    
+    // 1st cycle, counting the number of words
+    letter_found = 0;
+    word_count = 0;
+    for (i=0; i<buffer_size; i++) {
+        if (buffer[i]==' ' && letter_found) {
+            word_count++;
+            letter_found=0;
+        } else letter_found=1;
+    }
+    if (letter_found!=0) word_count++; // to get last word
+
+    // create the array of words
+    argv_tab = new char*[word_count];
+    argc = word_count;
+    
+    // 2nd cycle, putting words into the array
+    letter_found = 0;
+    word_count = 0;
+    for (i=0; i<buffer_size; i++) {
+        if (buffer[i]==' ') {
+            buffer[i] = '\0';
+            letter_found = 0;  
+        } else if (!letter_found) {
+             argv_tab[word_count++]=&buffer[i];
+             letter_found=1;
+        }
+    }
+    
+    *argv = argv_tab;
+    return argc;
+}
+
+void CommandServer::toLowerCase(char* word) {
+    int i;
+    for (i=0; i<strlen(word); i++) {
+        if (word[i]>=65 && word[i]<=90) { // if between A-Z
+            word[i] += 32;
+        }    
+    }   
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CommandServer.h	Tue Sep 02 22:07:18 2014 +0000
@@ -0,0 +1,95 @@
+#include "mbed.h"
+
+#define MAX_ARG_SIZE 20
+#define DEFAULT_BUFFER_SIZE 50
+
+/** A  light Command Server Library \n
+    You can register your commands and the functions linked. \n
+    On each execution of a command (char array), it will parse the array and send all the parameters to the functions. \n
+    Here is an quick example class that to show the purpose of this library.
+    @code
+    #include "mbed.h"
+    #include "CommandServer.h"
+    
+    Serial pc(USBTX, USBRX);
+
+    void echoCommand(int argc, char* argv[], char* result);
+    
+    int main() {
+        CommandServer server = CommandServer();
+        char buffer[50];
+        char result[50];
+        int i=0;
+    
+        server.addCommand("echo", echoCommand);
+        pc.printf("Example Command Server\n\n");
+
+        while(true) {  
+            buffer[i++] = pc.getc();
+            if (buffer[i-1]=='\n') {
+                buffer[i-1]='\0';
+                i=0;
+            
+                if (server.executeCommand(buffer, result)) {
+                    pc.printf("%s\n", result); 
+                } else {
+                    pc.printf("Command not found.\n");  
+                }
+            }
+        }
+    }
+    
+    void echoCommand(int argc, char* argv[], char* result) {
+        int i;
+        sprintf(result, "");
+        for (i=1; i<argc; i++) {
+            sprintf(result, "%s %s", result, argv[i]);
+        }
+        sprintf(result, "%s\n", result);
+    }
+    @endcode
+*/
+class CommandServer {
+private:
+    class Command {
+    private:
+        char _name[MAX_ARG_SIZE];
+        void(*_function)(int argc, char* argv[], char* result);
+        Command* _next;
+
+        friend class CommandServer;
+    };
+    
+    CommandServer::Command* _first_command;
+    
+    int parse_buffer(char* buffer, char*** argv);
+    
+public:
+    /** Constructor of the Command Server  
+    */
+    CommandServer();
+    
+    /** Add a command to the Server.
+        @param commandName the name of the command. Not case sensitive.
+        @param commandFunction the pointer to the function called when function is executed. \n
+            The 2 first parameters are liked a C code main (number and value of arguments). \n
+            The last (result) is got on command execution and transport a potential result to the executor. \n
+    */
+    void addCommand(char* commandName, void(*commandFunction)(int argc, char* argv[], char* result));
+    /** Clean all the commands (free memory allocated).
+    */
+    void cleanCommands();
+    
+    /** Execute a command. It will check each registered command with its name.
+        @param command the command with the arguments in a single char array.
+        @param result a char array alocated by the user and sent to the function for feedback use.
+    */
+    bool executeCommand(char* command, char* result);
+
+    /** A Utility function to transform a char array to lower case (useful for argument checks). \n
+            WARNING : This function modifies the word.
+        @param word the word to modify.
+        
+    */
+    static void toLowerCase(char* word);
+};
\ No newline at end of file