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
WiconnectFile.cpp
00001 /** 00002 * ACKme WiConnect Host Library is licensed under the BSD licence: 00003 * 00004 * Copyright (c)2014 ACKme Networks. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without modification, 00008 * are permitted provided that the following conditions are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright notice, 00011 * this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright notice, 00013 * this list of conditions and the following disclaimer in the documentation 00014 * and/or other materials provided with the distribution. 00015 * 3. The name of the author may not be used to endorse or promote products 00016 * derived from this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED 00019 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00020 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00021 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00022 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00023 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00026 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00027 * OF SUCH DAMAGE. 00028 */ 00029 00030 #include "Wiconnect.h" 00031 #include "internal/common.h" 00032 00033 #define CHECK_OPENED_FOR_READING() if(!readEnabled) return WICONNECT_NOT_OPENED_FOR_READING 00034 00035 00036 00037 00038 /*************************************************************************************************/ 00039 WiconnectFile::WiconnectFile(int rxBufferLen, void *rxBuffer_) 00040 { 00041 wiconnect = Wiconnect::getInstance(); 00042 00043 memset(&rxBuffer, 0, sizeof(Buffer)); 00044 00045 rxBuffer.size = rxBufferLen - 4; 00046 rxBuffer.buffer = (uint8_t*)rxBuffer_; 00047 00048 if(rxBuffer.size > 0) 00049 { 00050 if(rxBuffer_ == NULL) 00051 { 00052 #ifdef WICONNECT_ENABLE_MALLOC 00053 wiconnect_assert(wiconnect, "File(), malloc not defined", wiconnect->_malloc != NULL); 00054 rxBuffer.buffer = (uint8_t*)wiconnect->_malloc(rxBufferLen); 00055 wiconnect_assert(wiconnect, "File(), failed to malloc buffer", rxBuffer.buffer != NULL); 00056 rxBuffer.allocated = true; 00057 #else 00058 wiconnect_assert(wiconnect, "must specify buffer", 0); 00059 #endif 00060 } 00061 rxBuffer.size -= 4; 00062 } 00063 00064 previous = next = NULL; 00065 handle = 0xff; 00066 readEnabled = false; 00067 *name = 0; 00068 size = 0; 00069 type = FILE_TYPE_UNKNOWN; 00070 version = 0; 00071 flags = FILE_FLAG_NONE; 00072 } 00073 00074 /*************************************************************************************************/ 00075 WiconnectFile::~WiconnectFile() 00076 { 00077 while(close() == WICONNECT_PROCESSING) 00078 { 00079 } 00080 00081 #ifdef WICONNECT_ENABLE_MALLOC 00082 if(rxBuffer.allocated && rxBuffer.size > 0) 00083 { 00084 wiconnect_assert(wiconnect, "~File(), free not defined", wiconnect->_free != NULL); 00085 wiconnect->_free(rxBuffer.buffer); 00086 } 00087 #endif 00088 } 00089 00090 /*************************************************************************************************/ 00091 WiconnectResult WiconnectFile::openForRead(uint8_t handle_, const char *filename) 00092 { 00093 handle = handle_; 00094 readEnabled = true; 00095 strcpy(name, filename); 00096 00097 return WICONNECT_SUCCESS; 00098 } 00099 00100 /*************************************************************************************************/ 00101 WiconnectResult WiconnectFile::initWithListing(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr) 00102 { 00103 uint32_t tmp; 00104 00105 if(!StringUtil::strHexToUint32(&typeStr[2], &tmp)) 00106 { 00107 return WICONNECT_RESPONSE_PARSE_ERROR; 00108 } 00109 type = (FileType)tmp; 00110 00111 if(!StringUtil::strHexToUint32(flagsStr, &tmp)) 00112 { 00113 return WICONNECT_RESPONSE_PARSE_ERROR; 00114 } 00115 flags = (FileFlags)tmp; 00116 00117 if(!StringUtil::strToUint32(sizeStr, &tmp)) 00118 { 00119 return WICONNECT_RESPONSE_PARSE_ERROR; 00120 } 00121 size = (uint32_t)tmp; 00122 00123 if(!FileInterface::fileVersionStrToInt(versionStr, &version)) 00124 { 00125 return WICONNECT_RESPONSE_PARSE_ERROR; 00126 } 00127 00128 strcpy(name, nameStr); 00129 00130 return WICONNECT_SUCCESS; 00131 } 00132 00133 #ifdef WICONNECT_ENABLE_MALLOC 00134 /*************************************************************************************************/ 00135 void* WiconnectFile::operator new(size_t size) 00136 { 00137 Wiconnect *wiconnect = Wiconnect::getInstance(); 00138 wiconnect_assert(wiconnect, "File:new, malloc not defined", wiconnect->_malloc != NULL); 00139 return Wiconnect::getInstance()->_malloc(size); 00140 } 00141 00142 /*************************************************************************************************/ 00143 void WiconnectFile::operator delete(void* ptr) 00144 { 00145 Wiconnect *wiconnect = Wiconnect::getInstance(); 00146 wiconnect_assert(wiconnect, "File:delete, free not defined", wiconnect->_free != NULL); 00147 Wiconnect::getInstance()->_free(ptr); 00148 } 00149 #endif 00150 00151 /*************************************************************************************************/ 00152 WiconnectResult WiconnectFile::close() 00153 { 00154 WiconnectResult result; 00155 CHECK_OPENED_FOR_READING(); 00156 CHECK_OTHER_COMMAND_EXECUTING(); 00157 00158 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("close %d", handle))) 00159 { 00160 readEnabled = false; 00161 } 00162 00163 CHECK_CLEANUP_COMMAND(); 00164 00165 return result; 00166 } 00167 00168 /*************************************************************************************************/ 00169 const char* WiconnectFile::getName() const 00170 { 00171 return name; 00172 } 00173 00174 /*************************************************************************************************/ 00175 uint32_t WiconnectFile::getSize() const 00176 { 00177 return size; 00178 } 00179 00180 /*************************************************************************************************/ 00181 FileType WiconnectFile::getType() const 00182 { 00183 return type; 00184 } 00185 00186 /*************************************************************************************************/ 00187 FileFlags WiconnectFile::getFlags() const 00188 { 00189 return flags; 00190 } 00191 00192 /*************************************************************************************************/ 00193 uint32_t WiconnectFile::getVersion() const 00194 { 00195 return version; 00196 } 00197 00198 /*************************************************************************************************/ 00199 const char* WiconnectFile::getVersionStr(char *buffer) const 00200 { 00201 return FileInterface::fileVersionIntToStr(version, true, buffer); 00202 } 00203 00204 /*************************************************************************************************/ 00205 const WiconnectFile* WiconnectFile::getNext() const 00206 { 00207 return next; 00208 } 00209 00210 /*************************************************************************************************/ 00211 const WiconnectFile* WiconnectFile::getPrevious() const 00212 { 00213 return previous; 00214 } 00215 00216 00217 /*************************************************************************************************/ 00218 WiconnectResult WiconnectFile::read(void* buffer, uint16_t maxLength, uint16_t *bytesReadPtr) 00219 { 00220 WiconnectResult result; 00221 00222 CHECK_OPENED_FOR_READING(); 00223 00224 if(rxBuffer.size > 0) 00225 { 00226 uint16_t bytesToRead = 0; 00227 const uint16_t bufferedBytes = (&rxBuffer.buffer[rxBuffer.bytesPending] - rxBuffer.ptr); 00228 if(bufferedBytes > 0) 00229 { 00230 bytesToRead = MIN(bufferedBytes, maxLength); 00231 memcpy(buffer, rxBuffer.ptr, bytesToRead); 00232 rxBuffer.ptr += bytesToRead; 00233 *bytesReadPtr = bytesToRead; 00234 } 00235 if(rxBuffer.ptr >= &rxBuffer.buffer[rxBuffer.bytesPending]) 00236 { 00237 clearRxBuffer(); 00238 } 00239 if(bytesToRead > 0) 00240 { 00241 return WICONNECT_SUCCESS; 00242 } 00243 } 00244 00245 CHECK_OTHER_COMMAND_EXECUTING(); 00246 00247 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand((char*)buffer, maxLength, "read %d %d", handle, maxLength))) 00248 { 00249 *bytesReadPtr = wiconnect->getLastCommandResponseLength(); 00250 } 00251 00252 CHECK_CLEANUP_COMMAND(); 00253 00254 return result; 00255 } 00256 00257 /*************************************************************************************************/ 00258 WiconnectResult WiconnectFile::read(uint8_t **bufferPtr, uint16_t *bytesReadPtr) 00259 { 00260 WiconnectResult result = WICONNECT_SUCCESS; 00261 00262 CHECK_OPENED_FOR_READING(); 00263 00264 if(rxBuffer.size == 0) 00265 { 00266 return WICONNECT_UNSUPPORTED; 00267 } 00268 else if(bufferPtr != NULL && bytesReadPtr == NULL) 00269 { 00270 return WICONNECT_BAD_ARG; 00271 } 00272 00273 if(rxBuffer.ptr >= &rxBuffer.buffer[rxBuffer.bytesPending]) 00274 { 00275 clearRxBuffer(); 00276 } 00277 00278 00279 if(rxBuffer.bytesPending < rxBuffer.size) 00280 { 00281 const int bytesToRead = rxBuffer.size - rxBuffer.bytesPending; 00282 char* ptr = (char*)&rxBuffer.buffer[rxBuffer.bytesPending]; 00283 00284 CHECK_OTHER_COMMAND_EXECUTING(); 00285 00286 loop: 00287 if(bytesToRead > 0 && WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(ptr, bytesToRead, "read %d %d", handle, bytesToRead))) 00288 { 00289 const uint16_t bytesRead = wiconnect->getLastCommandResponseLength(); 00290 rxBuffer.bytesPending += bytesRead; 00291 } 00292 00293 // if still processing and in non-blocking mode, 00294 // then this api call must block until the command completes 00295 if(result == WICONNECT_PROCESSING && wiconnect->nonBlocking) 00296 { 00297 goto loop; 00298 } 00299 00300 CHECK_CLEANUP_COMMAND(); 00301 } 00302 00303 if(bufferPtr != NULL) 00304 { 00305 *bufferPtr = rxBuffer.buffer; 00306 *bytesReadPtr = rxBuffer.bytesPending; 00307 clearRxBuffer(); 00308 } 00309 00310 return result; 00311 } 00312 00313 /*************************************************************************************************/ 00314 WiconnectResult WiconnectFile::getc(uint8_t *c) 00315 { 00316 WiconnectResult result; 00317 00318 if(rxBuffer.size == 0) 00319 { 00320 return WICONNECT_UNSUPPORTED; 00321 } 00322 00323 if(rxBuffer.bytesPending == 0 && 00324 WICONNECT_FAILED(result, read())) 00325 { 00326 return result; 00327 } 00328 else if(rxBuffer.ptr < &rxBuffer.buffer[rxBuffer.bytesPending]) 00329 { 00330 *c = *rxBuffer.ptr; 00331 ++rxBuffer.ptr; 00332 return WICONNECT_SUCCESS; 00333 } 00334 else 00335 { 00336 clearRxBuffer(); 00337 return WICONNECT_ERROR; 00338 } 00339 } 00340 00341 /*************************************************************************************************/ 00342 void WiconnectFile::clearRxBuffer() 00343 { 00344 rxBuffer.bytesPending = 0; 00345 rxBuffer.ptr = rxBuffer.buffer; 00346 }
Generated on Tue Jul 12 2022 17:35:58 by 1.7.2