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); }
CommandServer.cpp@1:855efbf6d7ae, 2014-09-03 (annotated)
- Committer:
- rominos2
- Date:
- Wed Sep 03 09:50:45 2014 +0000
- Revision:
- 1:855efbf6d7ae
- Parent:
- 0:1bfd6f4c0dbb
- Child:
- 3:8784fbd35d29
Change Library name for better understanding.; Modified some data types for better reading.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rominos2 | 0:1bfd6f4c0dbb | 1 | #include "mbed.h" |
rominos2 | 1:855efbf6d7ae | 2 | #include "CommandDispatcher.h" |
rominos2 | 0:1bfd6f4c0dbb | 3 | |
rominos2 | 1:855efbf6d7ae | 4 | CommandDispatcher::CommandDispatcher() : _first_command(NULL) { |
rominos2 | 0:1bfd6f4c0dbb | 5 | } |
rominos2 | 0:1bfd6f4c0dbb | 6 | |
rominos2 | 1:855efbf6d7ae | 7 | void CommandDispatcher::addCommand(char* commandName, void(*command_function)(unsigned int argc, char* argv[], char* result)) { |
rominos2 | 1:855efbf6d7ae | 8 | CommandDispatcher::Command* com = new CommandDispatcher::Command(); |
rominos2 | 0:1bfd6f4c0dbb | 9 | strcpy(com->_name, commandName); |
rominos2 | 0:1bfd6f4c0dbb | 10 | com->_function = command_function; |
rominos2 | 0:1bfd6f4c0dbb | 11 | com->_next = _first_command; |
rominos2 | 0:1bfd6f4c0dbb | 12 | _first_command = com; |
rominos2 | 0:1bfd6f4c0dbb | 13 | } |
rominos2 | 0:1bfd6f4c0dbb | 14 | |
rominos2 | 1:855efbf6d7ae | 15 | void CommandDispatcher::cleanCommands() { |
rominos2 | 1:855efbf6d7ae | 16 | CommandDispatcher::Command* com = _first_command; |
rominos2 | 0:1bfd6f4c0dbb | 17 | while (com!=NULL) { |
rominos2 | 0:1bfd6f4c0dbb | 18 | _first_command = com->_next; |
rominos2 | 0:1bfd6f4c0dbb | 19 | delete com; |
rominos2 | 0:1bfd6f4c0dbb | 20 | } |
rominos2 | 0:1bfd6f4c0dbb | 21 | } |
rominos2 | 0:1bfd6f4c0dbb | 22 | |
rominos2 | 1:855efbf6d7ae | 23 | bool CommandDispatcher::executeCommand(char* command, char* result) { |
rominos2 | 1:855efbf6d7ae | 24 | CommandDispatcher::Command* command_ptr; |
rominos2 | 0:1bfd6f4c0dbb | 25 | bool function_return = false; |
rominos2 | 1:855efbf6d7ae | 26 | unsigned int argc; |
rominos2 | 0:1bfd6f4c0dbb | 27 | char** argv; |
rominos2 | 0:1bfd6f4c0dbb | 28 | char* buffer; |
rominos2 | 0:1bfd6f4c0dbb | 29 | |
rominos2 | 0:1bfd6f4c0dbb | 30 | buffer = new char[strlen(command)+1]; // + 1 for the \0 |
rominos2 | 0:1bfd6f4c0dbb | 31 | strcpy(buffer, command); |
rominos2 | 0:1bfd6f4c0dbb | 32 | |
rominos2 | 0:1bfd6f4c0dbb | 33 | argc = parse_buffer(buffer, &argv); |
rominos2 | 0:1bfd6f4c0dbb | 34 | toLowerCase(argv[0]); |
rominos2 | 0:1bfd6f4c0dbb | 35 | |
rominos2 | 0:1bfd6f4c0dbb | 36 | for (command_ptr=_first_command; command_ptr!=NULL; command_ptr = command_ptr->_next) { |
rominos2 | 0:1bfd6f4c0dbb | 37 | if (strcmp(argv[0], command_ptr->_name)==0) { |
rominos2 | 0:1bfd6f4c0dbb | 38 | command_ptr->_function(argc, argv, result); |
rominos2 | 0:1bfd6f4c0dbb | 39 | function_return = true; |
rominos2 | 0:1bfd6f4c0dbb | 40 | break; |
rominos2 | 0:1bfd6f4c0dbb | 41 | } |
rominos2 | 0:1bfd6f4c0dbb | 42 | } |
rominos2 | 0:1bfd6f4c0dbb | 43 | |
rominos2 | 0:1bfd6f4c0dbb | 44 | delete[] argv; |
rominos2 | 0:1bfd6f4c0dbb | 45 | delete[] buffer; |
rominos2 | 0:1bfd6f4c0dbb | 46 | return function_return; |
rominos2 | 0:1bfd6f4c0dbb | 47 | } |
rominos2 | 0:1bfd6f4c0dbb | 48 | |
rominos2 | 1:855efbf6d7ae | 49 | int CommandDispatcher::parse_buffer(char* buffer, char*** argv) { |
rominos2 | 1:855efbf6d7ae | 50 | unsigned int i; |
rominos2 | 1:855efbf6d7ae | 51 | unsigned int word_count; |
rominos2 | 1:855efbf6d7ae | 52 | bool letter_found; |
rominos2 | 1:855efbf6d7ae | 53 | unsigned int buffer_size = strlen(buffer); |
rominos2 | 1:855efbf6d7ae | 54 | unsigned int argc; |
rominos2 | 0:1bfd6f4c0dbb | 55 | char** argv_tab; |
rominos2 | 0:1bfd6f4c0dbb | 56 | |
rominos2 | 0:1bfd6f4c0dbb | 57 | // 1st cycle, counting the number of words |
rominos2 | 1:855efbf6d7ae | 58 | letter_found = false; |
rominos2 | 0:1bfd6f4c0dbb | 59 | word_count = 0; |
rominos2 | 0:1bfd6f4c0dbb | 60 | for (i=0; i<buffer_size; i++) { |
rominos2 | 0:1bfd6f4c0dbb | 61 | if (buffer[i]==' ' && letter_found) { |
rominos2 | 0:1bfd6f4c0dbb | 62 | word_count++; |
rominos2 | 1:855efbf6d7ae | 63 | letter_found=false; |
rominos2 | 1:855efbf6d7ae | 64 | } else letter_found=true; |
rominos2 | 0:1bfd6f4c0dbb | 65 | } |
rominos2 | 1:855efbf6d7ae | 66 | if (letter_found) word_count++; // to get last word |
rominos2 | 0:1bfd6f4c0dbb | 67 | |
rominos2 | 0:1bfd6f4c0dbb | 68 | // create the array of words |
rominos2 | 0:1bfd6f4c0dbb | 69 | argv_tab = new char*[word_count]; |
rominos2 | 0:1bfd6f4c0dbb | 70 | argc = word_count; |
rominos2 | 0:1bfd6f4c0dbb | 71 | |
rominos2 | 0:1bfd6f4c0dbb | 72 | // 2nd cycle, putting words into the array |
rominos2 | 1:855efbf6d7ae | 73 | letter_found = false; |
rominos2 | 0:1bfd6f4c0dbb | 74 | word_count = 0; |
rominos2 | 0:1bfd6f4c0dbb | 75 | for (i=0; i<buffer_size; i++) { |
rominos2 | 0:1bfd6f4c0dbb | 76 | if (buffer[i]==' ') { |
rominos2 | 0:1bfd6f4c0dbb | 77 | buffer[i] = '\0'; |
rominos2 | 1:855efbf6d7ae | 78 | letter_found = false; |
rominos2 | 0:1bfd6f4c0dbb | 79 | } else if (!letter_found) { |
rominos2 | 0:1bfd6f4c0dbb | 80 | argv_tab[word_count++]=&buffer[i]; |
rominos2 | 1:855efbf6d7ae | 81 | letter_found=true; |
rominos2 | 0:1bfd6f4c0dbb | 82 | } |
rominos2 | 0:1bfd6f4c0dbb | 83 | } |
rominos2 | 0:1bfd6f4c0dbb | 84 | |
rominos2 | 0:1bfd6f4c0dbb | 85 | *argv = argv_tab; |
rominos2 | 0:1bfd6f4c0dbb | 86 | return argc; |
rominos2 | 0:1bfd6f4c0dbb | 87 | } |
rominos2 | 0:1bfd6f4c0dbb | 88 | |
rominos2 | 1:855efbf6d7ae | 89 | void CommandDispatcher::toLowerCase(char* word) { |
rominos2 | 0:1bfd6f4c0dbb | 90 | int i; |
rominos2 | 0:1bfd6f4c0dbb | 91 | for (i=0; i<strlen(word); i++) { |
rominos2 | 0:1bfd6f4c0dbb | 92 | if (word[i]>=65 && word[i]<=90) { // if between A-Z |
rominos2 | 0:1bfd6f4c0dbb | 93 | word[i] += 32; |
rominos2 | 0:1bfd6f4c0dbb | 94 | } |
rominos2 | 0:1bfd6f4c0dbb | 95 | } |
rominos2 | 0:1bfd6f4c0dbb | 96 | } |