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@25:1423b707b705, 2017-05-12 (annotated)
- Committer:
- tsungta
- Date:
- Fri May 12 01:53:35 2017 +0000
- Revision:
- 25:1423b707b705
- Parent:
- 24:838a0b25934b
update mbed-os to revision 2992; Note that NNN50 is temporary not supported due to the memory constraint
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 | } |
tsungta | 21:72d7a6e85d7f | 94 | int cyntecAtoInt(uint8_t *str) |
gillwei7 | 13:7eaec228ad23 | 95 | { |
gillwei7 | 13:7eaec228ad23 | 96 | int result = 0; |
gillwei7 | 13:7eaec228ad23 | 97 | uint8_t i = 0; |
tsungta | 21:72d7a6e85d7f | 98 | bool is_negative = false; |
gillwei7 | 13:7eaec228ad23 | 99 | |
tsungta | 21:72d7a6e85d7f | 100 | if (*str == '-') { |
tsungta | 21:72d7a6e85d7f | 101 | is_negative = true; |
tsungta | 21:72d7a6e85d7f | 102 | str++; |
tsungta | 21:72d7a6e85d7f | 103 | } |
tsungta | 21:72d7a6e85d7f | 104 | while( *str != '\0') |
gillwei7 | 13:7eaec228ad23 | 105 | { |
gillwei7 | 13:7eaec228ad23 | 106 | result *= 10; |
gillwei7 | 13:7eaec228ad23 | 107 | result = result + ( *str - '0' ); |
gillwei7 | 13:7eaec228ad23 | 108 | str++; |
gillwei7 | 13:7eaec228ad23 | 109 | i++; |
gillwei7 | 13:7eaec228ad23 | 110 | } |
gillwei7 | 13:7eaec228ad23 | 111 | |
tsungta | 21:72d7a6e85d7f | 112 | if (is_negative) |
tsungta | 21:72d7a6e85d7f | 113 | return -result; |
tsungta | 21:72d7a6e85d7f | 114 | else |
tsungta | 21:72d7a6e85d7f | 115 | return result; |
gillwei7 | 13:7eaec228ad23 | 116 | } |
gillwei7 | 0:5c195ab2f696 | 117 | uint8_t cyntecArgToUint8(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 118 | { |
gillwei7 | 0:5c195ab2f696 | 119 | uint8_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 120 | uint8_t num[2]; |
gillwei7 | 0:5c195ab2f696 | 121 | uint8_t i; |
gillwei7 | 0:5c195ab2f696 | 122 | |
gillwei7 | 0:5c195ab2f696 | 123 | if ( len != 2 ) |
gillwei7 | 0:5c195ab2f696 | 124 | { |
gillwei7 | 0:5c195ab2f696 | 125 | return 0; |
gillwei7 | 0:5c195ab2f696 | 126 | } |
gillwei7 | 0:5c195ab2f696 | 127 | |
gillwei7 | 0:5c195ab2f696 | 128 | for ( i = 0 ; i < 2 ; i++ ) |
gillwei7 | 0:5c195ab2f696 | 129 | { |
gillwei7 | 0:5c195ab2f696 | 130 | if ('0' <= str[i] && str[i] <= '9') |
gillwei7 | 0:5c195ab2f696 | 131 | num[i] = str[i] - '0'; |
gillwei7 | 0:5c195ab2f696 | 132 | else if ('a' <= str[i] && str[i] <= 'f') |
gillwei7 | 0:5c195ab2f696 | 133 | num[i] = str[i] - 'a' + 10; |
gillwei7 | 0:5c195ab2f696 | 134 | else if ('A' <= str[i] && str[i] <= 'F') |
gillwei7 | 0:5c195ab2f696 | 135 | num[i] = str[i] - 'A' + 10; |
gillwei7 | 0:5c195ab2f696 | 136 | else |
gillwei7 | 0:5c195ab2f696 | 137 | return 0; |
gillwei7 | 0:5c195ab2f696 | 138 | } |
gillwei7 | 0:5c195ab2f696 | 139 | |
gillwei7 | 0:5c195ab2f696 | 140 | result |= num[0] << 4; |
gillwei7 | 0:5c195ab2f696 | 141 | result |= num[1] << 0; |
gillwei7 | 0:5c195ab2f696 | 142 | |
gillwei7 | 0:5c195ab2f696 | 143 | return result; |
gillwei7 | 0:5c195ab2f696 | 144 | } |
gillwei7 | 0:5c195ab2f696 | 145 | |
gillwei7 | 0:5c195ab2f696 | 146 | uint16_t cyntecAtoiUint16(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 147 | { |
gillwei7 | 0:5c195ab2f696 | 148 | uint16_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 149 | uint16_t i = 0; |
gillwei7 | 0:5c195ab2f696 | 150 | |
gillwei7 | 0:5c195ab2f696 | 151 | while( *str != '\0' && i < len) |
gillwei7 | 0:5c195ab2f696 | 152 | { |
gillwei7 | 0:5c195ab2f696 | 153 | result *= 10; |
gillwei7 | 0:5c195ab2f696 | 154 | result = result + ( *str - '0' ); |
gillwei7 | 0:5c195ab2f696 | 155 | str++; |
gillwei7 | 0:5c195ab2f696 | 156 | i++; |
gillwei7 | 0:5c195ab2f696 | 157 | } |
gillwei7 | 0:5c195ab2f696 | 158 | |
gillwei7 | 0:5c195ab2f696 | 159 | return result; |
gillwei7 | 0:5c195ab2f696 | 160 | } |
gillwei7 | 0:5c195ab2f696 | 161 | |
gillwei7 | 0:5c195ab2f696 | 162 | uint16_t cyntecArgToUint16(uint8_t *str, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 163 | { |
gillwei7 | 0:5c195ab2f696 | 164 | uint16_t result = 0; |
gillwei7 | 0:5c195ab2f696 | 165 | uint8_t num[4]; |
gillwei7 | 0:5c195ab2f696 | 166 | uint8_t i; |
gillwei7 | 0:5c195ab2f696 | 167 | |
gillwei7 | 0:5c195ab2f696 | 168 | if ( len != 4 ) |
gillwei7 | 0:5c195ab2f696 | 169 | { |
gillwei7 | 0:5c195ab2f696 | 170 | return 0; |
gillwei7 | 0:5c195ab2f696 | 171 | } |
gillwei7 | 0:5c195ab2f696 | 172 | |
gillwei7 | 0:5c195ab2f696 | 173 | for ( i = 0 ; i < 4 ; i++ ) |
gillwei7 | 0:5c195ab2f696 | 174 | { |
gillwei7 | 0:5c195ab2f696 | 175 | if ('0' <= str[i] && str[i] <= '9') |
gillwei7 | 0:5c195ab2f696 | 176 | num[i] = str[i] - '0'; |
gillwei7 | 0:5c195ab2f696 | 177 | else if ('a' <= str[i] && str[i] <= 'f') |
gillwei7 | 0:5c195ab2f696 | 178 | num[i] = str[i] - 'a' + 10; |
gillwei7 | 0:5c195ab2f696 | 179 | else if ('A' <= str[i] && str[i] <= 'F') |
gillwei7 | 0:5c195ab2f696 | 180 | num[i] = str[i] - 'A' + 10; |
gillwei7 | 0:5c195ab2f696 | 181 | else |
gillwei7 | 0:5c195ab2f696 | 182 | return 0; |
gillwei7 | 0:5c195ab2f696 | 183 | } |
gillwei7 | 0:5c195ab2f696 | 184 | |
gillwei7 | 0:5c195ab2f696 | 185 | result |= num[0] << 12; |
gillwei7 | 0:5c195ab2f696 | 186 | result |= num[1] << 8; |
gillwei7 | 0:5c195ab2f696 | 187 | result |= num[2] << 4; |
gillwei7 | 0:5c195ab2f696 | 188 | result |= num[3] << 0; |
gillwei7 | 0:5c195ab2f696 | 189 | |
gillwei7 | 0:5c195ab2f696 | 190 | return result; |
gillwei7 | 0:5c195ab2f696 | 191 | } |
gillwei7 | 0:5c195ab2f696 | 192 | |
gillwei7 | 3:38ec8ad317f4 | 193 | //gill 20150918 |
gillwei7 | 3:38ec8ad317f4 | 194 | uint32_t cyntecHexToUint32(uint8_t *str, uint8_t len) |
gillwei7 | 3:38ec8ad317f4 | 195 | { |
gillwei7 | 3:38ec8ad317f4 | 196 | if (len > 8) |
gillwei7 | 3:38ec8ad317f4 | 197 | return 0; |
gillwei7 | 3:38ec8ad317f4 | 198 | uint32_t result = 0; |
gillwei7 | 3:38ec8ad317f4 | 199 | uint16_t i = 0; |
gillwei7 | 3:38ec8ad317f4 | 200 | |
gillwei7 | 3:38ec8ad317f4 | 201 | while( *str != '\0' && i < len) |
gillwei7 | 3:38ec8ad317f4 | 202 | { |
gillwei7 | 3:38ec8ad317f4 | 203 | result *= 16; |
gillwei7 | 3:38ec8ad317f4 | 204 | result = result + ( *str - '0' ); |
gillwei7 | 3:38ec8ad317f4 | 205 | str++; |
gillwei7 | 3:38ec8ad317f4 | 206 | i++; |
gillwei7 | 3:38ec8ad317f4 | 207 | } |
gillwei7 | 3:38ec8ad317f4 | 208 | |
gillwei7 | 3:38ec8ad317f4 | 209 | return result; |
gillwei7 | 3:38ec8ad317f4 | 210 | } |
gillwei7 | 3:38ec8ad317f4 | 211 | |
gillwei7 | 3:38ec8ad317f4 | 212 | |
gillwei7 | 3:38ec8ad317f4 | 213 | |
gillwei7 | 3:38ec8ad317f4 | 214 | |
gillwei7 | 0:5c195ab2f696 | 215 | uint8_t cyntecStrCmp(uint8_t *src, uint8_t *dst, uint8_t len) |
gillwei7 | 0:5c195ab2f696 | 216 | { |
gillwei7 | 0:5c195ab2f696 | 217 | uint8_t i = 0; |
gillwei7 | 0:5c195ab2f696 | 218 | |
gillwei7 | 0:5c195ab2f696 | 219 | while ( *src != '\0' && *dst != '\0' && i < len ) |
gillwei7 | 0:5c195ab2f696 | 220 | { |
gillwei7 | 0:5c195ab2f696 | 221 | if ( *src != *dst ) |
gillwei7 | 0:5c195ab2f696 | 222 | return 0; |
gillwei7 | 0:5c195ab2f696 | 223 | i++; |
gillwei7 | 0:5c195ab2f696 | 224 | src++; |
gillwei7 | 0:5c195ab2f696 | 225 | dst++; |
gillwei7 | 0:5c195ab2f696 | 226 | } |
gillwei7 | 0:5c195ab2f696 | 227 | |
gillwei7 | 0:5c195ab2f696 | 228 | return 1; |
gillwei7 | 0:5c195ab2f696 | 229 | } |
gillwei7 | 0:5c195ab2f696 | 230 | |
gillwei7 | 0:5c195ab2f696 | 231 | // Initialize the state machine. |
gillwei7 | 0:5c195ab2f696 | 232 | void cyntecCommandReaderInit(void) |
gillwei7 | 0:5c195ab2f696 | 233 | { |
gillwei7 | 0:5c195ab2f696 | 234 | commandState.state = CMD_AWAITING_ARGUMENT; |
gillwei7 | 0:5c195ab2f696 | 235 | commandState.index = 0; |
gillwei7 | 0:5c195ab2f696 | 236 | commandState.tokenIndices[0] = 0; |
gillwei7 | 0:5c195ab2f696 | 237 | commandState.tokenCount = 0; |
gillwei7 | 0:5c195ab2f696 | 238 | commandState.error = CYNTEC_CMD_SUCCESS; |
gillwei7 | 0:5c195ab2f696 | 239 | commandState.argOffset = 0; |
gillwei7 | 0:5c195ab2f696 | 240 | cyntecCurrentCommand = NULL; |
gillwei7 | 0:5c195ab2f696 | 241 | commandState.totalIndex = 0; //gill |
gillwei7 | 0:5c195ab2f696 | 242 | } |
gillwei7 | 0:5c195ab2f696 | 243 | |
gillwei7 | 0:5c195ab2f696 | 244 | static uint8_t tokenLength(uint8_t num) |
gillwei7 | 0:5c195ab2f696 | 245 | { |
gillwei7 | 0:5c195ab2f696 | 246 | return (commandState.tokenIndices[num + 1] |
gillwei7 | 0:5c195ab2f696 | 247 | - commandState.tokenIndices[num]); |
gillwei7 | 0:5c195ab2f696 | 248 | } |
gillwei7 | 0:5c195ab2f696 | 249 | |
gillwei7 | 0:5c195ab2f696 | 250 | static uint8_t *tokenPointer(uint8_t tokenNum) |
gillwei7 | 0:5c195ab2f696 | 251 | { |
gillwei7 | 0:5c195ab2f696 | 252 | return (commandState.buffer + commandState.tokenIndices[tokenNum]); |
gillwei7 | 0:5c195ab2f696 | 253 | } |
gillwei7 | 0:5c195ab2f696 | 254 | |
gillwei7 | 0:5c195ab2f696 | 255 | void cyntecCommandActionHandler(const CommandAction action) |
gillwei7 | 0:5c195ab2f696 | 256 | { |
gillwei7 | 0:5c195ab2f696 | 257 | (*action)(); |
gillwei7 | 0:5c195ab2f696 | 258 | clearBuffer(); |
gillwei7 | 0:5c195ab2f696 | 259 | } |
gillwei7 | 0:5c195ab2f696 | 260 | |
gillwei7 | 0:5c195ab2f696 | 261 | static bool getNestedCommand(CyntecCommandEntry *entry, |
gillwei7 | 0:5c195ab2f696 | 262 | CyntecCommandEntry **nestedCommand) |
gillwei7 | 0:5c195ab2f696 | 263 | { |
gillwei7 | 0:5c195ab2f696 | 264 | if ( entry -> action == NULL ) { |
gillwei7 | 0:5c195ab2f696 | 265 | *nestedCommand = (CyntecCommandEntry*)entry->subMenu; |
gillwei7 | 0:5c195ab2f696 | 266 | return true; |
gillwei7 | 0:5c195ab2f696 | 267 | } else { |
gillwei7 | 0:5c195ab2f696 | 268 | return false; |
gillwei7 | 0:5c195ab2f696 | 269 | } |
gillwei7 | 0:5c195ab2f696 | 270 | } |
gillwei7 | 0:5c195ab2f696 | 271 | |
gillwei7 | 0:5c195ab2f696 | 272 | static void cyntecPrintCommandUsage(CyntecCommandEntry *entry) |
gillwei7 | 0:5c195ab2f696 | 273 | { |
gillwei7 | 0:5c195ab2f696 | 274 | CyntecCommandEntry *commandFinger; |
gillwei7 | 0:5c195ab2f696 | 275 | |
gillwei7 | 0:5c195ab2f696 | 276 | if (entry == NULL) { |
gillwei7 | 0:5c195ab2f696 | 277 | entry = commandFinger = cyntecCommandTable; |
gillwei7 | 0:5c195ab2f696 | 278 | } else { |
gillwei7 | 0:5c195ab2f696 | 279 | getNestedCommand(entry, &commandFinger); |
gillwei7 | 0:5c195ab2f696 | 280 | |
gillwei7 | 3:38ec8ad317f4 | 281 | console.printf("%s-%s\r\n",entry->name,entry->description); |
gillwei7 | 0:5c195ab2f696 | 282 | } |
gillwei7 | 0:5c195ab2f696 | 283 | |
gillwei7 | 0:5c195ab2f696 | 284 | if ( commandFinger != NULL ) { |
gillwei7 | 0:5c195ab2f696 | 285 | for (; commandFinger->name != NULL; commandFinger++) { |
gillwei7 | 0:5c195ab2f696 | 286 | console.printf("%s - %s\r\n",commandFinger->name,commandFinger->description); |
gillwei7 | 0:5c195ab2f696 | 287 | } |
gillwei7 | 0:5c195ab2f696 | 288 | } |
gillwei7 | 0:5c195ab2f696 | 289 | |
gillwei7 | 0:5c195ab2f696 | 290 | } |
gillwei7 | 0:5c195ab2f696 | 291 | |
gillwei7 | 0:5c195ab2f696 | 292 | void cyntecCommandErrorHandler(uint8_t status) |
gillwei7 | 0:5c195ab2f696 | 293 | { |
silviaChen | 24:838a0b25934b | 294 | //Silvia 20161111 modify |
silviaChen | 24:838a0b25934b | 295 | console.printf("\r\nERROR;%s\r\n\r\n", cyntecCommandErrorNames[status]); |
gillwei7 | 0:5c195ab2f696 | 296 | cyntecPrintCommandUsage(cyntecCurrentCommand); |
gillwei7 | 0:5c195ab2f696 | 297 | } |
gillwei7 | 0:5c195ab2f696 | 298 | |
gillwei7 | 0:5c195ab2f696 | 299 | static CyntecCommandEntry *commandLookup(CyntecCommandEntry *commandFinger, |
gillwei7 | 0:5c195ab2f696 | 300 | uint8_t tokenNum) |
gillwei7 | 0:5c195ab2f696 | 301 | { |
gillwei7 | 0:5c195ab2f696 | 302 | uint8_t *inputCommand = tokenPointer(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 303 | uint8_t inputLength = tokenLength(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 304 | |
gillwei7 | 0:5c195ab2f696 | 305 | for (; commandFinger->name != NULL; commandFinger++) { |
gillwei7 | 0:5c195ab2f696 | 306 | const char *entryFinger = commandFinger->name; |
gillwei7 | 0:5c195ab2f696 | 307 | uint8_t *inputFinger = inputCommand; |
gillwei7 | 0:5c195ab2f696 | 308 | for (;; entryFinger++, inputFinger++) { |
gillwei7 | 0:5c195ab2f696 | 309 | bool endInput = (inputFinger - inputCommand == inputLength); |
gillwei7 | 0:5c195ab2f696 | 310 | bool endEntry = (*entryFinger == 0); |
gillwei7 | 0:5c195ab2f696 | 311 | if (endInput && endEntry) { |
gillwei7 | 0:5c195ab2f696 | 312 | return commandFinger; // Exact match. |
gillwei7 | 0:5c195ab2f696 | 313 | } else if ((*inputFinger) != (*entryFinger)) { |
gillwei7 | 0:5c195ab2f696 | 314 | break; |
gillwei7 | 0:5c195ab2f696 | 315 | } |
gillwei7 | 0:5c195ab2f696 | 316 | } |
gillwei7 | 0:5c195ab2f696 | 317 | } |
gillwei7 | 0:5c195ab2f696 | 318 | return NULL; |
gillwei7 | 0:5c195ab2f696 | 319 | } |
gillwei7 | 0:5c195ab2f696 | 320 | |
gillwei7 | 0:5c195ab2f696 | 321 | void callCommandAction(void) |
gillwei7 | 0:5c195ab2f696 | 322 | { |
gillwei7 | 0:5c195ab2f696 | 323 | CyntecCommandEntry *commandFinger = cyntecCommandTable; |
gillwei7 | 0:5c195ab2f696 | 324 | uint8_t tokenNum = 0; |
gillwei7 | 0:5c195ab2f696 | 325 | |
gillwei7 | 0:5c195ab2f696 | 326 | if (commandState.tokenCount == 0) { |
gillwei7 | 0:5c195ab2f696 | 327 | cyntecCommandReaderInit(); |
gillwei7 | 0:5c195ab2f696 | 328 | return; |
gillwei7 | 0:5c195ab2f696 | 329 | } |
gillwei7 | 0:5c195ab2f696 | 330 | |
gillwei7 | 0:5c195ab2f696 | 331 | // Lookup the command. |
gillwei7 | 0:5c195ab2f696 | 332 | while (true) { |
gillwei7 | 0:5c195ab2f696 | 333 | commandFinger = commandLookup(commandFinger, tokenNum); |
gillwei7 | 0:5c195ab2f696 | 334 | if (commandFinger == NULL) { |
gillwei7 | 0:5c195ab2f696 | 335 | commandState.error = CYNTEC_CMD_ERR_NO_SUCH_COMMAND; |
gillwei7 | 0:5c195ab2f696 | 336 | break; |
gillwei7 | 0:5c195ab2f696 | 337 | } else { |
gillwei7 | 0:5c195ab2f696 | 338 | cyntecCurrentCommand = commandFinger; |
gillwei7 | 0:5c195ab2f696 | 339 | tokenNum += 1; |
gillwei7 | 0:5c195ab2f696 | 340 | commandState.argOffset += 1; |
gillwei7 | 0:5c195ab2f696 | 341 | |
gillwei7 | 0:5c195ab2f696 | 342 | if ( getNestedCommand(commandFinger, &commandFinger) ) { |
gillwei7 | 0:5c195ab2f696 | 343 | if (tokenNum >= commandState.tokenCount) { |
gillwei7 | 0:5c195ab2f696 | 344 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 345 | break; |
gillwei7 | 0:5c195ab2f696 | 346 | } |
gillwei7 | 0:5c195ab2f696 | 347 | } else { |
gillwei7 | 0:5c195ab2f696 | 348 | break; |
gillwei7 | 0:5c195ab2f696 | 349 | } |
gillwei7 | 0:5c195ab2f696 | 350 | } |
gillwei7 | 0:5c195ab2f696 | 351 | } |
gillwei7 | 0:5c195ab2f696 | 352 | |
gillwei7 | 0:5c195ab2f696 | 353 | if (commandState.error == CYNTEC_CMD_SUCCESS) { |
gillwei7 | 0:5c195ab2f696 | 354 | cyntecCommandActionHandler(commandFinger->action); |
gillwei7 | 0:5c195ab2f696 | 355 | } else { |
gillwei7 | 0:5c195ab2f696 | 356 | cyntecCommandErrorHandler(commandState.error);; |
gillwei7 | 0:5c195ab2f696 | 357 | } |
gillwei7 | 0:5c195ab2f696 | 358 | |
gillwei7 | 0:5c195ab2f696 | 359 | cyntecCommandReaderInit(); |
gillwei7 | 0:5c195ab2f696 | 360 | } |
gillwei7 | 0:5c195ab2f696 | 361 | |
gillwei7 | 0:5c195ab2f696 | 362 | /* |
gillwei7 | 0:5c195ab2f696 | 363 | * |
gillwei7 | 0:5c195ab2f696 | 364 | */ |
gillwei7 | 0:5c195ab2f696 | 365 | void cyntecEndArgument(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 366 | { |
gillwei7 | 0:5c195ab2f696 | 367 | if (commandState.tokenCount == MAX_TOKEN_COUNT) { |
gillwei7 | 0:5c195ab2f696 | 368 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 369 | commandState.state = CMD_READING_TO_EOL; |
gillwei7 | 0:5c195ab2f696 | 370 | } |
gillwei7 | 0:5c195ab2f696 | 371 | |
gillwei7 | 0:5c195ab2f696 | 372 | commandState.tokenCount += 1; |
gillwei7 | 0:5c195ab2f696 | 373 | commandState.tokenIndices[commandState.tokenCount] = commandState.index; |
gillwei7 | 0:5c195ab2f696 | 374 | commandState.state = CMD_AWAITING_ARGUMENT; |
gillwei7 | 0:5c195ab2f696 | 375 | |
gillwei7 | 0:5c195ab2f696 | 376 | if (input == '\r' || input == '\n') { |
gillwei7 | 0:5c195ab2f696 | 377 | callCommandAction(); |
gillwei7 | 0:5c195ab2f696 | 378 | } |
gillwei7 | 0:5c195ab2f696 | 379 | } |
gillwei7 | 0:5c195ab2f696 | 380 | |
gillwei7 | 0:5c195ab2f696 | 381 | /* |
gillwei7 | 0:5c195ab2f696 | 382 | * |
gillwei7 | 0:5c195ab2f696 | 383 | */ |
gillwei7 | 0:5c195ab2f696 | 384 | void cyntecWriteToBuffer(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 385 | { |
gillwei7 | 0:5c195ab2f696 | 386 | if (commandState.index == CYNTEC_COMMAND_BUFFER_LENGTH) { |
gillwei7 | 0:5c195ab2f696 | 387 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 388 | commandState.state = CMD_READING_TO_EOL; |
gillwei7 | 0:5c195ab2f696 | 389 | } else { |
gillwei7 | 0:5c195ab2f696 | 390 | commandState.buffer[commandState.index] = input; |
gillwei7 | 0:5c195ab2f696 | 391 | commandState.index += 1; |
gillwei7 | 0:5c195ab2f696 | 392 | } |
gillwei7 | 0:5c195ab2f696 | 393 | } |
gillwei7 | 0:5c195ab2f696 | 394 | |
gillwei7 | 3:38ec8ad317f4 | 395 | |
gillwei7 | 0:5c195ab2f696 | 396 | /* |
gillwei7 | 0:5c195ab2f696 | 397 | * Process the given char as a command. |
gillwei7 | 0:5c195ab2f696 | 398 | */ |
gillwei7 | 0:5c195ab2f696 | 399 | void cyntecProcessCommandInput(uint8_t input) { |
gillwei7 | 3:38ec8ad317f4 | 400 | |
gillwei7 | 0:5c195ab2f696 | 401 | bool isEol = false; |
gillwei7 | 0:5c195ab2f696 | 402 | bool isSpace = false; |
gillwei7 | 0:5c195ab2f696 | 403 | |
gillwei7 | 0:5c195ab2f696 | 404 | if (previousCharacter == '\r' && input == '\n') { |
gillwei7 | 0:5c195ab2f696 | 405 | previousCharacter = input; |
gillwei7 | 0:5c195ab2f696 | 406 | return; |
gillwei7 | 0:5c195ab2f696 | 407 | } |
gillwei7 | 0:5c195ab2f696 | 408 | |
gillwei7 | 0:5c195ab2f696 | 409 | previousCharacter = input; |
gillwei7 | 0:5c195ab2f696 | 410 | isEol = ((input == '\r') || (input == '\n')); |
gillwei7 | 0:5c195ab2f696 | 411 | isSpace = (input == ' '); |
gillwei7 | 0:5c195ab2f696 | 412 | |
gillwei7 | 0:5c195ab2f696 | 413 | switch (commandState.state) { |
gillwei7 | 0:5c195ab2f696 | 414 | case CMD_AWAITING_ARGUMENT: |
gillwei7 | 0:5c195ab2f696 | 415 | if (!isEol) |
gillwei7 | 3:38ec8ad317f4 | 416 | cyntecWriteToTotalBuffer(input); // total buffer including space |
gillwei7 | 0:5c195ab2f696 | 417 | if (isEol) { |
gillwei7 | 0:5c195ab2f696 | 418 | callCommandAction(); |
gillwei7 | 0:5c195ab2f696 | 419 | } else if (! isSpace) { |
gillwei7 | 0:5c195ab2f696 | 420 | commandState.state = CMD_READING_ARGUMENT; |
gillwei7 | 0:5c195ab2f696 | 421 | cyntecWriteToBuffer(input); |
gillwei7 | 0:5c195ab2f696 | 422 | } |
gillwei7 | 0:5c195ab2f696 | 423 | break; |
gillwei7 | 0:5c195ab2f696 | 424 | case CMD_READING_ARGUMENT: |
gillwei7 | 0:5c195ab2f696 | 425 | if (!isEol) |
gillwei7 | 0:5c195ab2f696 | 426 | cyntecWriteToTotalBuffer(input); |
gillwei7 | 0:5c195ab2f696 | 427 | if (isEol || isSpace) { |
gillwei7 | 0:5c195ab2f696 | 428 | cyntecEndArgument(input); |
gillwei7 | 0:5c195ab2f696 | 429 | } else { |
gillwei7 | 0:5c195ab2f696 | 430 | cyntecWriteToBuffer(input); |
gillwei7 | 0:5c195ab2f696 | 431 | } |
gillwei7 | 0:5c195ab2f696 | 432 | break; |
gillwei7 | 0:5c195ab2f696 | 433 | case CMD_READING_TO_EOL: |
gillwei7 | 0:5c195ab2f696 | 434 | if (isEol) { |
gillwei7 | 0:5c195ab2f696 | 435 | if (commandState.error != CYNTEC_CMD_SUCCESS) { |
gillwei7 | 0:5c195ab2f696 | 436 | cyntecCommandErrorHandler(commandState.error); |
gillwei7 | 0:5c195ab2f696 | 437 | } |
gillwei7 | 0:5c195ab2f696 | 438 | cyntecCommandReaderInit(); |
gillwei7 | 0:5c195ab2f696 | 439 | } |
gillwei7 | 0:5c195ab2f696 | 440 | break; |
gillwei7 | 0:5c195ab2f696 | 441 | } |
gillwei7 | 0:5c195ab2f696 | 442 | } |
gillwei7 | 0:5c195ab2f696 | 443 | |
gillwei7 | 0:5c195ab2f696 | 444 | |
gillwei7 | 0:5c195ab2f696 | 445 | /** Retrieves unsigned integer arguments. */ |
gillwei7 | 0:5c195ab2f696 | 446 | uint8_t *cyntecGetCommandArgument(uint8_t argNum, uint8_t *length) |
gillwei7 | 0:5c195ab2f696 | 447 | { |
gillwei7 | 0:5c195ab2f696 | 448 | uint8_t tokenNum = argNum + commandState.argOffset; |
gillwei7 | 0:5c195ab2f696 | 449 | |
gillwei7 | 0:5c195ab2f696 | 450 | if (length != NULL) { |
gillwei7 | 0:5c195ab2f696 | 451 | *length = tokenLength(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 452 | } |
gillwei7 | 0:5c195ab2f696 | 453 | return tokenPointer(tokenNum); |
gillwei7 | 0:5c195ab2f696 | 454 | } |
gillwei7 | 0:5c195ab2f696 | 455 | |
gillwei7 | 0:5c195ab2f696 | 456 | void clearBuffer(void) |
gillwei7 | 0:5c195ab2f696 | 457 | { |
gillwei7 | 0:5c195ab2f696 | 458 | uint16_t i; |
gillwei7 | 0:5c195ab2f696 | 459 | for (i=0;i<CYNTEC_COMMAND_BUFFER_LENGTH;i++) |
gillwei7 | 0:5c195ab2f696 | 460 | { |
gillwei7 | 0:5c195ab2f696 | 461 | commandState.buffer[i] = NULL; |
gillwei7 | 0:5c195ab2f696 | 462 | } |
gillwei7 | 0:5c195ab2f696 | 463 | } |
gillwei7 | 0:5c195ab2f696 | 464 | |
gillwei7 | 0:5c195ab2f696 | 465 | /** Retrieves the token count. */ |
gillwei7 | 0:5c195ab2f696 | 466 | uint8_t cyntecGetCommandTokenCnt() |
gillwei7 | 0:5c195ab2f696 | 467 | { |
gillwei7 | 0:5c195ab2f696 | 468 | return commandState.tokenCount; |
gillwei7 | 0:5c195ab2f696 | 469 | } |
gillwei7 | 0:5c195ab2f696 | 470 | |
gillwei7 | 0:5c195ab2f696 | 471 | /* |
gillwei7 | 0:5c195ab2f696 | 472 | gill add for accept blank in name 20150904 |
gillwei7 | 0:5c195ab2f696 | 473 | uint8_t *cyntecGetCommandBuffer() |
gillwei7 | 0:5c195ab2f696 | 474 | void cyntecWriteToTotalBuffer(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 475 | uint8_t *cyntecGetCommandTotalBuffer(void) |
gillwei7 | 0:5c195ab2f696 | 476 | uint8_t cyntecGetTotalIndex(void) |
gillwei7 | 0:5c195ab2f696 | 477 | */ |
gillwei7 | 3:38ec8ad317f4 | 478 | |
gillwei7 | 0:5c195ab2f696 | 479 | |
gillwei7 | 0:5c195ab2f696 | 480 | void cyntecWriteToTotalBuffer(uint8_t input) |
gillwei7 | 0:5c195ab2f696 | 481 | { |
gillwei7 | 0:5c195ab2f696 | 482 | if (commandState.totalIndex == CYNTEC_COMMAND_BUFFER_LENGTH) { |
gillwei7 | 0:5c195ab2f696 | 483 | commandState.error = CYNTEC_CMD_ERR_WRONG_NUMBER_OF_ARGUMENTS; |
gillwei7 | 0:5c195ab2f696 | 484 | commandState.state = CMD_READING_TO_EOL; |
gillwei7 | 0:5c195ab2f696 | 485 | } else { |
gillwei7 | 0:5c195ab2f696 | 486 | commandState.totalBuffer[commandState.totalIndex] = input; |
gillwei7 | 0:5c195ab2f696 | 487 | commandState.totalIndex += 1; |
gillwei7 | 0:5c195ab2f696 | 488 | } |
gillwei7 | 0:5c195ab2f696 | 489 | } |
gillwei7 | 0:5c195ab2f696 | 490 | |
gillwei7 | 0:5c195ab2f696 | 491 | uint8_t *cyntecGetCommandTotalBuffer(void) |
gillwei7 | 0:5c195ab2f696 | 492 | { |
gillwei7 | 0:5c195ab2f696 | 493 | return commandState.totalBuffer; |
gillwei7 | 0:5c195ab2f696 | 494 | } |
gillwei7 | 0:5c195ab2f696 | 495 | |
gillwei7 | 0:5c195ab2f696 | 496 | uint8_t cyntecGetTotalIndex(void) |
gillwei7 | 0:5c195ab2f696 | 497 | { |
gillwei7 | 0:5c195ab2f696 | 498 | return commandState.totalIndex; |
gillwei7 | 3:38ec8ad317f4 | 499 | } |
gillwei7 | 3:38ec8ad317f4 | 500 | |
gillwei7 | 9:ff3ccba5dc16 | 501 |