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:
24:e27e23297f02
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
dan_ackme 17:7268f365676b 30 #include "Wiconnect.h"
dan_ackme 17:7268f365676b 31 #include "internal/common.h"
dan_ackme 17:7268f365676b 32
dan_ackme 17:7268f365676b 33 #define CHECK_OPENED_FOR_READING() if(!readEnabled) return WICONNECT_NOT_OPENED_FOR_READING
dan_ackme 17:7268f365676b 34
dan_ackme 17:7268f365676b 35
dan_ackme 17:7268f365676b 36
dan_ackme 17:7268f365676b 37
dan_ackme 17:7268f365676b 38 /*************************************************************************************************/
dan_ackme 17:7268f365676b 39 WiconnectFile::WiconnectFile(int rxBufferLen, void *rxBuffer_)
dan_ackme 17:7268f365676b 40 {
dan_ackme 17:7268f365676b 41 wiconnect = Wiconnect::getInstance();
dan_ackme 17:7268f365676b 42
dan_ackme 17:7268f365676b 43 memset(&rxBuffer, 0, sizeof(Buffer));
dan_ackme 17:7268f365676b 44
dan_ackme 17:7268f365676b 45 rxBuffer.size = !wiconnect->nonBlocking ? rxBufferLen : 0;
dan_ackme 17:7268f365676b 46 rxBuffer.buffer = (uint8_t*)rxBuffer_;
dan_ackme 17:7268f365676b 47
dan_ackme 17:7268f365676b 48 if(rxBuffer.size > 0)
dan_ackme 17:7268f365676b 49 {
dan_ackme 17:7268f365676b 50 if(rxBuffer_ == NULL)
dan_ackme 17:7268f365676b 51 {
dan_ackme 17:7268f365676b 52 #ifdef WICONNECT_ENABLE_MALLOC
dan_ackme 17:7268f365676b 53 wiconnect_assert(wiconnect, "File(), malloc not defined", wiconnect->_malloc != NULL);
dan_ackme 17:7268f365676b 54 rxBuffer.buffer = (uint8_t*)wiconnect->_malloc(rxBufferLen);
dan_ackme 17:7268f365676b 55 wiconnect_assert(wiconnect, "File(), failed to malloc buffer", rxBuffer.buffer != NULL);
dan_ackme 17:7268f365676b 56 rxBuffer.allocated = true;
dan_ackme 17:7268f365676b 57 #else
dan_ackme 17:7268f365676b 58 wiconnect_assert(0);
dan_ackme 17:7268f365676b 59 #endif
dan_ackme 17:7268f365676b 60 }
dan_ackme 17:7268f365676b 61 }
dan_ackme 17:7268f365676b 62
dan_ackme 17:7268f365676b 63 previous = next = NULL;
dan_ackme 17:7268f365676b 64 handle = 0xff;
dan_ackme 17:7268f365676b 65 readEnabled = false;
dan_ackme 17:7268f365676b 66 *name = 0;
dan_ackme 17:7268f365676b 67 size = 0;
dan_ackme 17:7268f365676b 68 type = FILE_TYPE_UNKNOWN;
dan_ackme 17:7268f365676b 69 version = 0;
dan_ackme 17:7268f365676b 70 flags = FILE_FLAG_NONE;
dan_ackme 17:7268f365676b 71 }
dan_ackme 17:7268f365676b 72
dan_ackme 17:7268f365676b 73 /*************************************************************************************************/
dan_ackme 17:7268f365676b 74 WiconnectFile::~WiconnectFile()
dan_ackme 17:7268f365676b 75 {
dan_ackme 17:7268f365676b 76 while(close() == WICONNECT_PROCESSING)
dan_ackme 17:7268f365676b 77 {
dan_ackme 17:7268f365676b 78 }
dan_ackme 17:7268f365676b 79
dan_ackme 17:7268f365676b 80 #ifdef WICONNECT_ENABLE_MALLOC
dan_ackme 17:7268f365676b 81 if(rxBuffer.allocated && rxBuffer.size > 0)
dan_ackme 17:7268f365676b 82 {
dan_ackme 17:7268f365676b 83 wiconnect_assert(wiconnect, "~File(), free not defined", wiconnect->_free != NULL);
dan_ackme 17:7268f365676b 84 wiconnect->_free(rxBuffer.buffer);
dan_ackme 17:7268f365676b 85 }
dan_ackme 17:7268f365676b 86 #endif
dan_ackme 17:7268f365676b 87 }
dan_ackme 17:7268f365676b 88
dan_ackme 17:7268f365676b 89 /*************************************************************************************************/
dan_ackme 17:7268f365676b 90 WiconnectResult WiconnectFile::openForRead(uint8_t handle_, const char *filename)
dan_ackme 17:7268f365676b 91 {
dan_ackme 17:7268f365676b 92 handle = handle_;
dan_ackme 17:7268f365676b 93 readEnabled = true;
dan_ackme 17:7268f365676b 94 strcpy(name, filename);
dan_ackme 17:7268f365676b 95
dan_ackme 17:7268f365676b 96 return WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 97 }
dan_ackme 17:7268f365676b 98
dan_ackme 17:7268f365676b 99 /*************************************************************************************************/
dan_ackme 17:7268f365676b 100 WiconnectResult WiconnectFile::initWithListing(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr)
dan_ackme 17:7268f365676b 101 {
dan_ackme 17:7268f365676b 102 uint32_t tmp;
dan_ackme 17:7268f365676b 103
dan_ackme 17:7268f365676b 104 if(!StringUtil::strHexToUint32(&typeStr[2], &tmp))
dan_ackme 17:7268f365676b 105 {
dan_ackme 17:7268f365676b 106 return WICONNECT_RESPONSE_PARSE_ERROR;
dan_ackme 17:7268f365676b 107 }
dan_ackme 17:7268f365676b 108 type = (FileType)tmp;
dan_ackme 17:7268f365676b 109
dan_ackme 17:7268f365676b 110 if(!StringUtil::strHexToUint32(flagsStr, &tmp))
dan_ackme 17:7268f365676b 111 {
dan_ackme 17:7268f365676b 112 return WICONNECT_RESPONSE_PARSE_ERROR;
dan_ackme 17:7268f365676b 113 }
dan_ackme 17:7268f365676b 114 flags = (FileFlags)tmp;
dan_ackme 17:7268f365676b 115
dan_ackme 17:7268f365676b 116 if(!StringUtil::strToUint32(sizeStr, &tmp))
dan_ackme 17:7268f365676b 117 {
dan_ackme 17:7268f365676b 118 return WICONNECT_RESPONSE_PARSE_ERROR;
dan_ackme 17:7268f365676b 119 }
dan_ackme 17:7268f365676b 120 size = (uint32_t)tmp;
dan_ackme 17:7268f365676b 121
dan_ackme 17:7268f365676b 122 if(!FileInterface::fileVersionStrToInt(versionStr, &version))
dan_ackme 17:7268f365676b 123 {
dan_ackme 17:7268f365676b 124 return WICONNECT_RESPONSE_PARSE_ERROR;
dan_ackme 17:7268f365676b 125 }
dan_ackme 17:7268f365676b 126
dan_ackme 17:7268f365676b 127 strcpy(name, nameStr);
dan_ackme 17:7268f365676b 128
dan_ackme 17:7268f365676b 129 return WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 130 }
dan_ackme 17:7268f365676b 131
dan_ackme 17:7268f365676b 132 /*************************************************************************************************/
dan_ackme 17:7268f365676b 133 void* WiconnectFile::operator new(size_t size)
dan_ackme 17:7268f365676b 134 {
dan_ackme 17:7268f365676b 135 Wiconnect *wiconnect = Wiconnect::getInstance();
dan_ackme 17:7268f365676b 136 wiconnect_assert(wiconnect, "File:new, malloc not defined", wiconnect->_malloc != NULL);
dan_ackme 17:7268f365676b 137 return Wiconnect::getInstance()->_malloc(size);
dan_ackme 17:7268f365676b 138 }
dan_ackme 17:7268f365676b 139
dan_ackme 17:7268f365676b 140 /*************************************************************************************************/
dan_ackme 17:7268f365676b 141 void WiconnectFile::operator delete(void* ptr)
dan_ackme 17:7268f365676b 142 {
dan_ackme 17:7268f365676b 143 Wiconnect *wiconnect = Wiconnect::getInstance();
dan_ackme 17:7268f365676b 144 wiconnect_assert(wiconnect, "File:delete, free not defined", wiconnect->_free != NULL);
dan_ackme 17:7268f365676b 145 Wiconnect::getInstance()->_free(ptr);
dan_ackme 17:7268f365676b 146 }
dan_ackme 17:7268f365676b 147
dan_ackme 17:7268f365676b 148
dan_ackme 17:7268f365676b 149 /*************************************************************************************************/
dan_ackme 17:7268f365676b 150 WiconnectResult WiconnectFile::close()
dan_ackme 17:7268f365676b 151 {
dan_ackme 17:7268f365676b 152 WiconnectResult result;
dan_ackme 17:7268f365676b 153 CHECK_OPENED_FOR_READING();
dan_ackme 17:7268f365676b 154 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 17:7268f365676b 155
dan_ackme 17:7268f365676b 156 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("close %d", handle)))
dan_ackme 17:7268f365676b 157 {
dan_ackme 17:7268f365676b 158 readEnabled = false;
dan_ackme 17:7268f365676b 159 }
dan_ackme 17:7268f365676b 160
dan_ackme 17:7268f365676b 161 CHECK_CLEANUP_COMMAND();
dan_ackme 17:7268f365676b 162
dan_ackme 17:7268f365676b 163 return result;
dan_ackme 17:7268f365676b 164 }
dan_ackme 17:7268f365676b 165
dan_ackme 17:7268f365676b 166 /*************************************************************************************************/
dan_ackme 17:7268f365676b 167 const char* WiconnectFile::getName() const
dan_ackme 17:7268f365676b 168 {
dan_ackme 17:7268f365676b 169 return name;
dan_ackme 17:7268f365676b 170 }
dan_ackme 17:7268f365676b 171
dan_ackme 17:7268f365676b 172 /*************************************************************************************************/
dan_ackme 17:7268f365676b 173 uint32_t WiconnectFile::getSize() const
dan_ackme 17:7268f365676b 174 {
dan_ackme 17:7268f365676b 175 return size;
dan_ackme 17:7268f365676b 176 }
dan_ackme 17:7268f365676b 177
dan_ackme 17:7268f365676b 178 /*************************************************************************************************/
dan_ackme 17:7268f365676b 179 FileType WiconnectFile::getType() const
dan_ackme 17:7268f365676b 180 {
dan_ackme 17:7268f365676b 181 return type;
dan_ackme 17:7268f365676b 182 }
dan_ackme 17:7268f365676b 183
dan_ackme 17:7268f365676b 184 /*************************************************************************************************/
dan_ackme 17:7268f365676b 185 FileFlags WiconnectFile::getFlags() const
dan_ackme 17:7268f365676b 186 {
dan_ackme 17:7268f365676b 187 return flags;
dan_ackme 17:7268f365676b 188 }
dan_ackme 17:7268f365676b 189
dan_ackme 17:7268f365676b 190 /*************************************************************************************************/
dan_ackme 17:7268f365676b 191 uint32_t WiconnectFile::getVersion() const
dan_ackme 17:7268f365676b 192 {
dan_ackme 17:7268f365676b 193 return version;
dan_ackme 17:7268f365676b 194 }
dan_ackme 17:7268f365676b 195
dan_ackme 17:7268f365676b 196 /*************************************************************************************************/
dan_ackme 17:7268f365676b 197 const char* WiconnectFile::getVersionStr(char *buffer) const
dan_ackme 17:7268f365676b 198 {
dan_ackme 17:7268f365676b 199 return FileInterface::fileVersionIntToStr(version, true, buffer);
dan_ackme 17:7268f365676b 200 }
dan_ackme 17:7268f365676b 201
dan_ackme 17:7268f365676b 202 /*************************************************************************************************/
dan_ackme 17:7268f365676b 203 const WiconnectFile* WiconnectFile::getNext() const
dan_ackme 17:7268f365676b 204 {
dan_ackme 17:7268f365676b 205 return next;
dan_ackme 17:7268f365676b 206 }
dan_ackme 17:7268f365676b 207
dan_ackme 17:7268f365676b 208 /*************************************************************************************************/
dan_ackme 17:7268f365676b 209 const WiconnectFile* WiconnectFile::getPrevious() const
dan_ackme 17:7268f365676b 210 {
dan_ackme 17:7268f365676b 211 return previous;
dan_ackme 17:7268f365676b 212 }
dan_ackme 17:7268f365676b 213
dan_ackme 17:7268f365676b 214
dan_ackme 17:7268f365676b 215 /*************************************************************************************************/
dan_ackme 17:7268f365676b 216 WiconnectResult WiconnectFile::read(void* buffer, uint16_t maxLength, uint16_t *bytesRead)
dan_ackme 17:7268f365676b 217 {
dan_ackme 17:7268f365676b 218 WiconnectResult result;
dan_ackme 17:7268f365676b 219
dan_ackme 17:7268f365676b 220 CHECK_OPENED_FOR_READING();
dan_ackme 17:7268f365676b 221 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 17:7268f365676b 222
dan_ackme 17:7268f365676b 223 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand((char*)buffer, maxLength, "read %d %d", handle, maxLength)))
dan_ackme 17:7268f365676b 224 {
dan_ackme 17:7268f365676b 225 *bytesRead = wiconnect->getLastCommandResponseLength();
dan_ackme 17:7268f365676b 226 }
dan_ackme 17:7268f365676b 227
dan_ackme 17:7268f365676b 228 CHECK_CLEANUP_COMMAND();
dan_ackme 17:7268f365676b 229
dan_ackme 17:7268f365676b 230 return result;
dan_ackme 17:7268f365676b 231 }
dan_ackme 17:7268f365676b 232
dan_ackme 17:7268f365676b 233 /*************************************************************************************************/
dan_ackme 17:7268f365676b 234 WiconnectResult WiconnectFile::read(uint8_t **bufferPtr, uint16_t *bytesReadPtr)
dan_ackme 17:7268f365676b 235 {
dan_ackme 17:7268f365676b 236 WiconnectResult result = WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 237
dan_ackme 17:7268f365676b 238 CHECK_OPENED_FOR_READING();
dan_ackme 17:7268f365676b 239
dan_ackme 17:7268f365676b 240 if(rxBuffer.size == 0)
dan_ackme 17:7268f365676b 241 {
dan_ackme 17:7268f365676b 242 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 243 }
dan_ackme 17:7268f365676b 244 else if(bufferPtr != NULL && bytesReadPtr == NULL)
dan_ackme 17:7268f365676b 245 {
dan_ackme 17:7268f365676b 246 return WICONNECT_BAD_ARG;
dan_ackme 17:7268f365676b 247 }
dan_ackme 17:7268f365676b 248 else if(rxBuffer.bytesPending < rxBuffer.size - 2)
dan_ackme 17:7268f365676b 249 {
dan_ackme 17:7268f365676b 250 const int bytesToRead = rxBuffer.size - rxBuffer.bytesPending - 2;
dan_ackme 17:7268f365676b 251 char* ptr = (char*)&rxBuffer.buffer[rxBuffer.bytesPending];
dan_ackme 17:7268f365676b 252 if(!WICONNECT_FAILED(result, wiconnect->sendCommand(ptr, bytesToRead+2, "read %d %d", handle, bytesToRead)))
dan_ackme 17:7268f365676b 253 {
dan_ackme 17:7268f365676b 254 rxBuffer.bytesPending += wiconnect->getLastCommandResponseLength();
dan_ackme 17:7268f365676b 255 }
dan_ackme 17:7268f365676b 256 }
dan_ackme 17:7268f365676b 257
dan_ackme 17:7268f365676b 258 if(bufferPtr != NULL)
dan_ackme 17:7268f365676b 259 {
dan_ackme 17:7268f365676b 260 *bufferPtr = rxBuffer.buffer;
dan_ackme 17:7268f365676b 261 *bytesReadPtr = rxBuffer.bytesPending;
dan_ackme 17:7268f365676b 262 clearRxBuffer();
dan_ackme 17:7268f365676b 263 }
dan_ackme 17:7268f365676b 264
dan_ackme 17:7268f365676b 265 return result;
dan_ackme 17:7268f365676b 266 }
dan_ackme 17:7268f365676b 267
dan_ackme 17:7268f365676b 268 /*************************************************************************************************/
dan_ackme 17:7268f365676b 269 WiconnectResult WiconnectFile::getc(uint8_t *c)
dan_ackme 17:7268f365676b 270 {
dan_ackme 17:7268f365676b 271 WiconnectResult result;
dan_ackme 17:7268f365676b 272
dan_ackme 17:7268f365676b 273 if(rxBuffer.size == 0)
dan_ackme 17:7268f365676b 274 {
dan_ackme 17:7268f365676b 275 return WICONNECT_UNSUPPORTED;
dan_ackme 17:7268f365676b 276 }
dan_ackme 17:7268f365676b 277
dan_ackme 17:7268f365676b 278 read_data:
dan_ackme 17:7268f365676b 279 if(rxBuffer.bytesPending == 0 &&
dan_ackme 17:7268f365676b 280 WICONNECT_FAILED(result, read()))
dan_ackme 17:7268f365676b 281 {
dan_ackme 17:7268f365676b 282 return result;
dan_ackme 17:7268f365676b 283 }
dan_ackme 17:7268f365676b 284 else if(rxBuffer.ptr < &rxBuffer.buffer[rxBuffer.bytesPending])
dan_ackme 17:7268f365676b 285 {
dan_ackme 17:7268f365676b 286 *c = *rxBuffer.ptr;
dan_ackme 17:7268f365676b 287 ++rxBuffer.ptr;
dan_ackme 17:7268f365676b 288 return WICONNECT_SUCCESS;
dan_ackme 17:7268f365676b 289 }
dan_ackme 17:7268f365676b 290 else
dan_ackme 17:7268f365676b 291 {
dan_ackme 17:7268f365676b 292 clearRxBuffer();
dan_ackme 17:7268f365676b 293 goto read_data;
dan_ackme 17:7268f365676b 294 }
dan_ackme 17:7268f365676b 295 }
dan_ackme 17:7268f365676b 296
dan_ackme 17:7268f365676b 297 /*************************************************************************************************/
dan_ackme 17:7268f365676b 298 void WiconnectFile::clearRxBuffer()
dan_ackme 17:7268f365676b 299 {
dan_ackme 17:7268f365676b 300 rxBuffer.bytesPending = 0;
dan_ackme 17:7268f365676b 301 rxBuffer.ptr = rxBuffer.buffer;
dan_ackme 17:7268f365676b 302 }