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