Host library for controlling a WiConnect enabled Wi-Fi module.
Dependents: wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more
Diff: internal/wiconnect/ProcessCommand.cpp
- Revision:
- 28:3c52f578708a
- Parent:
- 27:b63f5a9cdefa
- Child:
- 29:b6af04b77a56
--- a/internal/wiconnect/ProcessCommand.cpp Thu Oct 23 15:21:50 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,351 +0,0 @@ -/** - * ACKme WiConnect Host Library is licensed under the BSD licence: - * - * Copyright (c)2014 ACKme Networks. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#include "CommandCommon.h" - - - -/*************************************************************************************************/ -WiconnectResult Wiconnect::checkCurrentCommand() -{ - WiconnectResult result; - - start: - CHECK_INITIALIZED(); - if(!commandExecuting) - { - return WICONNECT_IDLE; - } - - CommandContext *context = (CommandContext*)commandContext; - - if(context->commandLen > 0) - { - const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); - const int bytesToWrite = context->commandLen; - const int bytesWritten = serial.write(context->commandPtr, bytesToWrite, timeout); - context->commandPtr += bytesWritten; - context->commandLen -= bytesWritten; - if(bytesToWrite != bytesWritten) - { - if(timeoutTimer.timedOut(context->timeoutMs)) - { - issueCommandCallback(WICONNECT_TIMEOUT); - return WICONNECT_TIMEOUT; - } - else - { - return WICONNECT_PROCESSING; - } - } - } - - while(context->reader.isValid()) - { - if(context->bytesToWrite == 0) - { - context->responseBufferPtr = context->responseBuffer; - if(WICONNECT_FAILED(result, context->reader.call(context->user, context->responseBuffer, context->responseBufferLen, &context->bytesToWrite))) - { - issueCommandCallback(result); - return result; - } - else if(context->bytesToWrite == EOF) - { - context->reader.setInvalid(); - context->bytesToWrite = 0; - context->responseBufferPtr = context->responseBuffer; - break; - } - else - { - timeoutTimer.reset(); - } - } - if(context->bytesToWrite > 0) - { - const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); - const int bytesToWrite = context->bytesToWrite; - const int bytesWritten = serial.write(context->responseBufferPtr, bytesToWrite, timeout); - context->responseBufferPtr += bytesWritten; - context->bytesToWrite -= bytesWritten; - if(bytesToWrite != bytesWritten) - { - if(timeoutTimer.timedOut(context->timeoutMs)) - { - issueCommandCallback(WICONNECT_TIMEOUT); - return WICONNECT_TIMEOUT; - } - else - { - return WICONNECT_PROCESSING; - } - } - } - } - - result = receiveResponse(); - if(result == WICONNECT_PROCESSING && !context->nonBlocking) - { - goto start; - } - return result; -} - -/*************************************************************************************************/ -WiconnectResult Wiconnect::receiveResponse() -{ -loop: - WiconnectResult result = receivePacket(); - - if(result == WICONNECT_PROCESSING) - { - } - else if(result == WICONNECT_SUCCESS) - { - CommandHeader *header = (CommandHeader*)commandHeaderBuffer; - CommandContext *context = (CommandContext*)commandContext; - - // TODO: need to notify safemode - - if(header->response_type == WICONNECT_CMD_TYPE_REPLY || header->response_type == WICONNECT_CMD_TYPE_SAFEMODE) - { - if(header->response_code != WICONNECT_CMD_SUCCESS) - { - DEBUG_CMD_ERROR(header->response_code); - flush(); - issueCommandCallback(WICONNECT_CMD_RESPONSE_ERROR); - return WICONNECT_CMD_RESPONSE_ERROR; - } - else if(header->response_len > 0) - { - DEBUG_CMD_RESPONSE(context->responseBuffer); - if(header->response_len < context->responseBufferLen) - { - context->responseBuffer[header->response_len] = 0; - } - } - else - { - *context->responseBuffer = 0; - } - - issueCommandCallback(WICONNECT_SUCCESS); - - return WICONNECT_SUCCESS; - } - else - { - DEBUG_CMD_LOG(context->responseBuffer); - RESET_CMD_HEADER(header); - context->responseBufferPtr = context->responseBuffer; - goto loop; - } - } - else - { - issueCommandCallback(result); - } - - return result; -} - -/*************************************************************************************************/ -WiconnectResult Wiconnect::receivePacket() -{ - CommandHeader *header = (CommandHeader*)commandHeaderBuffer; - CommandContext *context = (CommandContext*)commandContext; - - if(header->bytes_remaining > 0) - { - uint16_t bytesReceived; - uint8_t buffer[WICONNECT_HEADER_LENGTH]; - - while(header->bytes_remaining > 0) - { - const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); - bytesReceived = serial.read((char*)buffer, header->bytes_remaining, timeout); - if(bytesReceived == 0) - { - return timeoutTimer.timedOut(context->timeoutMs) ? WICONNECT_TIMEOUT : WICONNECT_PROCESSING; - } - - for(uint8_t *ptr = buffer; bytesReceived > 0; ++ptr) - { - if(header->response_type == WICONNECT_CMD_TYPE_NULL) - { - if( *ptr == WICONNECT_CMD_TYPE_REPLY || - *ptr == WICONNECT_CMD_TYPE_LOG || - *ptr == WICONNECT_CMD_TYPE_SAFEMODE) - { - header->response_type = (ResponseType)*ptr; - -- header->bytes_remaining; - } - --bytesReceived; - } - else if(header->response_code == WICONNECT_CMD_CODE_NULL) - { - if(*ptr >= '0' && *ptr <= '7') - { - header->response_code = (ResponseCode)(*ptr - '0' + 1); - --header->bytes_remaining; - header->len_buffer_ptr = header->len_buffer; - } - else - { - RESET_CMD_HEADER(header); - } - --bytesReceived; - } - else if(header->bytes_remaining > 2) - { - uint8_t len_chars = MIN((int)bytesReceived, (int)(header->bytes_remaining-2)); - header->bytes_remaining -= len_chars; - bytesReceived -= len_chars; - while(len_chars-- > 0) - { - *header->len_buffer_ptr++ = *ptr++; - } - --ptr; // need to decrement since the for loop increments - if(header->bytes_remaining == 2) - { - uint32_t packetLen; - *header->len_buffer_ptr = 0; - if(!StringUtil::strToUint32((const char*)header->len_buffer, &packetLen)) - { - RESET_CMD_HEADER(header); - } - else - { - if(packetLen > 0) - { - if(packetLen == 1 || packetLen == 2) - { - return WICONNECT_CMD_RESPONSE_ERROR; - } - packetLen -= 2; - } - if((int)packetLen > context->responseBufferLen) - { - DEBUG_ERROR("Packet larger than response buffer: %d > %d", packetLen, context->responseBufferLen); - return WICONNECT_OVERFLOW; - } - header->response_len = (uint16_t)packetLen; - context->bytesToRead = packetLen; - } - } - } - else if(header->bytes_remaining == 2) - { - --bytesReceived; - if(*ptr == '\r') - { - header->bytes_remaining = 1; - } - else - { - RESET_CMD_HEADER(header); - } - } - else - { - --bytesReceived; - if(*ptr == '\n') - { - header->bytes_remaining = 0; - break; - } - else - { - RESET_CMD_HEADER(header); - } - } - } - } - } - - while(context->bytesToRead > 0) - { - const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); - const int bytesToRead = context->bytesToRead; - const int bytesReceived = serial.read(context->responseBufferPtr, bytesToRead, timeout); - context->responseBufferPtr += bytesReceived; - context->bytesToRead -= bytesReceived; - - if(bytesReceived != bytesToRead) - { - return timeoutTimer.timedOut(context->timeoutMs) ? WICONNECT_TIMEOUT : WICONNECT_PROCESSING; - } - else if(context->bytesToRead == 0) - { - *context->responseBufferPtr = 0; - - // read the trailing \r\n - char trailingCRLF[2]; - const int bytesReceived = serial.read(trailingCRLF, 2, 100); - // FIXME there's a potenital weakness where the trailing \r\n isn't ready to be recieved - if(bytesReceived != 2) - { - return WICONNECT_TIMEOUT; - } - } - } - - return (header->response_code != WICONNECT_CMD_CODE_NULL && - header->response_type != WICONNECT_CMD_TYPE_NULL && - context->bytesToRead == 0) ? WICONNECT_SUCCESS : WICONNECT_PROCESSING; -} - -/*************************************************************************************************/ -void Wiconnect::issueCommandCallback(WiconnectResult result) -{ - CommandHeader *header = (CommandHeader*)commandHeaderBuffer; - CommandContext *context = (CommandContext*)commandContext; -#ifdef WICONNECT_ASYNC_TIMER_ENABLED - void *returnPtr = (currentQueuedCommand != NULL) ? (void*)currentQueuedCommand : (void*)context->responseBuffer; - currentQueuedCommand = NULL; - commandProcessorTimer.stop(); -#else - void *returnPtr = (void*)context->responseBuffer; -#endif - context->callback.call(result, returnPtr, (void*)(uint32_t)header->response_len); - commandExecuting = false; - -#ifdef WICONNECT_ASYNC_TIMER_ENABLED - processNextQueuedCommand(); -#endif -} - -/*************************************************************************************************/ -void Wiconnect::stopCurrentCommand() -{ - internalProcessingState = 0; - issueCommandCallback(WICONNECT_ABORTED); -} -