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);
}

CommandServer.cpp

Committer:
rominos2
Date:
2014-09-03
Revision:
1:855efbf6d7ae
Parent:
0:1bfd6f4c0dbb
Child:
3:8784fbd35d29

File content as of revision 1:855efbf6d7ae:

#include "mbed.h"
#include "CommandDispatcher.h"

CommandDispatcher::CommandDispatcher() : _first_command(NULL) {
}

void CommandDispatcher::addCommand(char* commandName, void(*command_function)(unsigned int argc, char* argv[], char* result)) {
    CommandDispatcher::Command* com = new CommandDispatcher::Command();
    strcpy(com->_name, commandName);
    com->_function = command_function;
    com->_next = _first_command;
    _first_command = com;
}

void CommandDispatcher::cleanCommands() {
    CommandDispatcher::Command* com = _first_command;
    while (com!=NULL) {
        _first_command = com->_next;
        delete com;
    }
}

bool CommandDispatcher::executeCommand(char* command, char* result) {
    CommandDispatcher::Command* command_ptr;
    bool function_return = false;
    unsigned 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 CommandDispatcher::parse_buffer(char* buffer, char*** argv) {
    unsigned int i;
    unsigned int word_count;
    bool letter_found;
    unsigned int buffer_size = strlen(buffer);
    unsigned int argc;
    char** argv_tab;
    
    // 1st cycle, counting the number of words
    letter_found = false;
    word_count = 0;
    for (i=0; i<buffer_size; i++) {
        if (buffer[i]==' ' && letter_found) {
            word_count++;
            letter_found=false;
        } else letter_found=true;
    }
    if (letter_found) 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 = false;
    word_count = 0;
    for (i=0; i<buffer_size; i++) {
        if (buffer[i]==' ') {
            buffer[i] = '\0';
            letter_found = false;  
        } else if (!letter_found) {
             argv_tab[word_count++]=&buffer[i];
             letter_found=true;
        }
    }
    
    *argv = argv_tab;
    return argc;
}

void CommandDispatcher::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;
        }    
    }   
}