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:
Mon Aug 11 03:29:30 2014 -0700
Revision:
1:6ec9998427ad
Parent:
0:ea85c4bb5e1f
Child:
6:8a87a59d0d21
fixed compiler warnings

Who changed what in which revision?

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