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

Revision:
29:b6af04b77a56
Child:
33:9b690d76eedf
Child:
35:15725177aa60
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Wiconnect.cpp	Mon Oct 27 13:42:26 2014 -0700
@@ -0,0 +1,398 @@
+/**
+ * ACKme WiConnect Host Library is licensed under the BSD licence: 
+ * 
+ * Copyright (c)2014 ACKme Networks.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, 
+ * are permitted provided that the following conditions are met: 
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice, 
+ * this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ * this list of conditions and the following disclaimer in the documentation 
+ * and/or other materials provided with the distribution. 
+ * 3. The name of the author may not be used to endorse or promote products 
+ * derived from this software without specific prior written permission. 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "api/WiconnectInterface.h"
+#include "internal/common.h"
+#include "internal/CommandCommon.h"
+
+
+
+
+using namespace wiconnect;
+
+
+
+
+
+#ifdef WICONNECT_ENABLE_MALLOC
+#define MALLOC_ARGS , void* (*mallocPtr)(size_t), void (*freePtr)(void*)
+#define MALLOC_CONSTRUCTORS   _malloc(mallocPtr), _free(freePtr),
+#else
+#define MALLOC_ARGS
+#define MALLOC_CONSTRUCTORS
+#endif
+
+
+static Wiconnect* instance = NULL;
+
+
+
+
+/*************************************************************************************************/
+void Wiconnect::prepare(void *internalBuffer_, int internalBufferSize_, bool nonBlocking_)
+{
+    instance = this;
+    internalBufferAlloc = false;
+#ifdef WICONNECT_ENABLE_MALLOC
+    if(internalBufferSize_ > 0 && internalBuffer_ == NULL)
+    {
+        wiconnect_assert(this, "Wiconnect(), malloc not defined", _malloc != NULL);
+        internalBuffer = (char*)_malloc(internalBufferSize_);
+        internalBufferAlloc = true;
+    }
+    else
+#endif
+    {
+        internalBuffer = (char*)internalBuffer_;
+    }
+
+    internalProcessingState = 0;
+    currentCommandId = NULL;
+    internalBufferSize = internalBufferSize_;;
+    nonBlocking = nonBlocking_;
+    commandExecuting = false;
+    initialized = false;
+    pinToGpioMapper = NULL;
+    defaultTimeoutMs = WICONNECT_DEFAULT_TIMEOUT;
+
+    memset(commandContext, 0, sizeof(commandContext));
+
+#ifdef WICONNECT_ASYNC_TIMER_ENABLED
+    commandProcessingPeriod = WICONNECT_DEFAULT_COMMAND_PROCESSING_PERIOD;
+    currentQueuedCommand = NULL;
+#endif
+}
+
+
+/*************************************************************************************************/
+Wiconnect::Wiconnect(const SerialConfig &serialConfig, int internalBufferSize, void *internalBuffer, Pin reset, Pin wake, bool nonBlocking MALLOC_ARGS) :
+        NetworkInterface(this), SocketInterface(this), FileInterface(this), GhmInterface(this),
+        MALLOC_CONSTRUCTORS serial(serialConfig, this), resetGpio(reset), wakeGpio(wake)
+{
+#ifdef WICONNECT_ENABLE_MALLOC
+    wiconnect_assert(this, "Wiconnect(), bad malloc/free", (mallocPtr == NULL && freePtr == NULL) || (mallocPtr != NULL && freePtr != NULL));
+#endif
+    prepare(internalBuffer, internalBufferSize, nonBlocking);
+}
+
+/*************************************************************************************************/
+Wiconnect::Wiconnect(const SerialConfig &serialConfig, Pin reset, Pin wake, bool nonBlocking MALLOC_ARGS) :
+    NetworkInterface(this), SocketInterface(this), FileInterface(this), GhmInterface(this),
+    MALLOC_CONSTRUCTORS serial(serialConfig, this), resetGpio(reset), wakeGpio(wake)
+{
+#ifdef WICONNECT_ENABLE_MALLOC
+    wiconnect_assert(this, "Wiconnect(), bad malloc/free", (mallocPtr == NULL && freePtr == NULL) || (mallocPtr != NULL && freePtr != NULL));
+#endif
+    prepare(NULL, 0, nonBlocking);
+}
+
+/*************************************************************************************************/
+Wiconnect::~Wiconnect()
+{
+#ifdef WICONNECT_ENABLE_MALLOC
+    if(internalBufferAlloc)
+    {
+        _free(internalBuffer);
+    }
+#endif
+}
+
+/*************************************************************************************************/
+WiconnectResult Wiconnect::init(bool bringNetworkUp)
+{
+    WiconnectResult result;
+    int retries;
+    bool configuredBus = false;
+    bool savedNonBlocking = nonBlocking;
+
+    DEBUG_INFO("Initializing wiconnect");
+
+    serial.initialize();
+
+    if(WICONNECT_FAILED(result, reset()))
+    {
+        return result;
+    }
+
+    delayMs(1000);
+
+    initialized = true;
+    nonBlocking = false;
+
+
+    loop:
+    for(retries = 3; retries > 0; --retries)
+    {
+        result = sendCommand(1000, CMD_SET_SYSTEM_COMMAND_MODE, "machine");
+        if(result != WICONNECT_SUCCESS)
+        {
+            delayMs(100);
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    if(result != WICONNECT_SUCCESS && !configuredBus)
+    {
+        configuredBus = true;
+        if(configureModuleDataBus())
+        {
+            goto loop;
+        }
+    }
+
+    if(result == WICONNECT_SUCCESS)
+    {
+        sendCommand("set stream.auto_close 0");
+    }
+    if(result == WICONNECT_SUCCESS && bringNetworkUp)
+    {
+        sendCommand(15000, "ping -g");
+    }
+
+    nonBlocking = savedNonBlocking;
+    if(result != WICONNECT_SUCCESS)
+    {
+        initialized = false;
+    }
+
+
+    return result;
+}
+
+/*************************************************************************************************/
+void Wiconnect::deinit(void)
+{
+    initialized = false;
+}
+
+/*************************************************************************************************/
+Wiconnect* Wiconnect::getInstance()
+{
+    return instance;
+}
+
+/*************************************************************************************************/
+bool Wiconnect::isInitialized()
+{
+    return initialized;
+}
+
+/*************************************************************************************************/
+WiconnectResult Wiconnect::reset()
+{
+    resetGpio = 0;
+    delayMs(10);
+    resetGpio = 1;
+    delayMs(1000);
+    return WICONNECT_SUCCESS;
+}
+
+/*************************************************************************************************/
+WiconnectResult Wiconnect::wakeup()
+{
+    wakeGpio = 1;
+    delayMs(1);
+    wakeGpio = 0;
+    return WICONNECT_SUCCESS;
+}
+
+/*************************************************************************************************/
+void Wiconnect::flush(int delayMs)
+{
+//    if(delayMs != 0)
+//    {
+//        serial.write("\r\n\r\n", 4, 0);
+//    }
+//    delayMs(delayMs);
+//    serial.flush();
+}
+
+/*************************************************************************************************/
+void Wiconnect::setPinToGpioMapper(PinToGpioMapper mapper)
+{
+    pinToGpioMapper = mapper;
+}
+
+/*************************************************************************************************/
+WiconnectResult Wiconnect::getVersion(char *versionBuffer, int versionBufferSize, const Callback &completeCallback)
+{
+    WiconnectResult result;
+
+    if(versionBuffer != NULL && versionBufferSize == 0)
+    {
+        return WICONNECT_BAD_ARG;
+    }
+
+    _CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(versionBuffer == NULL)
+    {
+        result = sendCommand(completeCallback, CMD_GET_VERSION);
+    }
+    else
+    {
+        result = sendCommand(completeCallback, versionBuffer, versionBufferSize, CMD_GET_VERSION);
+    }
+
+    _CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+WiconnectResult Wiconnect::updateFirmware(bool forced, const char *versionStr, const Callback &completeCallback)
+{
+    WiconnectResult result;
+    char *cmdBuffer = internalBuffer;
+
+    if(_WICONNECT_IS_IDLE())
+    {
+        strcpy(cmdBuffer, "ota ");
+        if(versionStr != NULL)
+        {
+            strcat(cmdBuffer, "-b wiconnect-");
+            strcat(cmdBuffer, versionStr);
+        }
+        else if(forced)
+        {
+            strcat(cmdBuffer, "-f");
+        }
+    }
+
+    _CHECK_OTHER_COMMAND_EXECUTING();
+
+    result = sendCommand(completeCallback, WICONNECT_FIRMWARE_UPDATE_TIMEOUT, cmdBuffer);
+
+    _CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+const char* Wiconnect::getWiconnectResultStr(WiconnectResult wiconnectResult)
+{
+    static const char* const wiconnectSuccessStrTable[] = {
+            "Success",                              // WICONNECT_SUCCESS
+            "Processing command",                   // WICONNECT_PROCESSING
+            "Idle",                                 // WICONNECT_IDLE
+            "Aborted",                              // WICONNECT_ABORTED
+    };
+    static const char* const wiconnectErrorStrTable[] = {
+            "",
+            "General error",                        // WICONNECT_ERROR
+            "WiConnect command code error",         // WICONNECT_CMD_RESPONSE_ERROR
+            "Null buffer",                          // WICONNECT_NULL_BUFFER
+            "Not initialized",                      // WICONNECT_NOT_INITIALIZED
+            "Overflow",                             // WICONNECT_OVERFLOW
+            "Timeout",                              // WICONNECT_TIMEOUT
+            "Response handler null",                // WICONNECT_RESPONSE_HANDLER_NULL
+            "Response parse error",                 // WICONNECT_RESPONSE_PARSE_ERROR
+            "Another command is executing",         // WICONNECT_ANOTHER_CMD_EXECUTING
+            "Bad argument(s)",                      // WICONNECT_BAD_ARG
+            "Unsupported",                          // WICONNECT_UNSUPPORTED
+            "Pin name to GPIO mapper null",         // WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL
+            "Duplicate",                            // WICONNECT_DUPLICATE
+            "Not found",                            // WICONNECT_NOT_FOUND
+            "No mapping for pinname to GPIO",       // WICONNECT_PINNAME_TO_GPIO_NO_MAPPING
+            "Not connected",                        // WICONNECT_NOT_CONNECTED
+            "Underflow",                            // WICONNECT_UNDERFLOW
+            "A monitor is not available",           // WICONNECT_MONITOR_NOT_AVAILABLE
+            "Not opened for reading",               // WICONNECT_NOT_OPENED_FOR_READING
+    };
+
+    if((int)wiconnectResult >= (int)WICONNECT_SUCCESS)
+    {
+        return wiconnectSuccessStrTable[wiconnectResult];
+    }
+    else
+    {
+        wiconnectResult = (WiconnectResult)(-((int)wiconnectResult));
+        return wiconnectErrorStrTable[wiconnectResult];
+    }
+}
+
+
+/*************************************************************************************************/
+void Wiconnect::setDebugLogger(LogFunc logFunc)
+{
+#ifdef WICONNECT_ENABLE_DEBUGGING
+    debugLogger = logFunc;
+#endif
+}
+
+/*************************************************************************************************/
+void Wiconnect::setAssertLogger(LogFunc assertLogFunc)
+{
+    assertLogger = assertLogFunc;
+}
+
+#ifdef WICONNECT_ENABLE_DEBUGGING
+/*************************************************************************************************/
+void Wiconnect::debugLog(const char *msg, ...)
+{
+    if(!debugLogger.isValid())
+    {
+        return;
+    }
+
+    static char buffer[96];
+    va_list args;
+    va_start(args, msg);
+    int len = vsnprintf(buffer, sizeof(buffer)-1, msg, args);
+    va_end(args);
+
+    if(len > (int)(sizeof(buffer)-6))
+    {
+        char *p = &buffer[sizeof(buffer)-6];
+        *p++ = '.';
+        *p++ = '.';
+        *p++ = '.';
+        *p++ = '\r';
+        *p++ = '\n';
+        *p = 0;
+    }
+    else
+    {
+        if(buffer[len-2] != '\r')
+        {
+            char *p = &buffer[len];
+            *p++ = '\r';
+            *p++ = '\n';
+            *p = 0;
+        }
+    }
+    debugLogger.call(buffer);
+}
+#endif