A light Command Dispatcher Library with commands linked to your functions.
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); }
Revision 0:1bfd6f4c0dbb, committed 2014-09-02
- 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