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

Committer:
dan_ackme
Date:
Sat Sep 06 20:34:01 2014 -0700
Revision:
24:e27e23297f02
Parent:
21:17bb3eddcbae
add api to get/set module settings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dan_ackme 24:e27e23297f02 1 /**
dan_ackme 24:e27e23297f02 2 * ACKme WiConnect Host Library is licensed under the BSD licence:
dan_ackme 24:e27e23297f02 3 *
dan_ackme 24:e27e23297f02 4 * Copyright (c)2014 ACKme Networks.
dan_ackme 24:e27e23297f02 5 * All rights reserved.
dan_ackme 24:e27e23297f02 6 *
dan_ackme 24:e27e23297f02 7 * Redistribution and use in source and binary forms, with or without modification,
dan_ackme 24:e27e23297f02 8 * are permitted provided that the following conditions are met:
dan_ackme 24:e27e23297f02 9 *
dan_ackme 24:e27e23297f02 10 * 1. Redistributions of source code must retain the above copyright notice,
dan_ackme 24:e27e23297f02 11 * this list of conditions and the following disclaimer.
dan_ackme 24:e27e23297f02 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
dan_ackme 24:e27e23297f02 13 * this list of conditions and the following disclaimer in the documentation
dan_ackme 24:e27e23297f02 14 * and/or other materials provided with the distribution.
dan_ackme 24:e27e23297f02 15 * 3. The name of the author may not be used to endorse or promote products
dan_ackme 24:e27e23297f02 16 * derived from this software without specific prior written permission.
dan_ackme 24:e27e23297f02 17 *
dan_ackme 24:e27e23297f02 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
dan_ackme 24:e27e23297f02 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
dan_ackme 24:e27e23297f02 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
dan_ackme 24:e27e23297f02 21 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
dan_ackme 24:e27e23297f02 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
dan_ackme 24:e27e23297f02 23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dan_ackme 24:e27e23297f02 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dan_ackme 24:e27e23297f02 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
dan_ackme 24:e27e23297f02 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
dan_ackme 24:e27e23297f02 27 * OF SUCH DAMAGE.
dan_ackme 0:ea85c4bb5e1f 28 */
dan_ackme 0:ea85c4bb5e1f 29
dan_ackme 0:ea85c4bb5e1f 30 #include "CommandCommon.h"
dan_ackme 0:ea85c4bb5e1f 31
dan_ackme 0:ea85c4bb5e1f 32
dan_ackme 0:ea85c4bb5e1f 33
dan_ackme 0:ea85c4bb5e1f 34 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 35 WiconnectResult Wiconnect::checkCurrentCommand()
dan_ackme 0:ea85c4bb5e1f 36 {
dan_ackme 0:ea85c4bb5e1f 37 WiconnectResult result;
dan_ackme 0:ea85c4bb5e1f 38
dan_ackme 0:ea85c4bb5e1f 39 start:
dan_ackme 0:ea85c4bb5e1f 40 CHECK_INITIALIZED();
dan_ackme 0:ea85c4bb5e1f 41 if(!commandExecuting)
dan_ackme 0:ea85c4bb5e1f 42 {
dan_ackme 0:ea85c4bb5e1f 43 return WICONNECT_IDLE;
dan_ackme 0:ea85c4bb5e1f 44 }
dan_ackme 0:ea85c4bb5e1f 45
dan_ackme 0:ea85c4bb5e1f 46 CommandContext *context = (CommandContext*)commandContext;
dan_ackme 0:ea85c4bb5e1f 47
dan_ackme 0:ea85c4bb5e1f 48 if(context->commandLen > 0)
dan_ackme 0:ea85c4bb5e1f 49 {
dan_ackme 0:ea85c4bb5e1f 50 const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs);
dan_ackme 0:ea85c4bb5e1f 51 const int bytesToWrite = context->commandLen;
dan_ackme 0:ea85c4bb5e1f 52 const int bytesWritten = serial.write(context->commandPtr, bytesToWrite, timeout);
dan_ackme 0:ea85c4bb5e1f 53 context->commandPtr += bytesWritten;
dan_ackme 0:ea85c4bb5e1f 54 context->commandLen -= bytesWritten;
dan_ackme 0:ea85c4bb5e1f 55 if(bytesToWrite != bytesWritten)
dan_ackme 0:ea85c4bb5e1f 56 {
dan_ackme 0:ea85c4bb5e1f 57 if(timeoutTimer.timedOut(context->timeoutMs))
dan_ackme 0:ea85c4bb5e1f 58 {
dan_ackme 0:ea85c4bb5e1f 59 issueCommandCallback(WICONNECT_TIMEOUT);
dan_ackme 0:ea85c4bb5e1f 60 return WICONNECT_TIMEOUT;
dan_ackme 0:ea85c4bb5e1f 61 }
dan_ackme 0:ea85c4bb5e1f 62 else
dan_ackme 0:ea85c4bb5e1f 63 {
dan_ackme 0:ea85c4bb5e1f 64 return WICONNECT_PROCESSING;
dan_ackme 0:ea85c4bb5e1f 65 }
dan_ackme 0:ea85c4bb5e1f 66 }
dan_ackme 0:ea85c4bb5e1f 67 }
dan_ackme 0:ea85c4bb5e1f 68
dan_ackme 0:ea85c4bb5e1f 69 while(context->reader.isValid())
dan_ackme 0:ea85c4bb5e1f 70 {
dan_ackme 0:ea85c4bb5e1f 71 if(context->bytesToWrite == 0)
dan_ackme 0:ea85c4bb5e1f 72 {
dan_ackme 0:ea85c4bb5e1f 73 context->responseBufferPtr = context->responseBuffer;
dan_ackme 0:ea85c4bb5e1f 74 if(WICONNECT_FAILED(result, context->reader.call(context->user, context->responseBuffer, context->responseBufferLen, &context->bytesToWrite)))
dan_ackme 0:ea85c4bb5e1f 75 {
dan_ackme 0:ea85c4bb5e1f 76 issueCommandCallback(result);
dan_ackme 0:ea85c4bb5e1f 77 return result;
dan_ackme 0:ea85c4bb5e1f 78 }
dan_ackme 0:ea85c4bb5e1f 79 else if(context->bytesToWrite == EOF)
dan_ackme 0:ea85c4bb5e1f 80 {
dan_ackme 0:ea85c4bb5e1f 81 context->reader.setInvalid();
dan_ackme 0:ea85c4bb5e1f 82 context->bytesToWrite = 0;
dan_ackme 0:ea85c4bb5e1f 83 context->responseBufferPtr = context->responseBuffer;
dan_ackme 0:ea85c4bb5e1f 84 break;
dan_ackme 0:ea85c4bb5e1f 85 }
dan_ackme 0:ea85c4bb5e1f 86 else
dan_ackme 0:ea85c4bb5e1f 87 {
dan_ackme 0:ea85c4bb5e1f 88 timeoutTimer.reset();
dan_ackme 0:ea85c4bb5e1f 89 }
dan_ackme 0:ea85c4bb5e1f 90 }
dan_ackme 0:ea85c4bb5e1f 91 if(context->bytesToWrite > 0)
dan_ackme 0:ea85c4bb5e1f 92 {
dan_ackme 0:ea85c4bb5e1f 93 const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs);
dan_ackme 0:ea85c4bb5e1f 94 const int bytesToWrite = context->bytesToWrite;
dan_ackme 0:ea85c4bb5e1f 95 const int bytesWritten = serial.write(context->responseBufferPtr, bytesToWrite, timeout);
dan_ackme 0:ea85c4bb5e1f 96 context->responseBufferPtr += bytesWritten;
dan_ackme 0:ea85c4bb5e1f 97 context->bytesToWrite -= bytesWritten;
dan_ackme 0:ea85c4bb5e1f 98 if(bytesToWrite != bytesWritten)
dan_ackme 0:ea85c4bb5e1f 99 {
dan_ackme 0:ea85c4bb5e1f 100 if(timeoutTimer.timedOut(context->timeoutMs))
dan_ackme 0:ea85c4bb5e1f 101 {
dan_ackme 0:ea85c4bb5e1f 102 issueCommandCallback(WICONNECT_TIMEOUT);
dan_ackme 0:ea85c4bb5e1f 103 return WICONNECT_TIMEOUT;
dan_ackme 0:ea85c4bb5e1f 104 }
dan_ackme 0:ea85c4bb5e1f 105 else
dan_ackme 0:ea85c4bb5e1f 106 {
dan_ackme 0:ea85c4bb5e1f 107 return WICONNECT_PROCESSING;
dan_ackme 0:ea85c4bb5e1f 108 }
dan_ackme 0:ea85c4bb5e1f 109 }
dan_ackme 0:ea85c4bb5e1f 110 }
dan_ackme 0:ea85c4bb5e1f 111 }
dan_ackme 0:ea85c4bb5e1f 112
dan_ackme 0:ea85c4bb5e1f 113 result = receiveResponse();
dan_ackme 0:ea85c4bb5e1f 114 if(result == WICONNECT_PROCESSING && !context->nonBlocking)
dan_ackme 0:ea85c4bb5e1f 115 {
dan_ackme 0:ea85c4bb5e1f 116 goto start;
dan_ackme 0:ea85c4bb5e1f 117 }
dan_ackme 0:ea85c4bb5e1f 118 return result;
dan_ackme 0:ea85c4bb5e1f 119 }
dan_ackme 0:ea85c4bb5e1f 120
dan_ackme 0:ea85c4bb5e1f 121 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 122 WiconnectResult Wiconnect::receiveResponse()
dan_ackme 0:ea85c4bb5e1f 123 {
dan_ackme 5:8d91a87ebba2 124 loop:
dan_ackme 5:8d91a87ebba2 125 WiconnectResult result = receivePacket();
dan_ackme 5:8d91a87ebba2 126
dan_ackme 5:8d91a87ebba2 127 if(result == WICONNECT_PROCESSING)
dan_ackme 0:ea85c4bb5e1f 128 {
dan_ackme 5:8d91a87ebba2 129 }
dan_ackme 5:8d91a87ebba2 130 else if(result == WICONNECT_SUCCESS)
dan_ackme 5:8d91a87ebba2 131 {
dan_ackme 5:8d91a87ebba2 132 CommandHeader *header = (CommandHeader*)commandHeaderBuffer;
dan_ackme 5:8d91a87ebba2 133 CommandContext *context = (CommandContext*)commandContext;
dan_ackme 0:ea85c4bb5e1f 134
dan_ackme 5:8d91a87ebba2 135 // TODO: need to notify safemode
dan_ackme 5:8d91a87ebba2 136
dan_ackme 5:8d91a87ebba2 137 if(header->response_type == WICONNECT_CMD_TYPE_REPLY || header->response_type == WICONNECT_CMD_TYPE_SAFEMODE)
dan_ackme 0:ea85c4bb5e1f 138 {
dan_ackme 5:8d91a87ebba2 139 if(header->response_code != WICONNECT_CMD_SUCCESS)
dan_ackme 0:ea85c4bb5e1f 140 {
dan_ackme 5:8d91a87ebba2 141 DEBUG_CMD_ERROR(header->response_code);
dan_ackme 5:8d91a87ebba2 142 flush();
dan_ackme 5:8d91a87ebba2 143 issueCommandCallback(WICONNECT_CMD_RESPONSE_ERROR);
dan_ackme 5:8d91a87ebba2 144 return WICONNECT_CMD_RESPONSE_ERROR;
dan_ackme 5:8d91a87ebba2 145 }
dan_ackme 5:8d91a87ebba2 146 else if(header->response_len > 0)
dan_ackme 5:8d91a87ebba2 147 {
dan_ackme 24:e27e23297f02 148 DEBUG_CMD_RESPONSE(context->responseBuffer);
dan_ackme 24:e27e23297f02 149 if(header->response_len < context->responseBufferLen)
dan_ackme 21:17bb3eddcbae 150 {
dan_ackme 24:e27e23297f02 151 context->responseBuffer[header->response_len] = 0;
dan_ackme 21:17bb3eddcbae 152 }
dan_ackme 0:ea85c4bb5e1f 153 }
dan_ackme 0:ea85c4bb5e1f 154 else
dan_ackme 0:ea85c4bb5e1f 155 {
dan_ackme 5:8d91a87ebba2 156 *context->responseBuffer = 0;
dan_ackme 0:ea85c4bb5e1f 157 }
dan_ackme 5:8d91a87ebba2 158
dan_ackme 5:8d91a87ebba2 159 issueCommandCallback(WICONNECT_SUCCESS);
dan_ackme 5:8d91a87ebba2 160
dan_ackme 5:8d91a87ebba2 161 return WICONNECT_SUCCESS;
dan_ackme 0:ea85c4bb5e1f 162 }
dan_ackme 0:ea85c4bb5e1f 163 else
dan_ackme 0:ea85c4bb5e1f 164 {
dan_ackme 5:8d91a87ebba2 165 DEBUG_CMD_LOG(context->responseBuffer);
dan_ackme 5:8d91a87ebba2 166 RESET_CMD_HEADER(header);
dan_ackme 5:8d91a87ebba2 167 context->responseBufferPtr = context->responseBuffer;
dan_ackme 5:8d91a87ebba2 168 goto loop;
dan_ackme 0:ea85c4bb5e1f 169 }
dan_ackme 0:ea85c4bb5e1f 170 }
dan_ackme 5:8d91a87ebba2 171 else
dan_ackme 5:8d91a87ebba2 172 {
dan_ackme 5:8d91a87ebba2 173 issueCommandCallback(result);
dan_ackme 5:8d91a87ebba2 174 }
dan_ackme 0:ea85c4bb5e1f 175
dan_ackme 5:8d91a87ebba2 176 return result;
dan_ackme 0:ea85c4bb5e1f 177 }
dan_ackme 0:ea85c4bb5e1f 178
dan_ackme 0:ea85c4bb5e1f 179 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 180 WiconnectResult Wiconnect::receivePacket()
dan_ackme 0:ea85c4bb5e1f 181 {
dan_ackme 0:ea85c4bb5e1f 182 CommandHeader *header = (CommandHeader*)commandHeaderBuffer;
dan_ackme 0:ea85c4bb5e1f 183 CommandContext *context = (CommandContext*)commandContext;
dan_ackme 0:ea85c4bb5e1f 184
dan_ackme 0:ea85c4bb5e1f 185 if(header->bytes_remaining > 0)
dan_ackme 0:ea85c4bb5e1f 186 {
dan_ackme 0:ea85c4bb5e1f 187 uint16_t bytesReceived;
dan_ackme 0:ea85c4bb5e1f 188 uint8_t buffer[WICONNECT_HEADER_LENGTH];
dan_ackme 0:ea85c4bb5e1f 189
dan_ackme 0:ea85c4bb5e1f 190 while(header->bytes_remaining > 0)
dan_ackme 0:ea85c4bb5e1f 191 {
dan_ackme 0:ea85c4bb5e1f 192 const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs);
dan_ackme 0:ea85c4bb5e1f 193 bytesReceived = serial.read((char*)buffer, header->bytes_remaining, timeout);
dan_ackme 0:ea85c4bb5e1f 194 if(bytesReceived == 0)
dan_ackme 0:ea85c4bb5e1f 195 {
dan_ackme 0:ea85c4bb5e1f 196 return timeoutTimer.timedOut(context->timeoutMs) ? WICONNECT_TIMEOUT : WICONNECT_PROCESSING;
dan_ackme 0:ea85c4bb5e1f 197 }
dan_ackme 0:ea85c4bb5e1f 198
dan_ackme 0:ea85c4bb5e1f 199 for(uint8_t *ptr = buffer; bytesReceived > 0; ++ptr)
dan_ackme 0:ea85c4bb5e1f 200 {
dan_ackme 0:ea85c4bb5e1f 201 if(header->response_type == WICONNECT_CMD_TYPE_NULL)
dan_ackme 0:ea85c4bb5e1f 202 {
dan_ackme 0:ea85c4bb5e1f 203 if( *ptr == WICONNECT_CMD_TYPE_REPLY ||
dan_ackme 0:ea85c4bb5e1f 204 *ptr == WICONNECT_CMD_TYPE_LOG ||
dan_ackme 0:ea85c4bb5e1f 205 *ptr == WICONNECT_CMD_TYPE_SAFEMODE)
dan_ackme 0:ea85c4bb5e1f 206 {
dan_ackme 0:ea85c4bb5e1f 207 header->response_type = (ResponseType)*ptr;
dan_ackme 0:ea85c4bb5e1f 208 -- header->bytes_remaining;
dan_ackme 0:ea85c4bb5e1f 209 }
dan_ackme 0:ea85c4bb5e1f 210 --bytesReceived;
dan_ackme 0:ea85c4bb5e1f 211 }
dan_ackme 0:ea85c4bb5e1f 212 else if(header->response_code == WICONNECT_CMD_CODE_NULL)
dan_ackme 0:ea85c4bb5e1f 213 {
dan_ackme 0:ea85c4bb5e1f 214 if(*ptr >= '0' && *ptr <= '7')
dan_ackme 0:ea85c4bb5e1f 215 {
dan_ackme 0:ea85c4bb5e1f 216 header->response_code = (ResponseCode)(*ptr - '0' + 1);
dan_ackme 0:ea85c4bb5e1f 217 --header->bytes_remaining;
dan_ackme 0:ea85c4bb5e1f 218 header->len_buffer_ptr = header->len_buffer;
dan_ackme 0:ea85c4bb5e1f 219 }
dan_ackme 0:ea85c4bb5e1f 220 else
dan_ackme 0:ea85c4bb5e1f 221 {
dan_ackme 0:ea85c4bb5e1f 222 RESET_CMD_HEADER(header);
dan_ackme 0:ea85c4bb5e1f 223 }
dan_ackme 0:ea85c4bb5e1f 224 --bytesReceived;
dan_ackme 0:ea85c4bb5e1f 225 }
dan_ackme 0:ea85c4bb5e1f 226 else if(header->bytes_remaining > 2)
dan_ackme 0:ea85c4bb5e1f 227 {
dan_ackme 0:ea85c4bb5e1f 228 uint8_t len_chars = MIN((int)bytesReceived, (int)(header->bytes_remaining-2));
dan_ackme 0:ea85c4bb5e1f 229 header->bytes_remaining -= len_chars;
dan_ackme 0:ea85c4bb5e1f 230 bytesReceived -= len_chars;
dan_ackme 0:ea85c4bb5e1f 231 while(len_chars-- > 0)
dan_ackme 0:ea85c4bb5e1f 232 {
dan_ackme 0:ea85c4bb5e1f 233 *header->len_buffer_ptr++ = *ptr++;
dan_ackme 0:ea85c4bb5e1f 234 }
dan_ackme 0:ea85c4bb5e1f 235 --ptr; // need to decrement since the for loop increments
dan_ackme 0:ea85c4bb5e1f 236 if(header->bytes_remaining == 2)
dan_ackme 0:ea85c4bb5e1f 237 {
dan_ackme 0:ea85c4bb5e1f 238 uint32_t packetLen;
dan_ackme 0:ea85c4bb5e1f 239 *header->len_buffer_ptr = 0;
dan_ackme 0:ea85c4bb5e1f 240 if(!StringUtil::strToUint32((const char*)header->len_buffer, &packetLen))
dan_ackme 0:ea85c4bb5e1f 241 {
dan_ackme 0:ea85c4bb5e1f 242 RESET_CMD_HEADER(header);
dan_ackme 0:ea85c4bb5e1f 243 }
dan_ackme 0:ea85c4bb5e1f 244 else
dan_ackme 24:e27e23297f02 245 {
dan_ackme 24:e27e23297f02 246 if(packetLen > 0)
dan_ackme 24:e27e23297f02 247 {
dan_ackme 24:e27e23297f02 248 if(packetLen == 1 || packetLen == 2)
dan_ackme 24:e27e23297f02 249 {
dan_ackme 24:e27e23297f02 250 return WICONNECT_CMD_RESPONSE_ERROR;
dan_ackme 24:e27e23297f02 251 }
dan_ackme 24:e27e23297f02 252 packetLen -= 2;
dan_ackme 17:7268f365676b 253 }
dan_ackme 0:ea85c4bb5e1f 254 if((int)packetLen > context->responseBufferLen)
dan_ackme 0:ea85c4bb5e1f 255 {
dan_ackme 0:ea85c4bb5e1f 256 DEBUG_ERROR("Packet larger than response buffer: %d > %d", packetLen, context->responseBufferLen);
dan_ackme 0:ea85c4bb5e1f 257 return WICONNECT_OVERFLOW;
dan_ackme 0:ea85c4bb5e1f 258 }
dan_ackme 0:ea85c4bb5e1f 259 header->response_len = (uint16_t)packetLen;
dan_ackme 0:ea85c4bb5e1f 260 context->bytesToRead = packetLen;
dan_ackme 0:ea85c4bb5e1f 261 }
dan_ackme 0:ea85c4bb5e1f 262 }
dan_ackme 0:ea85c4bb5e1f 263 }
dan_ackme 0:ea85c4bb5e1f 264 else if(header->bytes_remaining == 2)
dan_ackme 0:ea85c4bb5e1f 265 {
dan_ackme 0:ea85c4bb5e1f 266 --bytesReceived;
dan_ackme 0:ea85c4bb5e1f 267 if(*ptr == '\r')
dan_ackme 0:ea85c4bb5e1f 268 {
dan_ackme 0:ea85c4bb5e1f 269 header->bytes_remaining = 1;
dan_ackme 0:ea85c4bb5e1f 270 }
dan_ackme 0:ea85c4bb5e1f 271 else
dan_ackme 0:ea85c4bb5e1f 272 {
dan_ackme 0:ea85c4bb5e1f 273 RESET_CMD_HEADER(header);
dan_ackme 0:ea85c4bb5e1f 274 }
dan_ackme 0:ea85c4bb5e1f 275 }
dan_ackme 0:ea85c4bb5e1f 276 else
dan_ackme 0:ea85c4bb5e1f 277 {
dan_ackme 0:ea85c4bb5e1f 278 --bytesReceived;
dan_ackme 0:ea85c4bb5e1f 279 if(*ptr == '\n')
dan_ackme 0:ea85c4bb5e1f 280 {
dan_ackme 0:ea85c4bb5e1f 281 header->bytes_remaining = 0;
dan_ackme 0:ea85c4bb5e1f 282 break;
dan_ackme 0:ea85c4bb5e1f 283 }
dan_ackme 0:ea85c4bb5e1f 284 else
dan_ackme 0:ea85c4bb5e1f 285 {
dan_ackme 0:ea85c4bb5e1f 286 RESET_CMD_HEADER(header);
dan_ackme 0:ea85c4bb5e1f 287 }
dan_ackme 0:ea85c4bb5e1f 288 }
dan_ackme 0:ea85c4bb5e1f 289 }
dan_ackme 0:ea85c4bb5e1f 290 }
dan_ackme 0:ea85c4bb5e1f 291 }
dan_ackme 0:ea85c4bb5e1f 292
dan_ackme 0:ea85c4bb5e1f 293 while(context->bytesToRead > 0)
dan_ackme 0:ea85c4bb5e1f 294 {
dan_ackme 0:ea85c4bb5e1f 295 const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs);
dan_ackme 0:ea85c4bb5e1f 296 const int bytesToRead = context->bytesToRead;
dan_ackme 0:ea85c4bb5e1f 297 const int bytesReceived = serial.read(context->responseBufferPtr, bytesToRead, timeout);
dan_ackme 0:ea85c4bb5e1f 298 context->responseBufferPtr += bytesReceived;
dan_ackme 0:ea85c4bb5e1f 299 context->bytesToRead -= bytesReceived;
dan_ackme 0:ea85c4bb5e1f 300
dan_ackme 0:ea85c4bb5e1f 301 if(bytesReceived != bytesToRead)
dan_ackme 0:ea85c4bb5e1f 302 {
dan_ackme 0:ea85c4bb5e1f 303 return timeoutTimer.timedOut(context->timeoutMs) ? WICONNECT_TIMEOUT : WICONNECT_PROCESSING;
dan_ackme 0:ea85c4bb5e1f 304 }
dan_ackme 0:ea85c4bb5e1f 305 else if(context->bytesToRead == 0)
dan_ackme 0:ea85c4bb5e1f 306 {
dan_ackme 24:e27e23297f02 307 *context->responseBufferPtr = 0;
dan_ackme 24:e27e23297f02 308
dan_ackme 24:e27e23297f02 309 // read the trailing \r\n
dan_ackme 24:e27e23297f02 310 char trailingCRLF[2];
dan_ackme 24:e27e23297f02 311 const int bytesReceived = serial.read(trailingCRLF, 2, 100);
dan_ackme 24:e27e23297f02 312 // FIXME there's a potenital weakness where the trailing \r\n isn't ready to be recieved
dan_ackme 24:e27e23297f02 313 if(bytesReceived != 2)
dan_ackme 24:e27e23297f02 314 {
dan_ackme 24:e27e23297f02 315 return WICONNECT_TIMEOUT;
dan_ackme 17:7268f365676b 316 }
dan_ackme 0:ea85c4bb5e1f 317 }
dan_ackme 0:ea85c4bb5e1f 318 }
dan_ackme 0:ea85c4bb5e1f 319
dan_ackme 0:ea85c4bb5e1f 320 return (header->response_code != WICONNECT_CMD_CODE_NULL &&
dan_ackme 0:ea85c4bb5e1f 321 header->response_type != WICONNECT_CMD_TYPE_NULL &&
dan_ackme 0:ea85c4bb5e1f 322 context->bytesToRead == 0) ? WICONNECT_SUCCESS : WICONNECT_PROCESSING;
dan_ackme 0:ea85c4bb5e1f 323 }
dan_ackme 0:ea85c4bb5e1f 324
dan_ackme 0:ea85c4bb5e1f 325 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 326 void Wiconnect::issueCommandCallback(WiconnectResult result)
dan_ackme 0:ea85c4bb5e1f 327 {
dan_ackme 0:ea85c4bb5e1f 328 CommandHeader *header = (CommandHeader*)commandHeaderBuffer;
dan_ackme 0:ea85c4bb5e1f 329 CommandContext *context = (CommandContext*)commandContext;
dan_ackme 0:ea85c4bb5e1f 330 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 0:ea85c4bb5e1f 331 void *returnPtr = (currentQueuedCommand != NULL) ? (void*)currentQueuedCommand : (void*)context->responseBuffer;
dan_ackme 0:ea85c4bb5e1f 332 currentQueuedCommand = NULL;
dan_ackme 0:ea85c4bb5e1f 333 commandProcessorTimer.stop();
dan_ackme 0:ea85c4bb5e1f 334 #else
dan_ackme 0:ea85c4bb5e1f 335 void *returnPtr = (void*)context->responseBuffer;
dan_ackme 0:ea85c4bb5e1f 336 #endif
dan_ackme 0:ea85c4bb5e1f 337 context->callback.call(result, returnPtr, (void*)(uint32_t)header->response_len);
dan_ackme 0:ea85c4bb5e1f 338 commandExecuting = false;
dan_ackme 0:ea85c4bb5e1f 339
dan_ackme 0:ea85c4bb5e1f 340 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 0:ea85c4bb5e1f 341 processNextQueuedCommand();
dan_ackme 0:ea85c4bb5e1f 342 #endif
dan_ackme 0:ea85c4bb5e1f 343 }
dan_ackme 0:ea85c4bb5e1f 344
dan_ackme 0:ea85c4bb5e1f 345 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 346 void Wiconnect::stopCurrentCommand()
dan_ackme 0:ea85c4bb5e1f 347 {
dan_ackme 0:ea85c4bb5e1f 348 internalProcessingState = 0;
dan_ackme 0:ea85c4bb5e1f 349 issueCommandCallback(WICONNECT_ABORTED);
dan_ackme 0:ea85c4bb5e1f 350 }
dan_ackme 0:ea85c4bb5e1f 351