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

FileInterface.cpp

Committer:
dan_ackme
Date:
2014-10-27
Revision:
29:b6af04b77a56

File content as of revision 29:b6af04b77a56:

/**
 * 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 "Wiconnect.h"
#include "internal/common.h"
#include "api/StringUtil.h"


/*************************************************************************************************/
FileInterface::FileInterface(Wiconnect *wiconnect_)
{
    wiconnect = wiconnect_;
}

/*************************************************************************************************/
WiconnectResult FileInterface::openFile(WiconnectFile &file, const char *name)
{
    WiconnectResult result;

    CHECK_OTHER_COMMAND_EXECUTING();

    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("fop %s", name)))
    {
        int32_t handle;
        if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&handle)))
        {
            file.openForRead(handle, name);
        }
    }

    CHECK_CLEANUP_COMMAND();

    return result;
}

/*************************************************************************************************/
WiconnectResult FileInterface::createFile(const ReaderFunc &reader, void *user, const char *name, uint32_t size, uint32_t version, FileType type, bool isEssential, int32_t checksum)
{
    WiconnectResult result;
    char *cmdBuffer = wiconnect->internalBuffer;

    if(WICONNECT_IS_IDLE())
    {
        char *ptr = cmdBuffer;

        ptr += sprintf(cmdBuffer, "fcr %s%s %u", isEssential ? "-e " : "", name, (unsigned int)size);

        if(version != 0)
        {
            *ptr = ' ';
            ++ptr;
            FileInterface::fileVersionIntToStr(version, true, ptr);
            ptr = ptr + strlen(ptr);
        }
        if(type != FILE_TYPE_ANY)
        {
            ptr += sprintf(ptr, " %X", type);
        }
        if(checksum != -1)
        {
            ptr += sprintf(ptr, " %X", (unsigned int)checksum);
        }
    }

    CHECK_OTHER_COMMAND_EXECUTING();

    result = wiconnect->sendCommand(reader, user, (const char *)cmdBuffer);

    CHECK_CLEANUP_COMMAND();

    return result;
}


/*************************************************************************************************/
WiconnectResult FileInterface::deleteFile(const char *name)
{
    WiconnectResult result;

    CHECK_OTHER_COMMAND_EXECUTING();

    result = wiconnect->sendCommand("fde %s", name);

    CHECK_CLEANUP_COMMAND();

    return result;
}

/*************************************************************************************************/
WiconnectResult FileInterface::deleteFile(const WiconnectFile &file)
{
    return deleteFile(file.getName());
}


/*************************************************************************************************/
const char* FileInterface::fileVersionIntToStr(uint32_t version, bool verbose, char *buffer)
{
    SET_STR_BUFFER(buffer, 32);
    const char *fmt = verbose ? "%u.%u.%u.%u" : "%u.%u.%u";
    sprintf(ptr, fmt, FILE_VERSION_ARGS(version));
    return ptr;
}

/*************************************************************************************************/
bool FileInterface::fileVersionStrToInt(const char *versionStr, uint32_t *versionIntPtr)
{
    const uint8_t offsets[] = {27, 21, 8, 0};
    char buffer[18];
    char *tok, *ptr = buffer;
    uint32_t version = 0;

    strcpy(buffer, versionStr);

    for(int i = 0; i < 4 && (tok = strtok(ptr, ".")) != NULL; ++i)
    {
        char *end;
        const uint32_t value = strtol(tok, &end, 10);
        if(*end != 0)
        {
            return false;
        }
        version |= (value << offsets[i]);
        ptr = NULL;
    }

    *versionIntPtr = version;

    return true;
}

/*************************************************************************************************/
const char* FileInterface::fileTypeToStr(FileType type)
{
    switch(type)
    {
    case FILE_TYPE_UPGRADE_APP:
        return "Upgrade App";
    case FILE_TYPE_WIFI_FW:
        return "Wifi Firmware";
    case FILE_TYPE_REGULAR_APP:
        return "Regular App";
    case FILE_TYPE_TEMPORY:
        return "Temporary";
    case FILE_TYPE_GPIO_CONFIG:
        return "GPIO Default Configuration";
    case FILE_TYPE_COMMAND_HELP:
        return "Command Help";
    case FILE_TYPE_SDC_CAPS:
        return "goHACK.me Capabilities";
    case FILE_TYPE_SETUP_SCRIPT:
        return "Setup Script";
    case FILE_TYPE_MISC_FIX_LEN:
        return "Miscellaneous";
    default:
        if(type >= FILE_TYPE_USER_RANGE_START && type <= FILE_TYPE_USER_RANGE_END)
            return "User";
        else
            return "Unknown";
    }
}

/*************************************************************************************************/
const char* FileInterface::fileFlagsToStr(FileFlags flags, char *buffer)
{
    SET_STR_BUFFER(buffer, 64);
    char *buf = ptr;

    static const char* const flag_strings[] = {
            "Valid",
            "Executable",
            "Encrypted",
            "Internal",
            "Bootable",
            "User",
            "Essential",
    };

    int i = 0;
    *ptr = 0;

    for(uint16_t f = flags; f != 0 && i < 7; f >>= 1, ++i)
    {
        if(f & 0x0001)
        {
            ptr += sprintf(ptr, "%s,", flag_strings[i]);
        }
    }

    if(ptr == buffer)
    {
        strcpy(buffer, "None");
    }
    else
    {
        *(ptr-1) = 0;
    }

    return buf;
}