This CLI (Command Line Interface) is based mbed-os. Both NNN50 and NQ620 are supported.
Fork of NNN40_CLI by
BLE CLI Document can be downloaded here .
Note that when evaluate using Windows PC as the host, the Serial driver need to be installed in advance. The instruction is explained in the link below
https://developer.mbed.org/handbook/Windows-serial-configuration
Once installed, a device called 'mbed Serial Port (COM#)' should be recognized in Device Manager, as shown below
Please open the com port at 115200 8n1 as default
CLI_Source/command-interpreter.cpp@5:ee474e3133eb, 2015-12-09 (annotated)
- Committer:
- gillwei7
- Date:
- Wed Dec 09 11:31:59 2015 +0000
- Revision:
- 5:ee474e3133eb
- Parent:
- 3:38ec8ad317f4
- Child:
- 9:ff3ccba5dc16
Gill Wei 20151209, add Wifi device commands for WIFI_32KRAM driver, add BLE central mode command.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gillwei7 | 0:5c195ab2f696 | 1 | /** |
gillwei7 | 0:5c195ab2f696 | 2 | * File: command-interpreter.c |
gillwei7 | 0:5c195ab2f696 | 3 | * Description: processes commands incoming over the serial port. |
gillwei7 | 0:5c195ab2f696 | 4 | * |
gillwei7 | 0:5c195ab2f696 | 5 | * Copyright 2014 by CYNTEC Corporation. All rights reserved. |
gillwei7 | 0:5c195ab2f696 | 6 | */ |
gillwei7 | 0:5c195ab2f696 | 7 | |
gillwei7 | 0:5c195ab2f696 | 8 | #include <stdint.h> |
gillwei7 | 0:5c195ab2f696 | 9 | #include <string.h> |
gillwei7 | 0:5c195ab2f696 | 10 | #include "mbed.h" |
gillwei7 | 0:5c195ab2f696 | 11 | #include "command-interpreter.h" |
gillwei7 | 0:5c195ab2f696 | 12 | |
gillwei7 | 0:5c195ab2f696 | 13 | extern Serial console; |
gillwei7 | 0:5c195ab2f696 | 14 | |
gillwei7 | 0:5c195ab2f696 | 15 | // Command parsing state |
gillwei7 | 0:5c195ab2f696 | 16 | typedef struct { |
gillwei7 | 0:5c195ab2f696 | 17 | |
gillwei7 | 0:5c195ab2f696 | 18 | // Finite-state machine's current state. |
gillwei7 | 0:5c195ab2f696 | 19 | uint8_t state; |
gillwei7 | 0:5c195ab2f696 | 20 | |
gillwei7 | 0:5c195ab2f696 | 21 | // The command line is stored in this buffer. |
gillwei7 | 0:5c195ab2f696 | 22 | uint8_t buffer[CYNTEC_COMMAND_BUFFER_LENGTH]; |
gillwei7 | 0:5c195ab2f696 | 23 | |
gillwei7 | 0:5c195ab2f696 | 24 | // Indices of the tokens (command(s) and arguments) in the above buffer. |
gillwei7 | 0:5c195ab2f696 | 25 | uint8_t tokenIndices[MAX_TOKEN_COUNT]; |
gillwei7 | 0:5c195ab2f696 | 26 | |
gillwei7 | 0:5c195ab2f696 | 27 | // The number of tokens read in, including the command(s). |
gillwei7 | 0:5c195ab2f696 | 28 | uint8_t tokenCount; |
gillwei7 | 0:5c195ab2f696 | 29 | |
gillwei7 | 0:5c195ab2f696 | 30 | // Used while reading in the command line. |
gillwei7 | 0:5c195ab2f696 | 31 | uint8_t index; |
gillwei7 | 0:5c195ab2f696 | 32 | |
gillwei7 | 0:5c195ab2f696 | 33 | // First error found in this command. |
gillwei7 | 0:5c195ab2f696 | 34 | uint8_t error; |
gillwei7 | 0:5c195ab2f696 | 35 | |
gillwei7 | 0:5c195ab2f696 | 36 | // The token number of the first true argument after possible nested commands. |
gillwei7 | 0:5c195ab2f696 | 37 | uint8_t argOffset; |
gillwei7 | 0:5c195ab2f696 | 38 | |
gillwei7 | 0:5c195ab2f696 | 39 | //gill |
gillwei7 | 0:5c195ab2f696 | 40 | uint8_t totalBuffer[CYNTEC_COMMAND_BUFFER_LENGTH]; |
gillwei7 | 0:5c195ab2f696 | 41 | uint8_t totalIndex; |
gillwei7 | 0:5c195ab2f696 | 42 | |
gillwei7 | 0:5c195ab2f696 | 43 | } CyntecCommandState; |
gillwei7 | 0:5c195ab2f696 | 44 | |
gillwei7 | 0:5c195ab2f696 | 45 | static CyntecCommandState commandState; |
gillwei7 | 0:5c195ab2f696 | 46 | |
gillwei7 | 0:5c195ab2f696 | 47 | // Remember the previous character seen by emberProcessCommandString() to ignore |
gillwei7 | 0:5c195ab2f696 | 48 | // an LF following a CR. |
gillwei7 | 0:5c195ab2f696 | 49 | static uint8_t previousCharacter = 0; |
gillwei7 | 0:5c195ab2f696 | 50 | CyntecCommandEntry *cyntecCurrentCommand; |
gillwei7 | 0:5c195ab2f696 | 51 | |
gillwei7 | 0:5c195ab2f696 | 52 | enum { |
gillwei7 | 0:5c195ab2f696 | 53 | CMD_AWAITING_ARGUMENT, |
gillwei7 | 0:5c195ab2f696 | 54 | CMD_READING_ARGUMENT, |
gillwei7 | 0:5c195ab2f696 | 55 | CMD_READING_TO_EOL // clean up after error |
gillwei7 | 0:5c195ab2f696 | 56 | }; |
gillwei7 | 0:5c195ab2f696 | 57 | |
gillwei7 | 0:5c195ab2f696 | 58 | |
gillwei7 | 0:5c195ab2f696 | 59 | |
gillwei7 | 0:5c195ab2f696 | 60 | const char* cyntecCommandErrorNames[] = |
gillwei7 | 0:5c195ab2f696 | 61 | { |
gillwei7 | 0:5c195ab2f696 | 62 | "", |
gillwei7 | 0:5c195ab2f696 | 63 | "No such command;", |
gillwei7 | 0:5c195ab2f696 | 64 | "Wrong number of arguments;", |
gillwei7 | 0:5c195ab2f696 | 65 | "Argument out of range;", |
gillwei7 | 0:5c195ab2f696 | 66 | "Argument syntax error;", |
gillwei7 | 0:5c195ab2f696 | 67 | "No matched argument;", |
gillwei7 | 5:ee474e3133eb | 68 | "Wrong command order;", |
gillwei7 | 5:ee474e3133eb | 69 | "Invalid state to perform operation;", |
gillwei7 | 0:5c195ab2f696 | 70 | "Function call fail;" |
gillwei7 | 0:5c195ab2f696 | 71 | }; |
gillwei7 | 0:5c195ab2f696 | 72 | |
gillwei7 | 0:5c195ab2f696 | 73 | /** |
gillwei7 | 0:5c195ab2f696 | 74 | * @brief Converts a character representation of a hex to real value. |
gillwei7 | 0:5c195ab2f696 | 75 | * @param c is the hex value in char format |
gillwei7 | 0:5c195ab2f696 | 76 | * @return the value of the hex otherwise INVALID_HEX_CHARACTER |
gillwei7 | 0:5c195ab2f696 | 77 | */ |
gillwei7 | 0:5c195ab2f696 | 78 | |
gillwei7 | 0:5c195ab2f696 | 79 | uint8_t cyntecAtoi(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 80 | { |
gillwei7 | 0:5c195ab2f696 | 81 | uint8_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 82 | uint8_t i = 0; |
gillwei7 | 0:5c195ab2f696 | 83 | |
gillwei7 | 0:5c195ab2f696 | 84 | while( *str != '\0' && i < len) |
gillwei7 | 0:5c195ab2f696 | 85 | { |
gillwei7 | 0:5c195ab2f696 | 86 | result *= 10; |
gillwei7 | 0:5c195ab2f696 | 87 | result = result + ( *str - '0' ); |
gillwei7 | 0:5c195ab2f696 | 88 | str++; |
gillwei7 | 0:5c195ab2f696 | 89 | i++; |
gillwei7 | 0:5c195ab2f696 | 90 | } |
gillwei7 | 0:5c195ab2f696 | 91 | |
gillwei7 | 0:5c195ab2f696 | 92 | return result; |
gillwei7 | 0:5c195ab2f696 | 93 | } |
gillwei7 | 0:5c195ab2f696 | 94 | |
gillwei7 | 0:5c195ab2f696 | 95 | uint8_t cyntecArgToUint8(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 96 | { |
gillwei7 | 0:5c195ab2f696 | 97 | uint8_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 98 | uint8_t num[2]; |
gillwei7 | 0:5c195ab2f696 | 99 | uint8_t i; |
gillwei7 | 0:5c195ab2f696 | 100 | |
gillwei7 | 0:5c195ab2f696 | 101 | if ( len != 2 ) |
gillwei7 | 0:5c195ab2f696 | 102 | { |
gillwei7 | 0:5c195ab2f696 | 103 | return 0; |
gillwei7 | 0:5c195ab2f696 | 104 | } |
gillwei7 | 0:5c195ab2f696 | 105 | |
gillwei7 | 0:5c195ab2f696 | 106 | for ( i = 0 ; i < 2 ; i++ ) |
gillwei7 | 0:5c195ab2f696 | 107 | { |
gillwei7 | 0:5c195ab2f696 | 108 | if ('0' <= str[i] && str[i] <= '9') |
gillwei7 | 0:5c195ab2f696 | 109 | num[i] = str[i] - '0'; |
gillwei7 | 0:5c195ab2f696 | 110 | else if ('a' <= str[i] && str[i] <= 'f') |
gillwei7 | 0:5c195ab2f696 | 111 | num[i] = str[i] - 'a' + 10; |
gillwei7 | 0:5c195ab2f696 | 112 | else if ('A' <= str[i] && str[i] <= 'F') |
gillwei7 | 0:5c195ab2f696 | 113 | num[i] = str[i] - 'A' + 10; |
gillwei7 | 0:5c195ab2f696 | 114 | else |
gillwei7 | 0:5c195ab2f696 | 115 | return 0; |
gillwei7 | 0:5c195ab2f696 | 116 | } |
gillwei7 | 0:5c195ab2f696 | 117 | |
gillwei7 | 0:5c195ab2f696 | 118 | result |= num[0] << 4; |
gillwei7 | 0:5c195ab2f696 | 119 | result |= num[1] << 0; |
gillwei7 | 0:5c195ab2f696 | 120 | |
gillwei7 | 0:5c195ab2f696 | 121 | return result; |
gillwei7 | 0:5c195ab2f696 | 122 | } |
gillwei7 | 0:5c195ab2f696 | 123 | |
gillwei7 | 0:5c195ab2f696 | 124 | uint16_t cyntecAtoiUint16(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 125 | { |
gillwei7 | 0:5c195ab2f696 | 126 | uint16_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 127 | uint16_t i = 0; |
gillwei7 | 0:5c195ab2f696 | 128 | |
gillwei7 | 0:5c195ab2f696 | 129 | while( *str != '\0' && i < len) |
gillwei7 | 0:5c195ab2f696 | 130 | { |
gillwei7 | 0:5c195ab2f696 | 131 | result *= 10; |
gillwei7 | 0:5c195ab2f696 | 132 | result = result + ( *str - '0' ); |
gillwei7 | 0:5c195ab2f696 | 133 | str++; |
gillwei7 | 0:5c195ab2f696 | 134 | i++; |
gillwei7 | 0:5c195ab2f696 | 135 | } |
gillwei7 | 0:5c195ab2f696 | 136 | |
gillwei7 | 0:5c195ab2f696 | 137 | return result; |
gillwei7 | 0:5c195ab2f696 | 138 | } |
gillwei7 | 0:5c195ab2f696 | 139 | |
gillwei7 | 0:5c195ab2f696 | 140 | uint16_t cyntecArgToUint16(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 141 | { |
gillwei7 | 0:5c195ab2f696 | 142 | uint16_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 143 | uint8_t num[4]; |
gillwei7 | 0:5c195ab2f696 | 144 | uint8_t i; |
gillwei7 | 0:5c195ab2f696 | 145 | |
gillwei7 | 0:5c195ab2f696 | 146 | if ( len != 4 ) |
gillwei7 | 0:5c195ab2f696 | 147 | { |
gillwei7 | 0:5c195ab2f696 | 148 | return 0; |
gillwei7 | 0:5c195ab2f696 | 149 | } |
gillwei7 | 0:5c195ab2f696 | 150 | |
gillwei7 | 0:5c195ab2f696 | 151 | for ( i = 0 ; i < 4 ; i++ ) |
gillwei7 | 0:5c195ab2f696 | 152 | { |
gillwei7 | 0:5c195ab2f696 | 153 | if ('0' <= str[i] && str[i] <= '9') |
gillwei7 | 0:5c195ab2f696 | 154 | num[i] = str[i] - '0'; |
gillwei7 | 0:5c195ab2f696 | 155 | else if ('a' <= str[i] && str[i] <= 'f') |
gillwei7 | 0:5c195ab2f696 | 156 | num[i] = str[i] - 'a' + 10; |
gillwei7 | 0:5c195ab2f696 | 157 | else if ('A' <= str[i] && str[i] <= 'F') |
gillwei7 | 0:5c195ab2f696 | 158 | num[i] = str[i] - 'A' + 10; |
gillwei7 | 0:5c195ab2f696 | 159 | else |
gillwei7 | 0:5c195ab2f696 | 160 | return 0; |
gillwei7 | 0:5c195ab2f696 | 161 | } |
gillwei7 | 0:5c195ab2f696 | 162 | |
gillwei7 | 0:5c195ab2f696 | 163 | result |= num[0] << 12; |
gillwei7 | 0:5c195ab2f696 | 164 | result |= num[1] << 8; |
gillwei7 | 0:5c195ab2f696 | 165 | result |= num[2] << 4; |
gillwei7 | 0:5c195ab2f696 | 166 | result |= num[3] << 0; |
gillwei7 | 0:5c195ab2f696 | 167 | |
gillwei7 | 0:5c195ab2f696 | 168 | return result; |
gillwei7 | 0:5c195ab2f696 | 169 | } |
gillwei7 | 0:5c195ab2f696 | 170 | |
gillwei7 | 3:38ec8ad317f4 | 171 | //gill 20150918 |
gillwei7 | 3:38ec8ad317f4 | 172 | uint32_t cyntecHexToUint32(uint8_t *str, uint8_t len) |
gillwei7 | 3:38ec8ad317f4 | 173 | { |
gillwei7 | 3:38ec8ad317f4 | 174 | if (len > 8) |
gillwei7 | 3:38ec8ad317f4 | 175 | return 0; |
gillwei7 | 3:38ec8ad317f4 | 176 | uint32_t result = 0; |
gillwei7 | 3:38ec8ad317f4 | 177 | uint16_t i = 0; |
gillwei7 | 3:38ec8ad317f4 | 178 | |
gillwei7 | 3:38ec8ad317f4 | 179 | while( *str != '\0' && i < len) |
gillwei7 | 3:38ec8ad317f4 | 180 | { |
gillwei7 | 3:38ec8ad317f4 | 181 | result *= 16; |
gillwei7 | 3:38ec8ad317f4 | 182 | result = result + ( *str - '0' ); |
gillwei7 | 3:38ec8ad317f4 | 183 | str++; |
gillwei7 | 3:38ec8ad317f4 | 184 | i++; |
gillwei7 | 3:38ec8ad317f4 | 185 | } |
gillwei7 | 3:38ec8ad317f4 | 186 | |
gillwei7 | 3:38ec8ad317f4 | 187 | return result; |
gillwei7 | 3:38ec8ad317f4 | 188 | } |
gillwei7 | 3:38ec8ad317f4 | 189 | |
gillwei7 | 3:38ec8ad317f4 | 190 | |
gillwei7 | 3:38ec8ad317f4 | 191 | |
gillwei7 | 3:38ec8ad317f4 | 192 | |
gillwei7 | 0:5c195ab2f696 | 193 | uint8_t cyntecStrCmp(uint8_t *src, uint8_t *dst, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 194 | { |
gillwei7 | 0:5c195ab2f696 | 195 | uint8_t i = 0; |
gillwei7 | 0:5c195ab2f696 | 196 | |
gillwei7 | 0:5c195ab2f696 | 197 | while ( *src != '\0' && *dst != '\0' && i < len ) |
gillwei7 | 0:5c195ab2f696 | 198 | { |
gillwei7 | 0:5c195ab2f696 | 199 | if ( *src != *dst ) |
gillwei7 | 0:5c195ab2f696 | 200 | return 0; |
gillwei7 | 0:5c195ab2f696 | 201 | i++; |
gillwei7 | 0:5c195ab2f696 | 202 | src++; |
gillwei7 | 0:5c195ab2f696 | 203 | dst++; |
gillwei7 | 0:5c195ab2f696 | 204 | } |
gillwei7 | 0:5c195ab2f696 | 205 | |
gillwei7 | 0:5c195ab2f696 | 206 | return 1; |
gillwei7 | 0:5c195ab2f696 | 207 | } |
gillwei7 | 0:5c195ab2f696 | 208 | |
gillwei7 | 0:5c195ab2f696 | 209 | // Initialize the state machine. |
gillwei7 | 0:5c195ab2f696 | 210 | void cyntecCommandReaderInit(void) |
gillwei7 | 0:5c195ab2f696 | 211 | { |
gillwei7 | 0:5c195ab2f696 | 212 | commandState.state = CMD_AWAITING_ARGUMENT; |
gillwei7 | 0:5c195ab2f696 | 213 | commandState.index = 0; |
gillwei7 | 0:5c195ab2f696 | 214 | commandState.tokenIndices[0] = 0; |
gillwei7 | 0:5c195ab2f696 | 215 | commandState.tokenCount = 0; |
gillwei7 | 0:5c195ab2f696 | 216 | commandState.error = CYNTEC_CMD_SUCCESS; |
gillwei7 | 0:5c195ab2f696 | 217 | commandState.argOffset = 0; |
gillwei7 | 0:5c195ab2f696 | 218 | cyntecCurrentCommand = NULL; |
gillwei7 | 0:5c195ab2f696 | 219 | commandState.totalIndex = 0; //gill |
gillwei7 | 0:5c195ab2f696 | 220 | } |
gillwei7 | 0:5c195ab2f696 | 221 | |
gillwei7 | 0:5c195ab2f696 | 222 | static uint8_t tokenLength(uint8_t num) |
gillwei7 | 0:5c195ab2f696 | 223 | { |
gillwei7 | 0:5c195ab2f696 | 224 | return (commandState.tokenIndices[num + 1] |
gillwei7 | 0:5c195ab2f696 | 225 | - commandState.tokenIndices[num]); |
gillwei7 | 0:5c195ab2f696 | 226 | } |
gillwei7 | 0:5c195ab2f696 | 227 | |
gillwei7 | 0:5c195ab2f696 | 228 | static uint8_t *tokenPointer(uint8_t tokenNum) |
gillwei7 | 0:5c195ab2f696 | 229 | { |
gillwei7 | 0:5c195ab2f696 | 230 | return (commandState.buffer + commandState.tokenIndices[tokenNum]); |
gillwei7 | 0:5c195ab2f696 | 231 | } |
gillwei7 | 0:5c195ab2f696 | 232 | |
gillwei7 | 0:5c195ab2f696 | 233 | void cyntecCommandActionHandler(const CommandAction action) |
gillwei7 | 0:5c195ab2f696 | 234 | { |
gillwei7 | 0:5c195ab2f696 | 235 | (*action)(); |
gillwei7 | 0:5c195ab2f696 | 236 | clearBuffer(); |
gillwei7 | 0:5c195ab2f696 | 237 | } |
gillwei7 | 0:5c195ab2f696 | 238 | |
gillwei7 | 0:5c195ab2f696 | 239 | static bool getNestedCommand(CyntecCommandEntry *entry, |
gillwei7 | 0:5c195ab2f696 | 240 | CyntecCommandEntry **nestedCommand) |
gillwei7 | 0:5c195ab2f696 | 241 | { |
gillwei7 | 0:5c195ab2f696 | 242 | if ( entry -> action == NULL ) { |
gillwei7 | 0:5c195ab2f696 | 243 | *nestedCommand = (CyntecCommandEntry*)entry->subMenu; |
gillwei7 | 0:5c195ab2f696 | 244 | return true; |
gillwei7 | 0:5c195ab2f696 | 245 | } else { |
gillwei7 | 0:5c195ab2f696 | 246 | return false; |
gillwei7 | 0:5c195ab2f696 | 247 | } |
gillwei7 | 0:5c195ab2f696 | 248 | } |
gillwei7 | 0:5c195ab2f696 | 249 | |
gillwei7 | 0:5c195ab2f696 | 250 | static void cyntecPrintCommandUsage(CyntecCommandEntry *entry) |
gillwei7 | 0:5c195ab2f696 | 251 | { |
gillwei7 | 0:5c195ab2f696 | 252 | CyntecCommandEntry *commandFinger; |
gillwei7 | 0:5c195ab2f696 | 253 | |
gillwei7 | 0:5c195ab2f696 | 254 | if (entry == NULL) { |
gillwei7 | 0:5c195ab2f696 | 255 | entry = commandFinger = cyntecCommandTable; |
gillwei7 | 0:5c195ab2f696 | 256 | } else { |
gillwei7 | 0:5c195ab2f696 | 257 | getNestedCommand(entry, &commandFinger); |
gillwei7 | 0:5c195ab2f696 | 258 | |
gillwei7 | 3:38ec8ad317f4 | 259 | console.printf("%s-%s\r\n",entry->name,entry->description); |
gillwei7 | 0:5c195ab2f696 | 260 | } |
gillwei7 | 0:5c195ab2f696 | 261 | |
gillwei7 | 0:5c195ab2f696 | 262 | if ( commandFinger != NULL ) { |
gillwei7 | 0:5c195ab2f696 | 263 | for (; commandFinger->name != NULL; commandFinger++) { |
gillwei7 | 0:5c195ab2f696 | 264 | console.printf("%s - %s\r\n",commandFinger->name,commandFinger->description); |
gillwei7 | 0:5c195ab2f696 | 265 | } |
gillwei7 | 0:5c195ab2f696 | 266 | } |
gillwei7 | 0:5c195ab2f696 | 267 | |
gillwei7 | 0:5c195ab2f696 | 268 | } |
gillwei7 | 0:5c195ab2f696 | 269 | |
gillwei7 | 0:5c195ab2f696 | 270 | void cyntecCommandErrorHandler(uint8_t status) |
gillwei7 | 0:5c195ab2f696 | 271 | { |
gillwei7 | 0:5c195ab2f696 | 272 | console.printf("%s\r\n",cyntecCommandErrorNames[status]); |
gillwei7 | 0:5c195ab2f696 | 273 | cyntecPrintCommandUsage(cyntecCurrentCommand); |
gillwei7 | 0:5c195ab2f696 | 274 | } |
gillwei7 | 0:5c195ab2f696 | 275 | |
gillwei7 | 0:5c195ab2f696 | 276 | static CyntecCommandEntry *commandLookup(CyntecCommandEntry *commandFinger, |
gillwei7 | 0:5c195ab2f696 | 277 | uint8_t tokenNum) |
gillwei7 | 0:5c195ab2f696 | 278 | { |
gillwei7 | 0:5c195ab2f696 | 279 | uint8_t *inputCommand = tokenPointer(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 280 | uint8_t inputLength = tokenLength(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 281 | |
gillwei7 | 0:5c195ab2f696 | 282 | for (; commandFinger->name != NULL; commandFinger++) { |
gillwei7 | 0:5c195ab2f696 | 283 | const char *entryFinger = commandFinger->name; |
gillwei7 | 0:5c195ab2f696 | 284 | uint8_t *inputFinger = inputCommand; |
gillwei7 | 0:5c195ab2f696 | 285 | for (;; entryFinger++, inputFinger++) { |
gillwei7 | 0:5c195ab2f696 | 286 | bool endInput = (inputFinger - inputCommand == inputLength); |
gillwei7 | 0:5c195ab2f696 | 287 | bool endEntry = (*entryFinger == 0); |
gillwei7 | 0:5c195ab2f696 | 288 | if (endInput && endEntry) { |
gillwei7 | 0:5c195ab2f696 | 289 | return commandFinger; // Exact match. |
gillwei7 | 0:5c195ab2f696 | 290 | } else if ((*inputFinger) != (*entryFinger)) { |
gillwei7 | 0:5c195ab2f696 | 291 | break; |
gillwei7 | 0:5c195ab2f696 | 292 | } |
gillwei7 | 0:5c195ab2f696 | 293 | } |
gillwei7 | 0:5c195ab2f696 | 294 | } |
gillwei7 | 0:5c195ab2f696 | 295 | return NULL; |
gillwei7 | 0:5c195ab2f696 | 296 | } |
gillwei7 | 0:5c195ab2f696 | 297 | |
gillwei7 | 0:5c195ab2f696 | 298 | void callCommandAction(void) |
gillwei7 | 0:5c195ab2f696 | 299 | { |
gillwei7 | 0:5c195ab2f696 | 300 | CyntecCommandEntry *commandFinger = cyntecCommandTable; |
gillwei7 | 0:5c195ab2f696 | 301 | uint8_t tokenNum = 0; |
gillwei7 | 0:5c195ab2f696 | 302 | |
gillwei7 | 0:5c195ab2f696 | 303 | if (commandState.tokenCount == 0) { |
gillwei7 | 0:5c195ab2f696 | 304 | cyntecCommandReaderInit(); |
gillwei7 | 0:5c195ab2f696 | 305 | return; |
gillwei7 | 0:5c195ab2f696 | 306 | } |
gillwei7 | 0:5c195ab2f696 | 307 | |
gillwei7 | 0:5c195ab2f696 | 308 | // Lookup the command. |
gillwei7 | 0:5c195ab2f696 | 309 | while (true) { |
gillwei7 | 0:5c195ab2f696 | 310 | commandFinger = commandLookup(commandFinger, tokenNum); |
gillwei7 | 0:5c195ab2f696 | 311 | if (commandFinger == NULL) { |
gillwei7 | 0:5c195ab2f696 | 312 | commandState.error = CYNTEC_CMD_ERR_NO_SUCH_COMMAND; |
gillwei7 | 0:5c195ab2f696 | 313 | break; |
gillwei7 | 0:5c195ab2f696 | 314 | } else { |
gillwei7 | 0:5c195ab2f696 | 315 | cyntecCurrentCommand = commandFinger; |
gillwei7 | 0:5c195ab2f696 | 316 | tokenNum += 1; |
gillwei7 | 0:5c195ab2f696 | 317 | commandState.argOffset += 1; |
gillwei7 | 0:5c195ab2f696 | 318 | |
gillwei7 | 0:5c195ab2f696 | 319 | if ( getNestedCommand(commandFinger, &commandFinger) ) { |
gillwei7 | 0:5c195ab2f696 | 320 | if (tokenNum >= commandState.tokenCount) { |
gillwei7 | 0:5c195ab2f696 | 321 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 322 | break; |
gillwei7 | 0:5c195ab2f696 | 323 | } |
gillwei7 | 0:5c195ab2f696 | 324 | } else { |
gillwei7 | 0:5c195ab2f696 | 325 | break; |
gillwei7 | 0:5c195ab2f696 | 326 | } |
gillwei7 | 0:5c195ab2f696 | 327 | } |
gillwei7 | 0:5c195ab2f696 | 328 | } |
gillwei7 | 0:5c195ab2f696 | 329 | |
gillwei7 | 0:5c195ab2f696 | 330 | if (commandState.error == CYNTEC_CMD_SUCCESS) { |
gillwei7 | 0:5c195ab2f696 | 331 | cyntecCommandActionHandler(commandFinger->action); |
gillwei7 | 0:5c195ab2f696 | 332 | } else { |
gillwei7 | 0:5c195ab2f696 | 333 | cyntecCommandErrorHandler(commandState.error);; |
gillwei7 | 0:5c195ab2f696 | 334 | } |
gillwei7 | 0:5c195ab2f696 | 335 | |
gillwei7 | 0:5c195ab2f696 | 336 | cyntecCommandReaderInit(); |
gillwei7 | 0:5c195ab2f696 | 337 | } |
gillwei7 | 0:5c195ab2f696 | 338 | |
gillwei7 | 0:5c195ab2f696 | 339 | /* |
gillwei7 | 0:5c195ab2f696 | 340 | * |
gillwei7 | 0:5c195ab2f696 | 341 | */ |
gillwei7 | 0:5c195ab2f696 | 342 | void cyntecEndArgument(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 343 | { |
gillwei7 | 0:5c195ab2f696 | 344 | if (commandState.tokenCount == MAX_TOKEN_COUNT) { |
gillwei7 | 0:5c195ab2f696 | 345 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 346 | commandState.state = CMD_READING_TO_EOL; |
gillwei7 | 0:5c195ab2f696 | 347 | } |
gillwei7 | 0:5c195ab2f696 | 348 | |
gillwei7 | 0:5c195ab2f696 | 349 | commandState.tokenCount += 1; |
gillwei7 | 0:5c195ab2f696 | 350 | commandState.tokenIndices[commandState.tokenCount] = commandState.index; |
gillwei7 | 0:5c195ab2f696 | 351 | commandState.state = CMD_AWAITING_ARGUMENT; |
gillwei7 | 0:5c195ab2f696 | 352 | |
gillwei7 | 0:5c195ab2f696 | 353 | if (input == '\r' || input == '\n') { |
gillwei7 | 0:5c195ab2f696 | 354 | callCommandAction(); |
gillwei7 | 0:5c195ab2f696 | 355 | } |
gillwei7 | 0:5c195ab2f696 | 356 | } |
gillwei7 | 0:5c195ab2f696 | 357 | |
gillwei7 | 0:5c195ab2f696 | 358 | /* |
gillwei7 | 0:5c195ab2f696 | 359 | * |
gillwei7 | 0:5c195ab2f696 | 360 | */ |
gillwei7 | 0:5c195ab2f696 | 361 | void cyntecWriteToBuffer(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 362 | { |
gillwei7 | 0:5c195ab2f696 | 363 | if (commandState.index == CYNTEC_COMMAND_BUFFER_LENGTH) { |
gillwei7 | 0:5c195ab2f696 | 364 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 365 | commandState.state = CMD_READING_TO_EOL; |
gillwei7 | 0:5c195ab2f696 | 366 | } else { |
gillwei7 | 0:5c195ab2f696 | 367 | commandState.buffer[commandState.index] = input; |
gillwei7 | 0:5c195ab2f696 | 368 | commandState.index += 1; |
gillwei7 | 0:5c195ab2f696 | 369 | } |
gillwei7 | 0:5c195ab2f696 | 370 | } |
gillwei7 | 0:5c195ab2f696 | 371 | |
gillwei7 | 3:38ec8ad317f4 | 372 | |
gillwei7 | 0:5c195ab2f696 | 373 | /* |
gillwei7 | 0:5c195ab2f696 | 374 | * Process the given char as a command. |
gillwei7 | 0:5c195ab2f696 | 375 | */ |
gillwei7 | 0:5c195ab2f696 | 376 | void cyntecProcessCommandInput(uint8_t input) { |
gillwei7 | 3:38ec8ad317f4 | 377 | |
gillwei7 | 0:5c195ab2f696 | 378 | bool isEol = false; |
gillwei7 | 0:5c195ab2f696 | 379 | bool isSpace = false; |
gillwei7 | 0:5c195ab2f696 | 380 | |
gillwei7 | 0:5c195ab2f696 | 381 | if (previousCharacter == '\r' && input == '\n') { |
gillwei7 | 0:5c195ab2f696 | 382 | previousCharacter = input; |
gillwei7 | 0:5c195ab2f696 | 383 | return; |
gillwei7 | 0:5c195ab2f696 | 384 | } |
gillwei7 | 0:5c195ab2f696 | 385 | |
gillwei7 | 0:5c195ab2f696 | 386 | previousCharacter = input; |
gillwei7 | 0:5c195ab2f696 | 387 | isEol = ((input == '\r') || (input == '\n')); |
gillwei7 | 0:5c195ab2f696 | 388 | isSpace = (input == ' '); |
gillwei7 | 0:5c195ab2f696 | 389 | |
gillwei7 | 0:5c195ab2f696 | 390 | switch (commandState.state) { |
gillwei7 | 0:5c195ab2f696 | 391 | case CMD_AWAITING_ARGUMENT: |
gillwei7 | 0:5c195ab2f696 | 392 | if (!isEol) |
gillwei7 | 3:38ec8ad317f4 | 393 | cyntecWriteToTotalBuffer(input); // total buffer including space |
gillwei7 | 0:5c195ab2f696 | 394 | if (isEol) { |
gillwei7 | 0:5c195ab2f696 | 395 | callCommandAction(); |
gillwei7 | 0:5c195ab2f696 | 396 | } else if (! isSpace) { |
gillwei7 | 0:5c195ab2f696 | 397 | commandState.state = CMD_READING_ARGUMENT; |
gillwei7 | 0:5c195ab2f696 | 398 | cyntecWriteToBuffer(input); |
gillwei7 | 0:5c195ab2f696 | 399 | } |
gillwei7 | 0:5c195ab2f696 | 400 | break; |
gillwei7 | 0:5c195ab2f696 | 401 | case CMD_READING_ARGUMENT: |
gillwei7 | 0:5c195ab2f696 | 402 | if (!isEol) |
gillwei7 | 0:5c195ab2f696 | 403 | cyntecWriteToTotalBuffer(input); |
gillwei7 | 0:5c195ab2f696 | 404 | if (isEol || isSpace) { |
gillwei7 | 0:5c195ab2f696 | 405 | cyntecEndArgument(input); |
gillwei7 | 0:5c195ab2f696 | 406 | } else { |
gillwei7 | 0:5c195ab2f696 | 407 | cyntecWriteToBuffer(input); |
gillwei7 | 0:5c195ab2f696 | 408 | } |
gillwei7 | 0:5c195ab2f696 | 409 | break; |
gillwei7 | 0:5c195ab2f696 | 410 | case CMD_READING_TO_EOL: |
gillwei7 | 0:5c195ab2f696 | 411 | if (isEol) { |
gillwei7 | 0:5c195ab2f696 | 412 | if (commandState.error != CYNTEC_CMD_SUCCESS) { |
gillwei7 | 0:5c195ab2f696 | 413 | cyntecCommandErrorHandler(commandState.error); |
gillwei7 | 0:5c195ab2f696 | 414 | } |
gillwei7 | 0:5c195ab2f696 | 415 | cyntecCommandReaderInit(); |
gillwei7 | 0:5c195ab2f696 | 416 | } |
gillwei7 | 0:5c195ab2f696 | 417 | break; |
gillwei7 | 0:5c195ab2f696 | 418 | } |
gillwei7 | 0:5c195ab2f696 | 419 | } |
gillwei7 | 0:5c195ab2f696 | 420 | |
gillwei7 | 0:5c195ab2f696 | 421 | |
gillwei7 | 0:5c195ab2f696 | 422 | /** Retrieves unsigned integer arguments. */ |
gillwei7 | 0:5c195ab2f696 | 423 | uint8_t *cyntecGetCommandArgument(uint8_t argNum, uint8_t *length) |
gillwei7 | 0:5c195ab2f696 | 424 | { |
gillwei7 | 0:5c195ab2f696 | 425 | uint8_t tokenNum = argNum + commandState.argOffset; |
gillwei7 | 0:5c195ab2f696 | 426 | |
gillwei7 | 0:5c195ab2f696 | 427 | if (length != NULL) { |
gillwei7 | 0:5c195ab2f696 | 428 | *length = tokenLength(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 429 | } |
gillwei7 | 0:5c195ab2f696 | 430 | return tokenPointer(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 431 | } |
gillwei7 | 0:5c195ab2f696 | 432 | |
gillwei7 | 0:5c195ab2f696 | 433 | void clearBuffer(void) |
gillwei7 | 0:5c195ab2f696 | 434 | { |
gillwei7 | 0:5c195ab2f696 | 435 | uint16_t i; |
gillwei7 | 0:5c195ab2f696 | 436 | for (i=0;i<CYNTEC_COMMAND_BUFFER_LENGTH;i++) |
gillwei7 | 0:5c195ab2f696 | 437 | { |
gillwei7 | 0:5c195ab2f696 | 438 | commandState.buffer[i] = NULL; |
gillwei7 | 0:5c195ab2f696 | 439 | } |
gillwei7 | 0:5c195ab2f696 | 440 | } |
gillwei7 | 0:5c195ab2f696 | 441 | |
gillwei7 | 0:5c195ab2f696 | 442 | /** Retrieves the token count. */ |
gillwei7 | 0:5c195ab2f696 | 443 | uint8_t cyntecGetCommandTokenCnt() |
gillwei7 | 0:5c195ab2f696 | 444 | { |
gillwei7 | 0:5c195ab2f696 | 445 | return commandState.tokenCount; |
gillwei7 | 0:5c195ab2f696 | 446 | } |
gillwei7 | 0:5c195ab2f696 | 447 | |
gillwei7 | 0:5c195ab2f696 | 448 | /* |
gillwei7 | 0:5c195ab2f696 | 449 | gill add for accept blank in name 20150904 |
gillwei7 | 0:5c195ab2f696 | 450 | uint8_t *cyntecGetCommandBuffer() |
gillwei7 | 0:5c195ab2f696 | 451 | void cyntecWriteToTotalBuffer(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 452 | uint8_t *cyntecGetCommandTotalBuffer(void) |
gillwei7 | 0:5c195ab2f696 | 453 | uint8_t cyntecGetTotalIndex(void) |
gillwei7 | 0:5c195ab2f696 | 454 | */ |
gillwei7 | 3:38ec8ad317f4 | 455 | |
gillwei7 | 0:5c195ab2f696 | 456 | |
gillwei7 | 0:5c195ab2f696 | 457 | void cyntecWriteToTotalBuffer(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 458 | { |
gillwei7 | 0:5c195ab2f696 | 459 | if (commandState.totalIndex == CYNTEC_COMMAND_BUFFER_LENGTH) { |
gillwei7 | 0:5c195ab2f696 | 460 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 461 | commandState.state = CMD_READING_TO_EOL; |
gillwei7 | 0:5c195ab2f696 | 462 | } else { |
gillwei7 | 0:5c195ab2f696 | 463 | commandState.totalBuffer[commandState.totalIndex] = input; |
gillwei7 | 0:5c195ab2f696 | 464 | commandState.totalIndex += 1; |
gillwei7 | 0:5c195ab2f696 | 465 | } |
gillwei7 | 0:5c195ab2f696 | 466 | } |
gillwei7 | 0:5c195ab2f696 | 467 | |
gillwei7 | 0:5c195ab2f696 | 468 | uint8_t *cyntecGetCommandTotalBuffer(void) |
gillwei7 | 0:5c195ab2f696 | 469 | { |
gillwei7 | 0:5c195ab2f696 | 470 | return commandState.totalBuffer; |
gillwei7 | 0:5c195ab2f696 | 471 | } |
gillwei7 | 0:5c195ab2f696 | 472 | |
gillwei7 | 0:5c195ab2f696 | 473 | uint8_t cyntecGetTotalIndex(void) |
gillwei7 | 0:5c195ab2f696 | 474 | { |
gillwei7 | 0:5c195ab2f696 | 475 | return commandState.totalIndex; |
gillwei7 | 3:38ec8ad317f4 | 476 | } |
gillwei7 | 3:38ec8ad317f4 | 477 |