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 Aug 23 05:39:17 2014 -0700
Revision:
17:7268f365676b
Child:
21:17bb3eddcbae
Fixes and documentation updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dan_ackme 17:7268f365676b 1 /**
dan_ackme 17:7268f365676b 2 * ACKme WiConnect Host Library is licensed under the BSD licence:
dan_ackme 17:7268f365676b 3 *
dan_ackme 17:7268f365676b 4 * Copyright (c)2014 ACKme Networks.
dan_ackme 17:7268f365676b 5 * All rights reserved.
dan_ackme 17:7268f365676b 6 *
dan_ackme 17:7268f365676b 7 * Redistribution and use in source and binary forms, with or without modification,
dan_ackme 17:7268f365676b 8 * are permitted provided that the following conditions are met:
dan_ackme 17:7268f365676b 9 *
dan_ackme 17:7268f365676b 10 * 1. Redistributions of source code must retain the above copyright notice,
dan_ackme 17:7268f365676b 11 * this list of conditions and the following disclaimer.
dan_ackme 17:7268f365676b 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
dan_ackme 17:7268f365676b 13 * this list of conditions and the following disclaimer in the documentation
dan_ackme 17:7268f365676b 14 * and/or other materials provided with the distribution.
dan_ackme 17:7268f365676b 15 * 3. The name of the author may not be used to endorse or promote products
dan_ackme 17:7268f365676b 16 * derived from this software without specific prior written permission.
dan_ackme 17:7268f365676b 17 *
dan_ackme 17:7268f365676b 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
dan_ackme 17:7268f365676b 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
dan_ackme 17:7268f365676b 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
dan_ackme 17:7268f365676b 21 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
dan_ackme 17:7268f365676b 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
dan_ackme 17:7268f365676b 23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dan_ackme 17:7268f365676b 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dan_ackme 17:7268f365676b 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
dan_ackme 17:7268f365676b 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
dan_ackme 17:7268f365676b 27 * OF SUCH DAMAGE.
dan_ackme 17:7268f365676b 28 */
dan_ackme 17:7268f365676b 29 #include <stdarg.h>
dan_ackme 17:7268f365676b 30 #include "Wiconnect.h"
dan_ackme 17:7268f365676b 31 #include "internal/common.h"
dan_ackme 17:7268f365676b 32 #include "StringUtil.h"
dan_ackme 17:7268f365676b 33
dan_ackme 17:7268f365676b 34
dan_ackme 17:7268f365676b 35 #define CHECK_CONNECTED() if(!isConnected()) return WICONNECT_NOT_CONNECTED
dan_ackme 17:7268f365676b 36
dan_ackme 17:7268f365676b 37
dan_ackme 17:7268f365676b 38 /*************************************************************************************************/
dan_ackme 17:7268f365676b 39 WiconnectSocket::WiconnectSocket(int rxBufferLen_, void *rxBuffer_, int txBufferLen_, void *txBuffer_)
dan_ackme 17:7268f365676b 40 {
dan_ackme 17:7268f365676b 41 wiconnect = Wiconnect::getInstance();
dan_ackme 17:7268f365676b 42
dan_ackme 17:7268f365676b 43 memset(&txBuffer, 0, sizeof(Buffer));
dan_ackme 17:7268f365676b 44 memset(&rxBuffer, 0, sizeof(Buffer));
dan_ackme 17:7268f365676b 45
dan_ackme 17:7268f365676b 46 txBuffer.size = !wiconnect->nonBlocking ? txBufferLen_ : 0;
dan_ackme 17:7268f365676b 47 txBuffer.buffer = (uint8_t*)txBuffer_;
dan_ackme 17:7268f365676b 48
dan_ackme 17:7268f365676b 49 rxBuffer.size = !wiconnect->nonBlocking ? rxBufferLen_ : 0;
dan_ackme 17:7268f365676b 50 rxBuffer.buffer = (uint8_t*)rxBuffer_;
dan_ackme 17:7268f365676b 51
dan_ackme 17:7268f365676b 52 if(txBuffer.size > 0)
dan_ackme 17:7268f365676b 53 {
dan_ackme 17:7268f365676b 54 if(txBuffer_ == NULL)
dan_ackme 17:7268f365676b 55 {
dan_ackme 17:7268f365676b 56 #ifdef WICONNECT_ENABLE_MALLOC
dan_ackme 17:7268f365676b 57 wiconnect_assert(wiconnect, "Socket(), malloc not defined", wiconnect->_malloc != NULL);
dan_ackme 17:7268f365676b 58 txBuffer.buffer = (uint8_t*)wiconnect->_malloc(txBufferLen_);
dan_ackme 17:7268f365676b 59 wiconnect_assert(wiconnect, "Socket(), txBuffer malloc failed", txBuffer.buffer != NULL);
dan_ackme 17:7268f365676b 60 txBuffer.allocated = true;
dan_ackme 17:7268f365676b 61 #else
dan_ackme 17:7268f365676b 62 wiconnect_assert(0);
dan_ackme 17:7268f365676b 63 #endif
dan_ackme 17:7268f365676b 64 }
dan_ackme 17:7268f365676b 65 }
dan_ackme 17:7268f365676b 66
dan_ackme 17:7268f365676b 67 if(rxBuffer.size > 0)
dan_ackme 17:7268f365676b 68 {
dan_ackme 17:7268f365676b 69 if(rxBuffer_ == NULL)
dan_ackme 17:7268f365676b 70 {
dan_ackme 17:7268f365676b 71 #ifdef WICONNECT_ENABLE_MALLOC
dan_ackme 17:7268f365676b 72 wiconnect_assert(wiconnect, "Socket(), malloc not defined", wiconnect->_malloc != NULL);
dan_ackme 17:7268f365676b 73 rxBuffer.buffer = (uint8_t*)wiconnect->_malloc(rxBufferLen_);
dan_ackme 17:7268f365676b 74 wiconnect_assert(wiconnect, "Socket(), rxBuffer malloc failed", rxBuffer.buffer != NULL);
dan_ackme 17:7268f365676b 75 rxBuffer.allocated = true;
dan_ackme 17:7268f365676b 76 #else
dan_ackme 17:7268f365676b 77 wiconnect_assert(0);
dan_ackme 17:7268f365676b 78 #endif
dan_ackme 17:7268f365676b 79 }
dan_ackme 17:7268f365676b 80 }
dan_ackme 17:7268f365676b 81
dan_ackme 17:7268f365676b 82 handle = SOCKET_INVALID_HANDLE;
dan_ackme 17:7268f365676b 83 type = SOCKET_TYPE_UNKNOWN;
dan_ackme 17:7268f365676b 84 remotePort = 0;
dan_ackme 17:7268f365676b 85 localPort = 0;
dan_ackme 17:7268f365676b 86 connected = false;
dan_ackme 17:7268f365676b 87 host[0] = 0;
dan_ackme 17:7268f365676b 88 }
dan_ackme 17:7268f365676b 89
dan_ackme 17:7268f365676b 90
dan_ackme 17:7268f365676b 91 /*************************************************************************************************/
dan_ackme 17:7268f365676b 92 WiconnectResult WiconnectSocket::init(uint8_t handle_, SocketType type_, const char *host_, uint16_t remotePort_, uint16_t localPort_)
dan_ackme 17:7268f365676b 93 {
dan_ackme 17:7268f365676b 94 handle = handle_;
dan_ackme 17:7268f365676b 95 type = type_;
dan_ackme 17:7268f365676b 96 remotePort = remotePort_;
dan_ackme 17:7268f365676b 97 localPort = localPort_;
dan_ackme 17:7268f365676b 98 connected = true;
dan_ackme 17:7268f365676b 99
dan_ackme 17:7268f365676b 100 txBuffer.ptr = txBuffer.buffer;
dan_ackme 17:7268f365676b 101 rxBuffer.ptr = rxBuffer.buffer;
dan_ackme 17:7268f365676b 102
dan_ackme 17:7268f365676b 103 strncpy(host, host_, sizeof(host)-1);
dan_ackme 17:7268f365676b 104
dan_ackme 17:7268f365676b 105 return WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 106 }
dan_ackme 17:7268f365676b 107
dan_ackme 17:7268f365676b 108 /*************************************************************************************************/
dan_ackme 17:7268f365676b 109 WiconnectSocket::~WiconnectSocket()
dan_ackme 17:7268f365676b 110 {
dan_ackme 17:7268f365676b 111 while((handle != SOCKET_INVALID_HANDLE) && (close() == WICONNECT_PROCESSING))
dan_ackme 17:7268f365676b 112 {
dan_ackme 17:7268f365676b 113 }
dan_ackme 17:7268f365676b 114
dan_ackme 17:7268f365676b 115 #ifdef WICONNECT_ENABLE_MALLOC
dan_ackme 17:7268f365676b 116 if(txBuffer.allocated && txBuffer.size > 0)
dan_ackme 17:7268f365676b 117 {
dan_ackme 17:7268f365676b 118 wiconnect_assert(wiconnect, "~Socket(), free not defined", wiconnect->_free != NULL);
dan_ackme 17:7268f365676b 119 wiconnect->_free(txBuffer.buffer);
dan_ackme 17:7268f365676b 120 }
dan_ackme 17:7268f365676b 121 if(rxBuffer.allocated && rxBuffer.size > 0)
dan_ackme 17:7268f365676b 122 {
dan_ackme 17:7268f365676b 123 wiconnect_assert(wiconnect, "~Socket(), free not defined", wiconnect->_free != NULL);
dan_ackme 17:7268f365676b 124 wiconnect->_free(rxBuffer.buffer);
dan_ackme 17:7268f365676b 125 }
dan_ackme 17:7268f365676b 126 #endif
dan_ackme 17:7268f365676b 127 }
dan_ackme 17:7268f365676b 128
dan_ackme 17:7268f365676b 129 /*************************************************************************************************/
dan_ackme 17:7268f365676b 130 bool WiconnectSocket::isConnected()
dan_ackme 17:7268f365676b 131 {
dan_ackme 17:7268f365676b 132 return connected;
dan_ackme 17:7268f365676b 133 }
dan_ackme 17:7268f365676b 134
dan_ackme 17:7268f365676b 135 /*************************************************************************************************/
dan_ackme 17:7268f365676b 136 SocketType WiconnectSocket::getType()
dan_ackme 17:7268f365676b 137 {
dan_ackme 17:7268f365676b 138 return type;
dan_ackme 17:7268f365676b 139 }
dan_ackme 17:7268f365676b 140
dan_ackme 17:7268f365676b 141 /*************************************************************************************************/
dan_ackme 17:7268f365676b 142 const char* WiconnectSocket::getHost()
dan_ackme 17:7268f365676b 143 {
dan_ackme 17:7268f365676b 144 return host;
dan_ackme 17:7268f365676b 145 }
dan_ackme 17:7268f365676b 146
dan_ackme 17:7268f365676b 147 /*************************************************************************************************/
dan_ackme 17:7268f365676b 148 uint16_t WiconnectSocket::getLocalPort()
dan_ackme 17:7268f365676b 149 {
dan_ackme 17:7268f365676b 150 return localPort;
dan_ackme 17:7268f365676b 151 }
dan_ackme 17:7268f365676b 152
dan_ackme 17:7268f365676b 153 /*************************************************************************************************/
dan_ackme 17:7268f365676b 154 uint16_t WiconnectSocket::getRemotePort()
dan_ackme 17:7268f365676b 155 {
dan_ackme 17:7268f365676b 156 return remotePort;
dan_ackme 17:7268f365676b 157 }
dan_ackme 17:7268f365676b 158
dan_ackme 17:7268f365676b 159 /*************************************************************************************************/
dan_ackme 17:7268f365676b 160 uint8_t WiconnectSocket::getHandle()
dan_ackme 17:7268f365676b 161 {
dan_ackme 17:7268f365676b 162 return handle;
dan_ackme 17:7268f365676b 163 }
dan_ackme 17:7268f365676b 164
dan_ackme 17:7268f365676b 165
dan_ackme 17:7268f365676b 166 /*************************************************************************************************/
dan_ackme 17:7268f365676b 167 WiconnectResult WiconnectSocket::close()
dan_ackme 17:7268f365676b 168 {
dan_ackme 17:7268f365676b 169 WiconnectResult result;
dan_ackme 17:7268f365676b 170 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 171 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 17:7268f365676b 172
dan_ackme 17:7268f365676b 173 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("close %d", handle)))
dan_ackme 17:7268f365676b 174 {
dan_ackme 17:7268f365676b 175 connected = false;
dan_ackme 17:7268f365676b 176 }
dan_ackme 17:7268f365676b 177
dan_ackme 17:7268f365676b 178 CHECK_CLEANUP_COMMAND();
dan_ackme 17:7268f365676b 179
dan_ackme 17:7268f365676b 180 return result;
dan_ackme 17:7268f365676b 181 }
dan_ackme 17:7268f365676b 182
dan_ackme 17:7268f365676b 183 /*************************************************************************************************/
dan_ackme 17:7268f365676b 184 WiconnectResult WiconnectSocket::poll(bool *rxDataAvailablePtr, bool autoClose)
dan_ackme 17:7268f365676b 185 {
dan_ackme 17:7268f365676b 186 WiconnectResult result;
dan_ackme 17:7268f365676b 187 int32_t status;
dan_ackme 17:7268f365676b 188
dan_ackme 17:7268f365676b 189 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 190 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 17:7268f365676b 191
dan_ackme 17:7268f365676b 192 *rxDataAvailablePtr = false;
dan_ackme 17:7268f365676b 193
dan_ackme 17:7268f365676b 194 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("poll %d", handle)))
dan_ackme 17:7268f365676b 195 {
dan_ackme 17:7268f365676b 196 if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
dan_ackme 17:7268f365676b 197 {
dan_ackme 17:7268f365676b 198 if(status > 0)
dan_ackme 17:7268f365676b 199 {
dan_ackme 17:7268f365676b 200 *rxDataAvailablePtr = true;
dan_ackme 17:7268f365676b 201 if(status == 2 && autoClose)
dan_ackme 17:7268f365676b 202 {
dan_ackme 17:7268f365676b 203 connected = false;
dan_ackme 17:7268f365676b 204 }
dan_ackme 17:7268f365676b 205 }
dan_ackme 17:7268f365676b 206 }
dan_ackme 17:7268f365676b 207 }
dan_ackme 17:7268f365676b 208
dan_ackme 17:7268f365676b 209 CHECK_CLEANUP_COMMAND();
dan_ackme 17:7268f365676b 210
dan_ackme 17:7268f365676b 211 return result;
dan_ackme 17:7268f365676b 212 }
dan_ackme 17:7268f365676b 213
dan_ackme 17:7268f365676b 214 /*************************************************************************************************/
dan_ackme 17:7268f365676b 215 WiconnectResult WiconnectSocket::write(int length, bool flush)
dan_ackme 17:7268f365676b 216 {
dan_ackme 17:7268f365676b 217 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 218
dan_ackme 17:7268f365676b 219 if( txBuffer.size == 0)
dan_ackme 17:7268f365676b 220 {
dan_ackme 17:7268f365676b 221 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 222 }
dan_ackme 17:7268f365676b 223 else if(length > txBuffer.size)
dan_ackme 17:7268f365676b 224 {
dan_ackme 17:7268f365676b 225 return WICONNECT_OVERFLOW;
dan_ackme 17:7268f365676b 226 }
dan_ackme 17:7268f365676b 227 txBuffer.bytesPending = length;
dan_ackme 17:7268f365676b 228
dan_ackme 17:7268f365676b 229 return flush ? flushTxBuffer() : WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 230 }
dan_ackme 17:7268f365676b 231
dan_ackme 17:7268f365676b 232 /*************************************************************************************************/
dan_ackme 17:7268f365676b 233 WiconnectResult WiconnectSocket::write(const void* buffer, int length, bool flush)
dan_ackme 17:7268f365676b 234 {
dan_ackme 17:7268f365676b 235 WiconnectResult result = WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 236 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 237
dan_ackme 17:7268f365676b 238 if(txBuffer.size > 0)
dan_ackme 17:7268f365676b 239 {
dan_ackme 17:7268f365676b 240 // NOTE: txBuffer only available in blocking mode (so no need to check if a cmd is executing)
dan_ackme 17:7268f365676b 241
dan_ackme 17:7268f365676b 242 const uint8_t *src = (const uint8_t *)buffer;
dan_ackme 17:7268f365676b 243
dan_ackme 17:7268f365676b 244 while(length > 0)
dan_ackme 17:7268f365676b 245 {
dan_ackme 17:7268f365676b 246 int bytesToWrite = MIN(length, txBuffer.size - txBuffer.bytesPending);
dan_ackme 17:7268f365676b 247 uint8_t *dst = (uint8_t*)&txBuffer.buffer[txBuffer.bytesPending];
dan_ackme 17:7268f365676b 248 memcpy(dst, src, bytesToWrite);
dan_ackme 17:7268f365676b 249 txBuffer.bytesPending += bytesToWrite;
dan_ackme 17:7268f365676b 250 length -= bytesToWrite;
dan_ackme 17:7268f365676b 251 src += bytesToWrite;
dan_ackme 17:7268f365676b 252
dan_ackme 17:7268f365676b 253 if((txBuffer.bytesPending >= txBuffer.size) &&
dan_ackme 17:7268f365676b 254 WICONNECT_FAILED(result, flushTxBuffer()))
dan_ackme 17:7268f365676b 255 {
dan_ackme 17:7268f365676b 256 break;
dan_ackme 17:7268f365676b 257 }
dan_ackme 17:7268f365676b 258 }
dan_ackme 17:7268f365676b 259
dan_ackme 17:7268f365676b 260 if(flush && txBuffer.bytesPending > 0)
dan_ackme 17:7268f365676b 261 {
dan_ackme 17:7268f365676b 262 result = flushTxBuffer();
dan_ackme 17:7268f365676b 263 }
dan_ackme 17:7268f365676b 264 }
dan_ackme 17:7268f365676b 265 else
dan_ackme 17:7268f365676b 266 {
dan_ackme 17:7268f365676b 267 if(WICONNECT_IS_IDLE())
dan_ackme 17:7268f365676b 268 {
dan_ackme 17:7268f365676b 269 txBuffer.ptr = (uint8_t*)buffer;
dan_ackme 17:7268f365676b 270 txBuffer.bytesPending = length;
dan_ackme 17:7268f365676b 271 }
dan_ackme 17:7268f365676b 272
dan_ackme 17:7268f365676b 273 result = flushTxBuffer();
dan_ackme 17:7268f365676b 274 }
dan_ackme 17:7268f365676b 275
dan_ackme 17:7268f365676b 276 return result;
dan_ackme 17:7268f365676b 277 }
dan_ackme 17:7268f365676b 278
dan_ackme 17:7268f365676b 279 /*************************************************************************************************/
dan_ackme 17:7268f365676b 280 WiconnectResult WiconnectSocket::read(void* buffer, uint16_t maxLength, uint16_t *bytesRead)
dan_ackme 17:7268f365676b 281 {
dan_ackme 17:7268f365676b 282 WiconnectResult result;
dan_ackme 17:7268f365676b 283
dan_ackme 17:7268f365676b 284 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 285 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 17:7268f365676b 286
dan_ackme 17:7268f365676b 287 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand((char*)buffer, maxLength, "read %d %d", handle, maxLength)))
dan_ackme 17:7268f365676b 288 {
dan_ackme 17:7268f365676b 289 *bytesRead = wiconnect->getLastCommandResponseLength();
dan_ackme 17:7268f365676b 290 }
dan_ackme 17:7268f365676b 291
dan_ackme 17:7268f365676b 292 CHECK_CLEANUP_COMMAND();
dan_ackme 17:7268f365676b 293
dan_ackme 17:7268f365676b 294 return result;
dan_ackme 17:7268f365676b 295 }
dan_ackme 17:7268f365676b 296
dan_ackme 17:7268f365676b 297 /*************************************************************************************************/
dan_ackme 17:7268f365676b 298 WiconnectResult WiconnectSocket::read(uint8_t **bufferPtr, uint16_t *bytesReadPtr)
dan_ackme 17:7268f365676b 299 {
dan_ackme 17:7268f365676b 300 WiconnectResult result = WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 301
dan_ackme 17:7268f365676b 302 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 303
dan_ackme 17:7268f365676b 304 if(rxBuffer.size == 0)
dan_ackme 17:7268f365676b 305 {
dan_ackme 17:7268f365676b 306 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 307 }
dan_ackme 17:7268f365676b 308 else if(bufferPtr != NULL && bytesReadPtr == NULL)
dan_ackme 17:7268f365676b 309 {
dan_ackme 17:7268f365676b 310 return WICONNECT_BAD_ARG;
dan_ackme 17:7268f365676b 311 }
dan_ackme 17:7268f365676b 312 else if(rxBuffer.bytesPending < rxBuffer.size - 2)
dan_ackme 17:7268f365676b 313 {
dan_ackme 17:7268f365676b 314 const int bytesToRead = rxBuffer.size - rxBuffer.bytesPending - 2;
dan_ackme 17:7268f365676b 315 char* ptr = (char*)&rxBuffer.buffer[rxBuffer.bytesPending];
dan_ackme 17:7268f365676b 316 if(!WICONNECT_FAILED(result, wiconnect->sendCommand(ptr, bytesToRead+2, "read %d %d", handle, bytesToRead)))
dan_ackme 17:7268f365676b 317 {
dan_ackme 17:7268f365676b 318 rxBuffer.bytesPending += wiconnect->getLastCommandResponseLength();
dan_ackme 17:7268f365676b 319 }
dan_ackme 17:7268f365676b 320 }
dan_ackme 17:7268f365676b 321
dan_ackme 17:7268f365676b 322 if(bufferPtr != NULL)
dan_ackme 17:7268f365676b 323 {
dan_ackme 17:7268f365676b 324 *bufferPtr = rxBuffer.buffer;
dan_ackme 17:7268f365676b 325 *bytesReadPtr = rxBuffer.bytesPending;
dan_ackme 17:7268f365676b 326 clearRxBuffer();
dan_ackme 17:7268f365676b 327 }
dan_ackme 17:7268f365676b 328
dan_ackme 17:7268f365676b 329 return result;
dan_ackme 17:7268f365676b 330 }
dan_ackme 17:7268f365676b 331
dan_ackme 17:7268f365676b 332 /*************************************************************************************************/
dan_ackme 17:7268f365676b 333 WiconnectResult WiconnectSocket::getc(uint8_t *c)
dan_ackme 17:7268f365676b 334 {
dan_ackme 17:7268f365676b 335 WiconnectResult result;
dan_ackme 17:7268f365676b 336
dan_ackme 17:7268f365676b 337 if(rxBuffer.size == 0)
dan_ackme 17:7268f365676b 338 {
dan_ackme 17:7268f365676b 339 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 340 }
dan_ackme 17:7268f365676b 341
dan_ackme 17:7268f365676b 342 read_data:
dan_ackme 17:7268f365676b 343 if(rxBuffer.bytesPending == 0 &&
dan_ackme 17:7268f365676b 344 WICONNECT_FAILED(result, read()))
dan_ackme 17:7268f365676b 345 {
dan_ackme 17:7268f365676b 346 return result;
dan_ackme 17:7268f365676b 347 }
dan_ackme 17:7268f365676b 348 else if(rxBuffer.ptr < &rxBuffer.buffer[rxBuffer.bytesPending])
dan_ackme 17:7268f365676b 349 {
dan_ackme 17:7268f365676b 350 *c = *rxBuffer.ptr;
dan_ackme 17:7268f365676b 351 ++rxBuffer.ptr;
dan_ackme 17:7268f365676b 352 return WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 353 }
dan_ackme 17:7268f365676b 354 else
dan_ackme 17:7268f365676b 355 {
dan_ackme 17:7268f365676b 356 clearRxBuffer();
dan_ackme 17:7268f365676b 357 goto read_data;
dan_ackme 17:7268f365676b 358 }
dan_ackme 17:7268f365676b 359 }
dan_ackme 17:7268f365676b 360
dan_ackme 17:7268f365676b 361 /*************************************************************************************************/
dan_ackme 17:7268f365676b 362 WiconnectResult WiconnectSocket::putc(uint8_t c, bool flush)
dan_ackme 17:7268f365676b 363 {
dan_ackme 17:7268f365676b 364 WiconnectResult result = WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 365 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 366
dan_ackme 17:7268f365676b 367 if(txBuffer.size == 0)
dan_ackme 17:7268f365676b 368 {
dan_ackme 17:7268f365676b 369 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 370 }
dan_ackme 17:7268f365676b 371 else if(txBuffer.bytesPending < txBuffer.size)
dan_ackme 17:7268f365676b 372 {
dan_ackme 17:7268f365676b 373 uint8_t *ptr = (uint8_t*)&txBuffer.buffer[txBuffer.bytesPending];
dan_ackme 17:7268f365676b 374 *ptr = c;
dan_ackme 17:7268f365676b 375 ++txBuffer.bytesPending;
dan_ackme 17:7268f365676b 376
dan_ackme 17:7268f365676b 377 if(flush || txBuffer.bytesPending >= txBuffer.size)
dan_ackme 17:7268f365676b 378 {
dan_ackme 17:7268f365676b 379 result = flushTxBuffer();
dan_ackme 17:7268f365676b 380 }
dan_ackme 17:7268f365676b 381 }
dan_ackme 17:7268f365676b 382 else
dan_ackme 17:7268f365676b 383 {
dan_ackme 17:7268f365676b 384 result = WICONNECT_OVERFLOW;
dan_ackme 17:7268f365676b 385 }
dan_ackme 17:7268f365676b 386
dan_ackme 17:7268f365676b 387 return result;
dan_ackme 17:7268f365676b 388 }
dan_ackme 17:7268f365676b 389
dan_ackme 17:7268f365676b 390 /*************************************************************************************************/
dan_ackme 17:7268f365676b 391 WiconnectResult WiconnectSocket::puts(const char *s, bool flush)
dan_ackme 17:7268f365676b 392 {
dan_ackme 17:7268f365676b 393 const int len = strlen(s);
dan_ackme 17:7268f365676b 394 return write(s, len, flush);
dan_ackme 17:7268f365676b 395 }
dan_ackme 17:7268f365676b 396
dan_ackme 17:7268f365676b 397 /*************************************************************************************************/
dan_ackme 17:7268f365676b 398 WiconnectResult WiconnectSocket::printf(const char* format, ...)
dan_ackme 17:7268f365676b 399 {
dan_ackme 17:7268f365676b 400 WiconnectResult result = WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 401
dan_ackme 17:7268f365676b 402 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 403 if(txBuffer.size == 0)
dan_ackme 17:7268f365676b 404 {
dan_ackme 17:7268f365676b 405 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 406 }
dan_ackme 17:7268f365676b 407
dan_ackme 17:7268f365676b 408 const int available = txBuffer.size - txBuffer.bytesPending;
dan_ackme 17:7268f365676b 409 char *ptr = (char*)&txBuffer.buffer[txBuffer.bytesPending];
dan_ackme 17:7268f365676b 410 va_list args;
dan_ackme 17:7268f365676b 411 va_start(args, format);
dan_ackme 17:7268f365676b 412 const int len = vsnprintf(ptr, available, format, args);
dan_ackme 17:7268f365676b 413 if(len > available)
dan_ackme 17:7268f365676b 414 {
dan_ackme 17:7268f365676b 415 return WICONNECT_OVERFLOW;
dan_ackme 17:7268f365676b 416 }
dan_ackme 17:7268f365676b 417 else
dan_ackme 17:7268f365676b 418 {
dan_ackme 17:7268f365676b 419 txBuffer.bytesPending += len;
dan_ackme 17:7268f365676b 420 }
dan_ackme 17:7268f365676b 421
dan_ackme 17:7268f365676b 422 if(txBuffer.bytesPending >= txBuffer.size)
dan_ackme 17:7268f365676b 423 {
dan_ackme 17:7268f365676b 424 result = flushTxBuffer();
dan_ackme 17:7268f365676b 425 }
dan_ackme 17:7268f365676b 426
dan_ackme 17:7268f365676b 427 return result;
dan_ackme 17:7268f365676b 428 }
dan_ackme 17:7268f365676b 429
dan_ackme 17:7268f365676b 430 /*************************************************************************************************/
dan_ackme 17:7268f365676b 431 WiconnectResult WiconnectSocket::flushTxBuffer()
dan_ackme 17:7268f365676b 432 {
dan_ackme 17:7268f365676b 433 WiconnectResult result = WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 434
dan_ackme 17:7268f365676b 435 CHECK_CONNECTED();
dan_ackme 17:7268f365676b 436 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 17:7268f365676b 437
dan_ackme 17:7268f365676b 438 if(txBuffer.bytesPending > 0)
dan_ackme 17:7268f365676b 439 {
dan_ackme 17:7268f365676b 440 result = wiconnect->sendCommand(ReaderFunc(this, &WiconnectSocket::writeDataCallback), NULL, "write %d %d", handle, txBuffer.bytesPending);
dan_ackme 17:7268f365676b 441 }
dan_ackme 17:7268f365676b 442
dan_ackme 17:7268f365676b 443 CHECK_CLEANUP_COMMAND();
dan_ackme 17:7268f365676b 444
dan_ackme 17:7268f365676b 445 if(result != WICONNECT_PROCESSING)
dan_ackme 17:7268f365676b 446 {
dan_ackme 17:7268f365676b 447 txBuffer.ptr = txBuffer.buffer;
dan_ackme 17:7268f365676b 448 txBuffer.bytesPending = 0;
dan_ackme 17:7268f365676b 449 }
dan_ackme 17:7268f365676b 450
dan_ackme 17:7268f365676b 451 return result;
dan_ackme 17:7268f365676b 452 }
dan_ackme 17:7268f365676b 453
dan_ackme 17:7268f365676b 454 /*************************************************************************************************/
dan_ackme 17:7268f365676b 455 void WiconnectSocket::clearRxBuffer()
dan_ackme 17:7268f365676b 456 {
dan_ackme 17:7268f365676b 457 rxBuffer.bytesPending = 0;
dan_ackme 17:7268f365676b 458 rxBuffer.ptr = rxBuffer.buffer;
dan_ackme 17:7268f365676b 459 }
dan_ackme 17:7268f365676b 460
dan_ackme 17:7268f365676b 461 /*************************************************************************************************/
dan_ackme 17:7268f365676b 462 uint8_t* WiconnectSocket::getTxBuffer()
dan_ackme 17:7268f365676b 463 {
dan_ackme 17:7268f365676b 464 return txBuffer.buffer;
dan_ackme 17:7268f365676b 465 }
dan_ackme 17:7268f365676b 466 /*************************************************************************************************/
dan_ackme 17:7268f365676b 467 int WiconnectSocket::getTxBufferSize()
dan_ackme 17:7268f365676b 468 {
dan_ackme 17:7268f365676b 469 return txBuffer.size;
dan_ackme 17:7268f365676b 470 }
dan_ackme 17:7268f365676b 471 /*************************************************************************************************/
dan_ackme 17:7268f365676b 472 int WiconnectSocket::getTxBufferBytesPending()
dan_ackme 17:7268f365676b 473 {
dan_ackme 17:7268f365676b 474 return txBuffer.bytesPending;
dan_ackme 17:7268f365676b 475 }
dan_ackme 17:7268f365676b 476 /*************************************************************************************************/
dan_ackme 17:7268f365676b 477 uint8_t* WiconnectSocket::getRxBuffer()
dan_ackme 17:7268f365676b 478 {
dan_ackme 17:7268f365676b 479 return rxBuffer.buffer;
dan_ackme 17:7268f365676b 480 }
dan_ackme 17:7268f365676b 481 /*************************************************************************************************/
dan_ackme 17:7268f365676b 482 int WiconnectSocket::getRxBufferSize()
dan_ackme 17:7268f365676b 483 {
dan_ackme 17:7268f365676b 484 return rxBuffer.size;
dan_ackme 17:7268f365676b 485 }
dan_ackme 17:7268f365676b 486 /*************************************************************************************************/
dan_ackme 17:7268f365676b 487 int WiconnectSocket::getRxBufferBytesPending()
dan_ackme 17:7268f365676b 488 {
dan_ackme 17:7268f365676b 489 return rxBuffer.bytesPending;
dan_ackme 17:7268f365676b 490 }
dan_ackme 17:7268f365676b 491
dan_ackme 17:7268f365676b 492
dan_ackme 17:7268f365676b 493 /*************************************************************************************************/
dan_ackme 17:7268f365676b 494 WiconnectResult WiconnectSocket::writeDataCallback(void *user, void *data, int maxReadSize, int *bytesRead)
dan_ackme 17:7268f365676b 495 {
dan_ackme 17:7268f365676b 496 if(txBuffer.bytesPending == 0)
dan_ackme 17:7268f365676b 497 {
dan_ackme 17:7268f365676b 498 *bytesRead = EOF;
dan_ackme 17:7268f365676b 499 }
dan_ackme 17:7268f365676b 500 else
dan_ackme 17:7268f365676b 501 {
dan_ackme 17:7268f365676b 502 const int bytesToWrite = MIN(maxReadSize, txBuffer.bytesPending);
dan_ackme 17:7268f365676b 503 memcpy(data, txBuffer.ptr, bytesToWrite);
dan_ackme 17:7268f365676b 504 txBuffer.ptr += bytesToWrite;
dan_ackme 17:7268f365676b 505 txBuffer.bytesPending -= bytesToWrite;
dan_ackme 17:7268f365676b 506 *bytesRead = bytesToWrite;
dan_ackme 17:7268f365676b 507 }
dan_ackme 17:7268f365676b 508
dan_ackme 17:7268f365676b 509 return WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 510 }
dan_ackme 17:7268f365676b 511