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@13:7eaec228ad23, 2016-02-25 (annotated)
- Committer:
- gillwei7
- Date:
- Thu Feb 25 07:22:37 2016 +0000
- Revision:
- 13:7eaec228ad23
- Parent:
- 9:ff3ccba5dc16
- Child:
- 20:bd1760975052
Modify TCP and UDP max data length
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 | uint8_t isValidGPIO(uint8_t num) |
gillwei7 | 9:ff3ccba5dc16 | 493 | { |
gillwei7 | 9:ff3ccba5dc16 | 494 | uint8_t cfgPin[] = {0,4,5,6,7,13,21,23,24,25,29,30,31}; |
gillwei7 | 9:ff3ccba5dc16 | 495 | uint8_t i; |
gillwei7 | 9:ff3ccba5dc16 | 496 | |
gillwei7 | 9:ff3ccba5dc16 | 497 | for ( i = 0; i < sizeof(cfgPin) ; i++ ) { |
gillwei7 | 9:ff3ccba5dc16 | 498 | if ( num == cfgPin[i] ) |
gillwei7 | 9:ff3ccba5dc16 | 499 | return 1; |
gillwei7 | 9:ff3ccba5dc16 | 500 | } |
gillwei7 | 9:ff3ccba5dc16 | 501 | |
gillwei7 | 9:ff3ccba5dc16 | 502 | return 0; |
gillwei7 | 9:ff3ccba5dc16 | 503 | } |