/* Function: bool SYS_CMD_Tasks( void ) Summary: Maintains the Command Processor System Service's internal state machine. Description: This function is used to maintain the Command Processor System Service internal state machine. Precondition: SYS_CMD_Initialize was successfully run once. Parameters: None. Returns: If successfully, returns true. If there is an error, returns false. Remarks: None. */ bool SYS_CMD_Tasks(void) { short i; SYS_CMD_DEVICE_NODE* pCmdIO; for (i=0; i<cmdIODevList.num; i++) { pCmdIO = SYS_CMDIO_GET_HANDLE(i); if(pCmdIO) { //Check if this command IO is ready if(!(*pCmdIO->pCmdApi->isRdy)(pCmdIO) && pCmdIO->cmdIoType != SYS_CMD_TELNET_COMMAND_READ_CONSOLE_IO_PARAM) { continue; } switch(pCmdIO->cmdState) { case SYS_CMD_STATE_DISABLE: //App layer is not ready to process commands yet break; case SYS_CMD_STATE_SETUP_READ: { readBuff[0] = '\0'; if ( pCmdIO->cmdIoType != SYS_CMD_TELNET_COMMAND_READ_CONSOLE_IO_PARAM) { _cmdAppData.bytesRead = (*pCmdIO->pCmdApi->readc)(pCmdIO); /* Read data from console. */ _cmdAppData.seqBuff[0] = '\0'; if (pCmdIO->cmdIoParam == NULL || *(uint8_t*)pCmdIO->cmdIoParam == SYS_CMD_SINGLE_CHARACTER_READ_CONSOLE_IO_PARAM) { pCmdIO->cmdState = SYS_CMD_STATE_WAIT_FOR_READ_DONE; } else if (*(uint8_t*)pCmdIO->cmdIoParam == SYS_CMD_FULL_COMMAND_READ_CONSOLE_IO_PARAM) { pCmdIO->cmdState = SYS_CMD_STATE_PROCESS_FULL_READ; } } else /* cmdIoParm is an I/O Socket, such as telnet */ { readBuff[0] = (*pCmdIO->pCmdApi->getc)(pCmdIO->cmdIoParam); /* Read data from console. */ pCmdIO->cmdState = SYS_CMD_STATE_WAIT_FOR_READ_DONE; } } break; case SYS_CMD_STATE_WAIT_FOR_READ_DONE: { if((readBuff[0] == '\r') || (readBuff[0] == '\n')) { pCmdIO->cmdState = SYS_CMD_STATE_SETUP_READ; // new command assembled if(pCmdIO->cmdPnt == pCmdIO->cmdBuff) { // just an extra \n or \r (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, LINE_TERM _promptStr); return true; } (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, LINE_TERM); *pCmdIO->cmdPnt = 0; pCmdIO->cmdPnt = pCmdIO->cmdEnd = pCmdIO->cmdBuff; if(!ParseCmdBuffer(pCmdIO)) { //Command not processed, show prompt (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, _promptStr); } else { //Command being processed, temporarily disable prompt until command completes pCmdIO->cmdState = SYS_CMD_STATE_DISABLE; } return true; } else if(readBuff[0] == '\b') { pCmdIO->cmdState = SYS_CMD_STATE_SETUP_READ; if(pCmdIO->cmdPnt > pCmdIO->cmdBuff) { (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, "\b \b"); pCmdIO->cmdPnt--; pCmdIO->cmdEnd--; } } else if(readBuff[0] == 0x1b) { _cmdAppData.seqBuff[0] = readBuff[1]; _cmdAppData.seqBuff[1] = readBuff[2]; // This is an escape sequence, start reading which cursor character ProcessEscSequence(pCmdIO); readBuff[0] = '\0'; readBuff[1] = '\0'; readBuff[2] = '\0'; pCmdIO->cmdState = SYS_CMD_STATE_SETUP_READ; } else if(pCmdIO->cmdEnd-pCmdIO->cmdBuff<SYS_CMD_MAX_LENGTH) { pCmdIO->cmdState = SYS_CMD_STATE_SETUP_READ; if (readBuff[0]!='\0') { (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, readBuff); *pCmdIO->cmdPnt++ = readBuff[0]; } if(pCmdIO->cmdPnt > pCmdIO->cmdEnd) { pCmdIO->cmdEnd = pCmdIO->cmdPnt; } } else { pCmdIO->cmdState = SYS_CMD_STATE_SETUP_READ; (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, " *** Command Processor buffer exceeded. Retry. ***" LINE_TERM); pCmdIO->cmdPnt = pCmdIO->cmdEnd = pCmdIO->cmdBuff; (*pCmdIO->pCmdApi->msg)(pCmdIO->cmdIoParam, _promptStr); } } break; case SYS_CMD_STATE_PROCESS_FULL_READ: { if (readBuff[0]!='\0') { readBuff[strlen(readBuff)-1] = '\0'; strcpy(pCmdIO->cmdBuff, readBuff); ParseCmdBuffer(pCmdIO); pCmdIO->cmdState = SYS_CMD_STATE_SETUP_READ; return true; } } break; } } } return true; }
// processing command received by the serial line bool _SYS_COMMAND_TASK(void) { short i; char data; _CMDIO_DEV_NODE* pCmdIO; const void* cmdIoParam; if (_cmdAlive == false) { return false; } for (i=0; i<cmdIODevList.num; i++) { pCmdIO = _SYS_CMDIO_GET_HANDLE(i); //DisplayPrompt(); if(pCmdIO) { cmdIoParam = pCmdIO->cmdIoParam; if((*pCmdIO->pCmdApi->isRdy)(cmdIoParam)) { // some data available data = (*pCmdIO->pCmdApi->getc)(cmdIoParam); /* Read data from console. */ if((data == '\r') || (data == '\n')) { // new command assembled if(pCmdIO->cmdPnt == pCmdIO->cmdBuff) { // just an extra \n or \r (*pCmdIO->pCmdApi->msg)(cmdIoParam, LINE_TERM _promptStr); return true; } (*pCmdIO->pCmdApi->msg)(cmdIoParam, LINE_TERM); *pCmdIO->cmdPnt = 0; pCmdIO->cmdPnt = pCmdIO->cmdEnd = pCmdIO->cmdBuff; ParseCmdBuffer(pCmdIO); (*pCmdIO->pCmdApi->msg)(cmdIoParam, _promptStr); return true; } else if(data == '\b') { if(pCmdIO->cmdPnt > pCmdIO->cmdBuff) { (*pCmdIO->pCmdApi->msg)(cmdIoParam, "\b \b"); pCmdIO->cmdPnt--; pCmdIO->cmdEnd--; } } else if(data == 0x1b) { // escape sequence ProcessEscSequence(pCmdIO); } else if(pCmdIO->cmdEnd-pCmdIO->cmdBuff<_SYS_CMD_MAX_LENGTH) { (*pCmdIO->pCmdApi->putc)(cmdIoParam, data); *pCmdIO->cmdPnt++ = data; if(pCmdIO->cmdPnt > pCmdIO->cmdEnd) { pCmdIO->cmdEnd = pCmdIO->cmdPnt; } } else { (*pCmdIO->pCmdApi->msg)(cmdIoParam, " *** Command Processor buffer exceeded. Retry. ***" LINE_TERM); pCmdIO->cmdPnt = pCmdIO->cmdEnd = pCmdIO->cmdBuff; (*pCmdIO->pCmdApi->msg)(cmdIoParam, _promptStr); } } } } return true; }