CLI example for NNN50

Dependencies:   NNN50_WIFI_API

Fork of NNN50_WiFi_HelloWorld by Delta

Committer:
silviaChen
Date:
Thu Sep 14 01:48:08 2017 +0000
Revision:
9:871fc0231c7f
Support both BLE UART service and WiFi CLI command

Who changed what in which revision?

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