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 0:ea85c4bb5e1f, committed 2014-08-11
- Comitter:
- dan_ackme
- Date:
- Mon Aug 11 09:58:24 2014 +0000
- Child:
- 1:6ec9998427ad
- Commit message:
- initial check-in
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FileInterface.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "mbed.h" + +#include "WiconnectTypes.h" +#include "types/FileList.h" + + +#define FILE_NAME_MAX_SIZE 96 +#define FILE_MAKE_VERSION(major, minor, patch, rc) ((unsigned int)((major) << 27)|(unsigned int)((minor) << 21)|(unsigned int)((patch) << 8)|(unsigned int)((rc) << 0)) +#define FILE_VERSION_ARGS(version) (unsigned int)((version >> 27) & 0x1F),(unsigned int)((version >> 21) & 0x3F),(unsigned int)((version >> 8) & 0x1FFF),(unsigned int)(version & 0xFF) + + +namespace wiconnect { + + +class FileInterface +{ +public: + FileInterface(Wiconnect *wiconnect); + + WiconnectResult createFile(const ReaderFunc &reader, void *user, const char *name, uint32_t size, uint32_t version = 0, FileType type = FILE_TYPE_ANY, bool isEssential = false, int32_t checksum = -1); + WiconnectResult openFile(File &file, const char *name); + WiconnectResult deleteFile(const char *name); + WiconnectResult deleteFile(const File &file); + WiconnectResult listFiles(FileList &list, const char *name = NULL, FileType type = FILE_TYPE_ANY, uint32_t version = 0); + + static const char* fileVersionIntToStr(uint32_t version, bool verbose = true, char *buffer = NULL); + static bool fileVersionStrToInt(const char *versionStr, uint32_t *versionIntPtr); + static const char* fileTypeToStr(FileType type); + static const char* fileFlagsToStr(FileFlags flags, char *buffer = NULL); + +protected: + WiconnectResult processFileList(char *responseStr, FileList &list, const char *name, FileType type, uint32_t version); +private: + Wiconnect *wiconnect; +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NetworkInterface.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "WiconnectTypes.h" +#include "types/ScanResultList.h" + + +namespace wiconnect { + + +class NetworkInterface +{ +public: + WiconnectResult startWebSetup(const char *ssid = NULL, const char *password = NULL, const Callback &completeHandler = Callback()); + WiconnectResult stopWebSetup(); + WiconnectResult isWebSetupRunning(bool *isRunningPtr); + + WiconnectResult join(const char* ssid = NULL, const char *password = NULL, const Callback &completeHandler = Callback()); + WiconnectResult leave(); + WiconnectResult getNetworkStatus(NetworkStatus *statusPtr); + +// WiconnectResult startSoftAp(const char* ssid = NULL, const char *password = NULL, const Callback &clientConnectedCallback = Callback()); +// WiconnectResult stopSoftAp(); +// WiconnectResult getSoftApClientList(); + + WiconnectResult scan(ScanResultList &resultList, const uint8_t *channelList = NULL, const char* ssid = NULL); + WiconnectResult ping(const char *domain = NULL, uint32_t *timeMsPtr = NULL); + WiconnectResult lookup(const char *domain, uint32_t *ipAddressPtr); + + WiconnectResult setDhcpEnabled(bool enabled); + WiconnectResult getDhcpEnabled(bool *enabledPtr); + WiconnectResult setIpSettings(uint32_t ip, uint32_t netmask, uint32_t gateway); + WiconnectResult setIpSettings(const char* ip, const char* netmask, const char* gateway); + WiconnectResult getIpSettings(uint32_t *ip, uint32_t *netmask, uint32_t *gateway); + WiconnectResult getSignalStrength(NetworkSignalStrength *signalStrengthPtr); + + static bool strToIp(const char *str, uint32_t *intPtr); + static const char* ipToStr(uint32_t ip, char *ipStrBuffer = NULL); + static const char* networkStatusToStr(NetworkStatus status); + static const char* signalStrengthToStr(NetworkSignalStrength signalStrenth); + static NetworkSignalStrength rssiToSignalStrength(int rssi); + static NetworkSecurity strToNetworkSecurity(const char *str); + static const char* networkSecurityToStr(NetworkSecurity security); + static bool strToSsid(const char *str, Ssid *ssid); + static const char* ssidToStr(const Ssid *ssid, char *ssidStrBuffer = NULL); + static bool strToMacAddress(const char *str, MacAddress *macAddress); + static const char* macAddressToStr(const MacAddress *macAddress, char *macStrBuffer = NULL); + +protected: + NetworkInterface(Wiconnect *wiconnect); + + WiconnectResult processScanResults(char *resultStr, ScanResultList &resultList); + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + Callback completeHandler; + PeriodicTimer monitorTimer; + + void webSetupStatusMonitor(); + void webSetupStatusCheckCallback(WiconnectResult result, void *arg1, void *arg2); + + void joinStatusMonitor(); + void joinStatusCheckCallback(WiconnectResult result, void *arg1, void *arg2); + + //void scanCompleteCallback(WiconnectResult result, void *arg1, void *arg2); +#endif + +private: + Wiconnect *wiconnect; +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SocketInterface.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,54 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "Wiconnect.h" +#include "types/Socket.h" +#include "types/SocketIrqHandlerMap.h" + + +namespace wiconnect { + + +#define SOCKET_ANY_PORT (uint16_t)0 + + + +class SocketInterface +{ +public: + SocketInterface(Wiconnect *wiconnect); + ~SocketInterface(); + + WiconnectResult closeAllSockets(); + WiconnectResult registerSocketIrqHandler(Pin irqPin, const Callback &handler); + WiconnectResult unregisterSocketIrqHandler(Pin irqPin); + + WiconnectResult connect(Socket &socket, SocketType type, const char *host, uint16_t remortPort, uint16_t localPort, const void *args, Pin irqPin); + WiconnectResult tcpConnect(Socket &socket, const char *host, uint16_t remortPort, Pin irqPin = NC); + WiconnectResult tlsConnect(Socket &socket, const char *host, uint16_t remortPort, const char *certFilename = NULL, Pin irqPin = NC); + WiconnectResult udpConnect(Socket &socket, const char *host, uint16_t remortPort, uint16_t localPort = SOCKET_ANY_PORT, Pin irqPin = NC); + WiconnectResult httpConnect(Socket &socket, const char *url, const HttpSocketArgs *args); + WiconnectResult httpGet(Socket &socket, const char *url, bool openOnly = false, const char *certFilename = NULL); + WiconnectResult httpPost(Socket &socket, const char *url, const char *contextType, bool openOnly = true, const char *certFilename = NULL); + WiconnectResult httpHead(Socket &socket, const char *url, const char *certFilename = NULL); + WiconnectResult httpAddHeader(Socket &socket, const char *key, const char *value); + WiconnectResult httpGetStatus(Socket &socket, uint32_t *statusCodePtr); + +protected: + SocketIrqHandlerMap irqHandlers; + +private: + Wiconnect *wiconnect; +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/StringUtil.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,387 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include <string.h> +#include <ctype.h> +#include <stdint.h> +#include <limits.h> + + +#ifdef WICONNECT_USE_STRTOLL +// Necessary to get strtoll in C99 mode. +// http://sourceware.org/ml/newlib/2012/msg00425.html +extern long long strtoll(const char *__n, char **__end_PTR, int __base); +#endif + + +class StringUtil +{ + +public: + /*************************************************************************************************/ + // Helper to find an occurrence of a delimiter string, + // insert '\0' in its place and return string after + // the delimiter e.g. + // if char s[] = "foo://bar"; + // - strchop(s, "://") returns "bar" + // - s becomes "foo" + static char *chop(char *haystack, const char *needle) + { + if (!haystack) + { + return NULL; + } + char *end = strstr(haystack, needle); + if (end) + { + *end = '\0'; + return end + strlen(needle); + } + return NULL; + } + + /*************************************************************************************************/ + // Check if string is non-null and non-empty. + static bool empty(const char *s) + { + return !(s && *s); + } + + /*************************************************************************************************/ + static bool isSpace(const char *s) + { + while(*s != 0) + { + if(!isspace((uint8_t)*s++)) + return false; + } + return true; + } + + /*************************************************************************************************/ + // Convert null-terminated string to lower case. + // ASCII charset only. + static void toLower(char *s) + { + for (; *s; ++s) + { + *s = tolower((int) * s); + } + } + + /*************************************************************************************************/ + // Combination of strip left + right. + static char *strip(char *s, const char *chars) + { + return rightStrip(leftStrip(s, chars), chars); + } + + /*************************************************************************************************/ + // Strip string from the left. + // Returns pointer into the input string. + static char *leftStrip(char *s, const char *chars) + { + return s + strspn(s, chars); + } + + /*************************************************************************************************/ + // Strip string from the right. + // Modified in place. + static char *rightStrip(char *s, const char *chars) + { + char *end = s + strlen(s) - 1; + while (end > s && strstr(chars, end)) + { + *end-- = '\0'; + } + return s; + } + + /*************************************************************************************************/ + // Parse decimal integer and check if it's in bounds [min, max]. + static bool parseInt(const char *s, intmax_t *result, intmax_t min, intmax_t max) + { + return parseBase(s, result, min, max, 10); + } + + // Parse hexadecimal integer and check if it's in bounds [min, max]. + static bool parseHex(const char *s, intmax_t *result, intmax_t min, intmax_t max) + { + return parseBase(s, result, min, max, 16); + } + + /*************************************************************************************************/ + static bool parseBase(const char *s, intmax_t *result, intmax_t min, intmax_t max, int base) + { + if (!s) + { + return false; + } + char *end; +#ifdef WICONNECT_USE_STRTOLL + intmax_t value = strtoll(s, &end, base); +#else + intmax_t value = strtol(s, &end, base); +#endif + if (*end || value < min || value > max) + { + return false; + } + *result = value; + return true; + } + + /*************************************************************************************************/ + // Parse an long long integer. + static bool parseBool(const char *onoff, bool *var) + { + const char* const on_vals[] = + { + "1", + "on", + "true", + "yes", + }; + + for(uint8_t i = 0; i < ARRAY_COUNT(on_vals); ++i) + { + if(strcasecmp(on_vals[i], onoff) == 0) + { + *var = true; + return true; + } + } + + const char* const off_vals[] = + { + "0", + "false", + "no", + "off", + NULL + }; + for(uint8_t i = 0; i < ARRAY_COUNT(off_vals); ++i) + { + if(strcasecmp(off_vals[i], onoff) == 0) + { + *var = false; + return true; + } + } + + return false; + } + + /*************************************************************************************************/ + // convert binary data to hex string + static void binToHex(char *dst, int max_dst, const void *data, int data_len) + { + char *end = dst + max_dst - 1; + for (int i = 0; i < data_len; ++i) + { + if (dst < end) + { + dst += sprintf(dst, "%2.2x", ((uint8_t *)data)[i]); + } + } + } + + + /*************************************************************************************************/ + // Parse binary data into hex string + // the input buffer MUST be len*2 long + // as the parsing is destructive and done in-place + static void binToHex(void *h, int len) + { + char *dst = (char*)h; + char *src= (char*)h+len; + + memmove(src, dst, len); + + while(len--) + { + sprintf(dst, "%2.2X", (unsigned int)(*src & 0xff)); + dst += 2; + ++src; + } + } + + + /*************************************************************************************************/ + // Parses hex representation of binary data destructively. + // Returns number of bytes parsed or -1 on error. + static int hexToBin(char *s) + { + int len, i, j; + len = strlen(s); + if (len % 2) + { + return -1; + } + for (i = j = 0; i < len; i += 2, j++) + { + const int num = hexToInt(&s[i]); + if(num == -1) + return -1; + s[j] = (char)num; + } + return j; + } + + /*************************************************************************************************/ + // hex string to integer, returns -1 on error + static int hexToInt(const char *hex_str) + { + int hi = hexToNibble(*hex_str); + int lo = hexToNibble(*(hex_str+1)); + if (hi == -1 || lo == -1) + { + return -1; + } + return (hi << 4) | lo; + } + + /*************************************************************************************************/ + static int hexToNibble(char c) + { + if (c >= '0' && c <= '9') + { + return c - '0'; + } + if (c >= 'a' && c <= 'f') + { + return 10 + (c - 'a'); + } + if (c >= 'A' && c <= 'F') + { + return 10 + (c - 'A'); + } + return -1; + } + + /*************************************************************************************************/ + static const char* uint32ToStr(char* intStrBuffer, int integer) + { + sprintf(intStrBuffer, "%u", integer); + return intStrBuffer; + } + + /*************************************************************************************************/ + static bool strToUint32(const char *str, uint32_t *uint32Ptr) + { + intmax_t r; + bool result = StringUtil::parseInt(str, &r, 0, UINT_MAX); + *uint32Ptr = (uint32_t)r; + return result; + } + + /*************************************************************************************************/ + static bool strToInt32(const char *str, int32_t *int32Ptr) + { + intmax_t r; + bool result = StringUtil::parseInt(str, &r, INT_MIN, INT_MAX); + *int32Ptr = (int32_t)r; + return result; + } + + /*************************************************************************************************/ + // uint32 hex string to uint32 + static bool strHexToUint32(const char *strHex, uint32_t *uint32Ptr) + { + intmax_t r; + bool result = StringUtil::parseHex(strHex, &r, 0, UINT_MAX); + *uint32Ptr = (uint32_t)r; + return result; + } + + /*************************************************************************************************/ + static char *strtok_r(char *str, const char *delim, char **nextp) + { + char *ret; + + if (str == NULL) + { + str = *nextp; + } + + str += strspn(str, delim); + + if (*str == '\0') + { + return NULL; + } + + ret = str; + + str += strcspn(str, delim); + + if (*str) + { + *str++ = '\0'; + } + + *nextp = str; + + return ret; + } + + /*************************************************************************************************/ + static int strncasecmp(const char *s1, const char *s2, int n) + { + if (n == 0) + return 0; + + while (n-- != 0 && tolower(*s1) == tolower(*s2)) + { + if (n == 0 || *s1 == '\0' || *s2 == '\0') + break; + s1++; + s2++; + } + + return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); + } + + /*************************************************************************************************/ + static int strcasecmp(const char *s1, const char *s2) + { + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + c1 = tolower (*p1); + c2 = tolower (*p2); + + if (c1 == '\0') + break; + + ++p1; + ++p2; + } + while (c1 == c2); + + if (UCHAR_MAX <= INT_MAX) + return c1 - c2; + else + /* On machines where 'char' and 'int' are types of the same size, the + difference of two 'unsigned char' values - including the sign bit - + doesn't fit in an 'int'. */ + return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0); + } +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wiconnect.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,19 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + + +#include "WiconnectInterface.h" + + +using namespace wiconnect; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WiconnectInterface.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,159 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "WiconnectTypes.h" + + +#include "types/LogFunc.h" +#include "types/ReaderFunc.h" +#include "types/Callback.h" +#include "types/QueuedCommand.h" +#include "types/CommandQueue.h" +#include "types/TimeoutTimer.h" +#include "types/PeriodicTimer.h" +#include "types/Gpio.h" +#include "types/WiconnectSerial.h" + +#include "NetworkInterface.h" +#include "SocketInterface.h" +#include "FileInterface.h" + + +#ifdef WICONNECT_ENABLE_MALLOC +#define WICONNECT_MALLOC_ARGS , void* (*malloc_)(size_t) = WICONNECT_DEFAULT_MALLOC, void (*free_)(void*) = WICONNECT_DEFAULT_FREE +#else +#define WICONNECT_MALLOC_ARGS +#endif + + +namespace wiconnect { + + +class Wiconnect : public NetworkInterface, + public SocketInterface, + public FileInterface +{ +public: + Wiconnect(const SerialConfig &serialConfig, Pin reset = PIN_NC, Pin wake = PIN_NC, bool nonBlocking = WICONNECT_DEFAULT_NONBLOCKING WICONNECT_MALLOC_ARGS); + Wiconnect(const SerialConfig &serialConfig, void *internalBuffer, int internalBufferSize, Pin reset = PIN_NC, Pin wake = PIN_NC, bool nonBlocking = WICONNECT_DEFAULT_NONBLOCKING WICONNECT_MALLOC_ARGS); + ~Wiconnect(); + + static Wiconnect* getInstance(); + + WiconnectResult init(bool bringNetworkUp); + void deinit(); + bool isInitialized(); + WiconnectResult reset(); + WiconnectResult wakeup(); + void flush(int delayMs = 500); + + WiconnectResult getVersion(char *versionBuffer = NULL, int versionBufferSize = 0, const Callback &completeCallback = Callback()); + + WiconnectResult sendCommand(const Callback &completeCallback, char *responseBuffer, int responseBufferLen, + int timeoutMs, const ReaderFunc &reader, void *user, const char *cmd, va_list vaList); + WiconnectResult sendCommand(char *responseBuffer, int responseBufferLen, int timeoutMs, const ReaderFunc &reader, + void *user, const char *cmd, va_list vaList); + WiconnectResult sendCommand(char *responseBuffer, int responseBufferLen, int timeoutMs, const ReaderFunc &reader, + void *user, const char *cmd, ...); + WiconnectResult sendCommand( int timeoutMs, const ReaderFunc &reader, void *user, const char *cmd, ...); + WiconnectResult sendCommand(const ReaderFunc &reader, void *user, const char *cmd, ...); + WiconnectResult sendCommand(char *responseBuffer, int responseBufferLen, int timeoutMs, const char *cmd, ...); + WiconnectResult sendCommand(const Callback &completeCallback, char *responseBuffer, int responseBufferLen, const char *cmd, ...); + WiconnectResult sendCommand(char *responseBuffer, int responseBufferLen, const char *cmd, ...); + WiconnectResult sendCommand(const Callback &completeCallback, const char *cmd, ...); + WiconnectResult sendCommand(const char *cmd, ...); + WiconnectResult sendCommand(const Callback &completeCallback, int timeoutMs, const char *cmd, ...); + WiconnectResult sendCommand(int timeoutMs, const char *cmd, ...); + WiconnectResult sendCommand(const char *cmd, va_list vaList); + + const char* getLastCommandResponseCodeStr(); + uint16_t getLastCommandResponseLength(); + char* getResponseBuffer(); + WiconnectResult responseToUint32(uint32_t *uint32Ptr); + WiconnectResult responseToInt32(int32_t *int32Ptr); + + WiconnectResult checkCurrentCommand(); + void stopCurrentCommand(); + void setCommandDefaultTimeout(int timeoutMs); + int getCommandDefaultTimeout(); + + void setPinToGpioMapper(PinToGpioMapper mapper); + + static const char* getWiconnectResultStr(WiconnectResult wiconnectResult); + void setDebugLogger(LogFunc logFunc); + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + WiconnectResult enqueueCommand(QueuedCommand *command, const Callback &commandCompleteHandler = Callback()); + void setCommandProcessingPeriod(uint32_t periodMs); +#endif + +protected: + +#ifdef WICONNECT_ENABLE_MALLOC + void* (*_malloc)(size_t); + void (*_free)(void *); + friend class QueuedCommand; + friend class WiconnectSerial; + friend class ScanResult; + friend class Socket; + friend class File; +#endif + + wiconnect::WiconnectSerial serial; + wiconnect::Gpio resetGpio; + wiconnect::Gpio wakeGpio; + + volatile bool commandExecuting; + bool initialized; + bool nonBlocking; + + PinToGpioMapper pinToGpioMapper; + + char *internalBuffer; + int internalBufferSize; + bool internalBufferAlloc; + uint8_t internalProcessingState; + void *currentCommandId; + + wiconnect::TimeoutTimer timeoutTimer; + int defaultTimeoutMs; + + uint8_t commandHeaderBuffer[32]; + char commandFormatBuffer[WICONNECT_MAX_CMD_SIZE]; + uint8_t commandContext[96]; + + void prepare(void *internalBuffer, int internalBufferSize, bool nonBlocking); + WiconnectResult inline receiveResponse(); + WiconnectResult inline receivePacket(); + void issueCommandCallback(WiconnectResult result); + + wiconnect::LogFunc debugLogger; + void debugLog(const char *msg, ...); + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + wiconnect::PeriodicTimer commandProcessorTimer; + uint32_t commandProcessingPeriod; + CommandQueue commandQueue; + wiconnect::QueuedCommand *currentQueuedCommand; + + void commandProcessingTimerHandler(void); + void processNextQueuedCommand(); + void checkQueuedCommandTimeout(); +#endif + + friend class NetworkInterface; + friend class SocketInterface; + friend class FileInterface; +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WiconnectTypes.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,222 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include <stdint.h> +#include <stdarg.h> + +#include "sdk.h" + +namespace wiconnect { + + +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif +#define ALIGN_n(x, n) ((((uint32_t)x) + ((n)-1)) & ~((n)-1)) +#define ALIGN_8(x) ALIGN_n(x, 8) +#define ALIGN_4(x) ALIGN_n(x, 4) + +#ifndef OFFSETOF +#define OFFSETOF(type, member) ((uintptr_t)&((type *)0)->member) +#endif + +#define ARRAY_COUNT(x) (sizeof (x) / sizeof *(x)) + + +#define WICONNECT_FAILED(result, func) ((int)(result = (func)) < (int)wiconnect::WICONNECT_SUCCESS) +#define WICONNECT_SUCCEEDED(result, func) ((result = (func)) == wiconnect::WICONNECT_SUCCESS) + +#define WICONNECT_NULL_RESPONSE_HANDLER WiconnectAsyncCallback() + + +#define WICONNECT_MAX_CMD_SIZE 128 +#define WICONNECT_MAX_VERSION_SIZE 96 +#define WICONNECT_MAX_SOCKETS 8 + + +#define SOCKET_INVALID_HANDLE ((uint8_t)0xFF) + + +typedef enum +{ + WICONNECT_ABORTED = 3, + WICONNECT_IDLE = 2, + WICONNECT_PROCESSING = 1, + WICONNECT_SUCCESS = 0, + WICONNECT_ERROR = -1, + WICONNECT_CMD_RESPONSE_ERROR = -2, + WICONNECT_NULL_BUFFER = -3, + WICONNECT_NOT_INITIALIZED = -4, + WICONNECT_OVERFLOW = -5, + WICONNECT_TIMEOUT = -6, + WICONNECT_RESPONSE_HANDLER_NULL = -7, + WICONNECT_RESPONSE_PARSE_ERROR = -8, + WICONNECT_ANOTHER_CMD_EXECUTING = -9, + WICONNECT_BAD_ARG = -10, + WICONNECT_UNSUPPORTED = -11, + WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL = -12, + WICONNECT_DUPLICATE = -13, + WICONNECT_NOT_FOUND = -14, + WICONNECT_PINNAME_TO_GPIO_NO_MAPPING = -15, + WICONNECT_NOT_CONNECTED = -16, + WICONNECT_UNDERFLOW = -17, + WICONNECT_MONITOR_NOT_AVAILABLE = -18, + WICONNECT_NOT_OPENED_FOR_READING = -19, +} WiconnectResult; + + +typedef enum +{ + NETWORK_STATUS_DOWN, + NETWORK_STATUS_WIFI_ONLY, + NETWORK_STATUS_UP +} NetworkStatus; + +typedef enum +{ + NETWORK_RSSI_EXCELLENT = 0, ///< > -20 dBm + NETWORK_RSSI_VERY_GOOD = 1, ///< > -35 dBm + NETWORK_RSSI_GOOD = 2, ///< > -50 dBm + NETWORK_RSSI_POOR = 3, ///< > -70 dBm + NETWORK_RSSI_VERY_POOR = 4, ///< < -71 dBm + NETWORK_RSSI_UNKNOWN = 5 ///< Not available +} NetworkSignalStrength; + +typedef enum +{ + NETWORK_SECURITY_OPEN, + NETWORK_SECURITY_WEP_PSK, + NETWORK_SECURITY_WPA_AES_PSK, + NETWORK_SECURITY_WPA_TKIP_PSK, + NETWORK_SECURITY_WPA2_AES_PSK, + NETWORK_SECURITY_WPA2_MIXED_PSK, + NETWORK_SECURITY_WPA2_TKIP_PSK, + NETWORK_SECURITY_UNKNOWN +} NetworkSecurity; + +typedef struct +{ + uint8_t val[32]; + uint8_t len; +} Ssid; + +typedef struct +{ + uint8_t octet[6]; +} MacAddress; +typedef char MacAddressStrBuffer[18]; +typedef char SsidStrBuffer[129]; +typedef char IpStrBuffer[18]; + + +typedef enum +{ + SOCKET_TYPE_UNKNOWN, + SOCKET_TYPE_TCP, + SOCKET_TYPE_TLS, + SOCKET_TYPE_UDP, + SOCKET_TYPE_HTTP, +} SocketType; + +typedef enum +{ + SOCKET_HTTP_GET, + SOCKET_HTTP_POST, + SOCKET_HTTP_HEAD, +} HttpSocketType; + +typedef struct +{ + const char *contextType; + const char *certName; + bool openOnly; + HttpSocketType type; +} HttpSocketArgs; + +typedef int8_t (*PinToGpioMapper)(Pin pin); + + +typedef enum +{ + FILE_FLAG_NONE = 0, + + FILE_FLAG_VALID = (1 << 0), + FILE_FLAG_EXECUTABLE = (1 << 1), + FILE_FLAG_ENCRYPTED = (1 << 2), + FILE_FLAG_INTERNAL = (1 << 3), + FILE_FLAG_BOOTABLE = (1 << 4), + FILE_FLAG_USER = (1 << 5), + FILE_FLAG_ESSENTIAL = (1 << 6), + FILE_FLAG_BACKUP = (1 << 7), + + FILE_FLAG_FORCE_COPY = (1 << 15), + + FILE_FLAG_INVALID = 0xFFFF +} FileFlags; + +typedef enum +{ + FILE_TYPE_UPGRADE_APP = 0x00, + FILE_TYPE_WIFI_FW = 0x01, + FILE_TYPE_SHARED_LIB = 0x02, + FILE_TYPE_TLS_CERT = 0x03, + FILE_TYPE_TXT_LOG = 0x04, + FILE_TYPE_DCT = 0x05, + + FILE_TYPE_MISC_APP = 0x80, + FILE_TYPE_REGULAR_APP = 0x81, + + FILE_TYPE_USER_RANGE_START = 150, + FILE_TYPE_USER_RANGE_END = 199, + + FILE_TYPE_TEMPORY = 0xF9, + FILE_TYPE_GPIO_CONFIG = 0xFA, + FILE_TYPE_COMMAND_HELP = 0xFB, + FILE_TYPE_SDC_CAPS = 0xFC, + FILE_TYPE_SETUP_SCRIPT = 0xFD, + FILE_TYPE_MISC_FIX_LEN = 0xFE, + FILE_TYPE_UNKNOWN = 0xFF, + FILE_TYPE_ANY = FILE_TYPE_UNKNOWN +} FileType; + +typedef struct +{ + int size; + uint8_t *buffer; + uint8_t *ptr; + int bytesPending; + bool allocated; +} Buffer; + + +class Wiconnect; +class TimeoutTimer; +class PeriodicTimer; +class QueuedCommand; +class CommandQueue; +class LogFunc; +class ReaderFunc; +class Callback; +class ScanResult; +class ScanResultList; +class Socket; +class WiconnectSerial; +class File; +class FileList; +class Gpio; +class SocketIrqHandlerMap; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/WiconnectCommands.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,29 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + + + +#define CMD_SAVE "save" +#define CMD_GET_VERSION "ver" + + +#define CMD_SET_SYSTEM_COMMAND_MODE "set system.cmd.mode %s" +#define CMD_SET_NETWORK_DHCP "set network.dhcp %d" +#define CMD_SET_STATIC_IP "set static.ip %d.%d.%d.%d" +#define CMD_SET_STATIC_GATEWAY "set static.netmask %d.%d.%d.%d" +#define CMD_SET_STATIC_NETMASK "set static.gatewat %d.%d.%d.%d" + + +#define CMD_GET_NETWORK_STATUS "get network.status" + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/common.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + + +#include "WiconnectCommands.h" + +/* Note we need the 2 concats below because arguments to ## + * are not expanded, so we need to expand __LINE__ with one indirection + * before doing the actual concatenation. */ +#define ASSERT_CONCAT_(a, b) a##b +#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) +#define ct_assert(e) enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) } + + +#ifndef WICONNECT_ASYNC_TIMER_ENABLED +#define CHECK_CALLBACK_AVAILABLE(cb) if(cb.isValid()) return WICONNECT_UNSUPPORTED +#else +#define CHECK_CALLBACK_AVAILABLE(cb) +#endif + +#define CHECK_CLEANUP_COMMAND() \ + if(result != WICONNECT_PROCESSING) \ + { \ + wiconnect->internalProcessingState = 0; \ + wiconnect->currentCommandId = NULL; \ + } + +#define CHECK_OTHER_COMMAND_EXECUTING() \ +{ \ + static const volatile uint8_t __funcId = 0; \ + if(wiconnect->currentCommandId == NULL) \ + { \ + wiconnect->currentCommandId = (void*)&__funcId; \ + } \ + else if(wiconnect->currentCommandId != (void*)&__funcId) \ + { \ + return WICONNECT_ANOTHER_CMD_EXECUTING; \ + } \ +} + + +#define WICONNECT_IS_IDLE() (wiconnect->currentCommandId == NULL) + + + + +#ifdef WICONNECT_USE_DEFAULT_STRING_BUFFERS +#define SET_STR_BUFFER(_buffer, size) \ + char *ptr, *buf; \ + (void)buf; \ + static char defaultBuffer[size]; \ + ptr = buf = (_buffer == NULL) ? defaultBuffer : _buffer; +#else +#define SET_STR_BUFFER(_buffer, size) \ + char *ptr, *buf; \ + (void)buf; \ + if(_buffer == NULL) \ + { \ + return "<null>"; \ + } \ + ptr = buf = _buffer; +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/file/FileInterface.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,207 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "internal/common.h" +#include "StringUtil.h" + + +/*************************************************************************************************/ +FileInterface::FileInterface(Wiconnect *wiconnect_) +{ + wiconnect = wiconnect_; +} + +/*************************************************************************************************/ +WiconnectResult FileInterface::openFile(File &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_MAX_CMD_SIZE]; + + if(WICONNECT_IS_IDLE()) + { + char *ptr = cmdBuffer; + + ptr += sprintf(cmdBuffer, "fcr %s%s %d", isEssential ? "-e " : "", name, 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", 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 File &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 Dcript"; + 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); + 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; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/file/FileList.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "internal/common.h" +#include "StringUtil.h" + + +static bool nameMatches(const char *needle, const char* haystack); + + + +/*************************************************************************************************/ +WiconnectResult FileInterface::listFiles(FileList &list, const char *name, FileType type, uint32_t version) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("ls -v"))) + { + result = processFileList(wiconnect->internalBuffer, list, name, type, version); + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult FileInterface::processFileList(char *responseStr, FileList &list, const char *name, FileType type, uint32_t version) +{ + WiconnectResult result = WICONNECT_SUCCESS; + char *line, *savedLine; + + for(savedLine = responseStr; (line = StringUtil::strtok_r(savedLine, "\r\n", &savedLine)) != NULL;) + { + uint32_t tmp; + char *toks[7], *savedTok; + + if(*line != '#') + { + continue; + } + savedTok = line + 2; + + for(int i = 0; i < 6 && (toks[i] = StringUtil::strtok_r(savedTok, " ", &savedTok)) != NULL; ++i) + { + if(toks[i] == NULL) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + goto exit; + } + } + + + if(name != NULL && !nameMatches(name, savedTok+1)) + { + continue; + } + else if((type != FILE_TYPE_ANY) && + StringUtil::strHexToUint32((const char*)&toks[1][2], &tmp) && + (type != (FileType)tmp)) + { + continue; + } + else if((version != 0) && + FileInterface::fileVersionStrToInt(toks[5], &tmp) && + (version != tmp)) + { + continue; + } + else if(WICONNECT_FAILED(result, list.add(toks[1], toks[2], toks[4], toks[5], savedTok+1))) + { + goto exit; + } + } + + exit: + return result; +} + + +/*************************************************************************************************/ +static bool nameMatches(const char *needle, const char* haystack) +{ + const int haystackLen = strlen(haystack); + + if(*needle == '*') + { + const int n = strlen(needle + 1); + + if(n > haystackLen) + { + return false; + } + return strcmp(needle+1, &haystack[haystackLen - n]) == 0; + } + else + { + return strcmp(needle, haystack) == 0; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/network/NetworkInterface.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,493 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "internal/common.h" +#include "StringUtil.h" + + +#define IPV4_FORMAT "%d.%d.%d.%d" +#define IPV4_ARGS(ip) \ + (int)( (ip) & 0xff), \ + (int)(((ip) >> 8) & 0xff), \ + (int)(((ip) >> 16) & 0xff), \ + (int)(((ip) >> 24) & 0xff) + + + +/*************************************************************************************************/ +NetworkInterface::NetworkInterface(Wiconnect *wiconnect_) +{ + wiconnect = wiconnect_; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::ping(const char *domain, uint32_t *timeMsPtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(completeHandler, "ping %s", (domain == NULL) ? "-g" : domain)) && + timeMsPtr != NULL) + { + if(sscanf(wiconnect->internalBuffer, "Ping reply in %ums", timeMsPtr) != 1) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::lookup(const char *domain, uint32_t *ipAddressPtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("nlo %s", domain))) + { + if(!NetworkInterface::strToIp(wiconnect->internalBuffer, ipAddressPtr)) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::setDhcpEnabled(bool enabled) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand(CMD_SET_NETWORK_DHCP, enabled); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::getDhcpEnabled(bool *enabledPtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.dhcp"))) + { + int32_t enabled; + if(WICONNECT_SUCCEEDED(result, wiconnect->responseToInt32(&enabled))) + { + *enabledPtr = (bool)enabled; + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::setIpSettings(uint32_t ip, uint32_t netmask, uint32_t gateway) +{ + WiconnectResult result; + + enum + { + FS_SET_IP, + FS_SET_NETMASK, + FS_SET_GATEWAY + }; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(wiconnect->internalProcessingState == FS_SET_IP) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_IP, IPV4_ARGS(ip)))) + { + wiconnect->internalProcessingState = FS_SET_NETMASK; + } + } + + if(wiconnect->internalProcessingState == FS_SET_NETMASK) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_NETMASK, IPV4_ARGS(netmask)))) + { + wiconnect->internalProcessingState = FS_SET_GATEWAY; + } + } + + if(wiconnect->internalProcessingState == FS_SET_GATEWAY) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_GATEWAY, IPV4_ARGS(gateway)))) + { + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::setIpSettings(const char* ipStr, const char* netmaskStr, const char* gatewayStr) +{ + uint32_t ip, nm, gw; + + if( !NetworkInterface::strToIp(ipStr, &ip) || + !NetworkInterface::strToIp(netmaskStr, &nm) || + !NetworkInterface::strToIp(gatewayStr, &gw)) + { + return WICONNECT_ERROR; + } + return setIpSettings(ip, nm, gw); +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::getIpSettings(uint32_t *ip, uint32_t *netmask, uint32_t *gateway) +{ + WiconnectResult result; + + enum + { + FS_GET_IP, + FS_GET_NETMASK, + FS_GET_GATEWAY + }; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(wiconnect->internalProcessingState == FS_GET_IP) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.ip"))) + { + if(!NetworkInterface::strToIp(wiconnect->internalBuffer, ip)) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + wiconnect->internalProcessingState = FS_GET_NETMASK; + } + } + } + + if(wiconnect->internalProcessingState == FS_GET_NETMASK) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.netmask"))) + { + if(!NetworkInterface::strToIp(wiconnect->internalBuffer, netmask)) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + wiconnect->internalProcessingState = FS_GET_GATEWAY; + } + } + } + + if(wiconnect->internalProcessingState == FS_GET_GATEWAY) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.gateway"))) + { + if(!NetworkInterface::strToIp(wiconnect->internalBuffer, gateway)) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + } + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} +/*************************************************************************************************/ +WiconnectResult NetworkInterface::getSignalStrength(NetworkSignalStrength *signalStrengthPtr) +{ + WiconnectResult result; + int32_t rssi_dbm; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("rssi"))) + { + if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&rssi_dbm))) + { + *signalStrengthPtr = NetworkInterface::rssiToSignalStrength(rssi_dbm); + } + } + + if(result == WICONNECT_CMD_RESPONSE_ERROR) + { + *signalStrengthPtr = NETWORK_RSSI_UNKNOWN; + result = WICONNECT_SUCCESS; + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +//----------------------------------------------------------------------------------------------- + + +/*************************************************************************************************/ +bool NetworkInterface::strToIp(const char *str, uint32_t *intPtr) +{ + if (!intPtr) + { + return false; + } + int temp[4]; + + if(sscanf(str, "%d.%d.%d.%d", &temp[0], &temp[1], &temp[2], &temp[3] ) != 4) + { + return false; + } + else if(temp[0] > 255 || temp[1] > 255 || temp[2] > 255 || temp[3] > 255) + { + return false; + } + *intPtr = (uint32_t)temp[3] << 24 | temp[2] << 16 | temp[1] << 8 | temp[0]; + + return true; +} + +/*************************************************************************************************/ +const char* NetworkInterface::ipToStr(uint32_t ip, char *ipStrBuffer) +{ + SET_STR_BUFFER(ipStrBuffer, 16); + sprintf(ptr, IPV4_FORMAT, IPV4_ARGS(ip)); + return ptr; +} + +/*************************************************************************************************/ +const char* NetworkInterface::networkStatusToStr(NetworkStatus status) +{ + switch(status) + { + case NETWORK_STATUS_DOWN: + return "Down"; + case NETWORK_STATUS_WIFI_ONLY: + return "WiFi Only"; + case NETWORK_STATUS_UP: + return "Up"; + default: + return "Unknown"; + } +} + +/*************************************************************************************************/ +const char* NetworkInterface::signalStrengthToStr(NetworkSignalStrength signalStrenth) +{ + switch(signalStrenth) + { + case NETWORK_RSSI_EXCELLENT: + return "Excellent"; + case NETWORK_RSSI_VERY_GOOD: + return "Very Good"; + case NETWORK_RSSI_GOOD: + return "Good"; + case NETWORK_RSSI_POOR: + return "Poor"; + case NETWORK_RSSI_VERY_POOR: + return "Very Poor"; + case NETWORK_RSSI_UNKNOWN: + default: + return "Unknown"; + } +} + +/*************************************************************************************************/ +NetworkSignalStrength NetworkInterface::rssiToSignalStrength(int rssi_dbm) +{ + if(rssi_dbm > -20) + { + return NETWORK_RSSI_EXCELLENT; + } + else if(rssi_dbm > -35) + { + return NETWORK_RSSI_VERY_GOOD; + } + else if(rssi_dbm > -50) + { + return NETWORK_RSSI_GOOD; + } + else if(rssi_dbm > -70) + { + return NETWORK_RSSI_POOR; + } + else + { + return NETWORK_RSSI_VERY_POOR; + } +} + + +typedef struct +{ + const char* key; + NetworkSecurity value; +} NetworkSecurityTableEntry; + +static const NetworkSecurityTableEntry networkSecurityTable[] = { + {"Auto", NETWORK_SECURITY_UNKNOWN}, + {"Open", NETWORK_SECURITY_OPEN}, + {"Unknown", NETWORK_SECURITY_UNKNOWN}, + {"WEP", NETWORK_SECURITY_WEP_PSK}, + {"WPA-AES", NETWORK_SECURITY_WPA_AES_PSK}, + {"WPA-TKIP", NETWORK_SECURITY_WPA_TKIP_PSK}, + {"WPA2-AES", NETWORK_SECURITY_WPA2_AES_PSK}, + {"WPA2-Mixed", NETWORK_SECURITY_WPA2_MIXED_PSK}, + {"WPA2-TKIP", NETWORK_SECURITY_WPA2_TKIP_PSK}, +}; + + +/*************************************************************************************************/ +NetworkSecurity NetworkInterface::strToNetworkSecurity(const char *str) +{ + const NetworkSecurityTableEntry *end = &networkSecurityTable[ARRAY_COUNT(networkSecurityTable)]; + + for(const NetworkSecurityTableEntry *e = networkSecurityTable; e < end; ++e) + { + if(StringUtil::strcasecmp(e->key, str) == 0) + { + return e->value; + } + } + return NETWORK_SECURITY_UNKNOWN; +} + +/*************************************************************************************************/ +const char* NetworkInterface::networkSecurityToStr(NetworkSecurity security) +{ + const NetworkSecurityTableEntry *end = &networkSecurityTable[ARRAY_COUNT(networkSecurityTable)]; + + for(const NetworkSecurityTableEntry *e = networkSecurityTable; e < end; ++e) + { + if(e->value == security) + { + return e->key; + } + } + return "Unknown"; +} + +/*************************************************************************************************/ +bool NetworkInterface::strToSsid(const char *str, Ssid *ssid) +{ +#define ESCAPE_CHARACTER_DELIMITER '\\' +#define HEX_ESCAPE_CHARACTER 'x' + int c; + uint8_t *ssidPtr = ssid->val; + int ssidLen = 0; + + while((c = (int)(*str++)) != 0) + { + if(c == ESCAPE_CHARACTER_DELIMITER) + { + if(*str == HEX_ESCAPE_CHARACTER) + { + c = StringUtil::hexToInt(str+1); + if(c == -1) + return false; + str += 3; + } + else + { + return false; + } + } + if(ssidLen >= sizeof(ssid->val)) + return false; + ++ssidLen; + *ssidPtr++ = (uint8_t)c; + } + + ssid->len = ssidLen; + + return true; +} + +/*************************************************************************************************/ +const char* NetworkInterface::ssidToStr(const Ssid *ssid, char *ssidStrBuffer) +{ + SET_STR_BUFFER(ssidStrBuffer, sizeof(SsidStrBuffer)); + const char *src = (const char*)ssid->val; + int len = ssid->len; + + while(len--) + { + if(*src >= 0x20 && *src <= 0x7E) + { + *ptr++ = *src; + } + else + { + ptr += sprintf(ptr, "\\x%02X", (*src) & 0xff); + } + ++src; + } + *ptr = 0; + return buf; +} + +/*************************************************************************************************/ +bool NetworkInterface::strToMacAddress(const char *str, MacAddress *macAddress) +{ + const char* strPtr = str; + uint8_t *macPtr = (uint8_t*)macAddress->octet; + + for(int count = 0; count < 6; ++count) + { + if(count < 5) + { + const char *idx = strchr(strPtr, ':'); + if(idx == NULL) + { + return false; + } + } + int num = StringUtil::hexToInt(strPtr); + if(num == -1) + { + return false; + } + *macPtr++ = (uint8_t)num; + strPtr += 3; + } + + return true; +} + +/*************************************************************************************************/ +const char* NetworkInterface::macAddressToStr(const MacAddress *macAddress, char *macStrBuffer) +{ + SET_STR_BUFFER(macStrBuffer, sizeof(MacAddressStrBuffer)); + const uint8_t *mac = macAddress->octet; + + sprintf(ptr, "%02X:%02X:%02X:%02X:%02X:%02X", + (unsigned int)mac[0], + (unsigned int)mac[1], + (unsigned int)mac[2], + (unsigned int)mac[3], + (unsigned int)mac[4], + (unsigned int)mac[5]); + + return ptr; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/network/NetworkJoin.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,165 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include "Wiconnect.h" +#include "internal/common.h" + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::join(const char* ssid, const char *password, const Callback &completeHandler_) +{ + WiconnectResult result; + + enum + { + FS_SET_SSID, + FS_SET_PASSWORD, + FS_NETWORK_UP + }; + + CHECK_CALLBACK_AVAILABLE(completeHandler_); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(wiconnect->internalProcessingState == FS_SET_SSID) + { + if(ssid == NULL || + WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set wlan.ssid %s", ssid))) + { + wiconnect->internalProcessingState = FS_SET_PASSWORD; + } + } + + if(wiconnect->internalProcessingState == FS_SET_PASSWORD) + { + if(password == NULL || + WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set wlan.passkey %s", password))) + { + wiconnect->internalProcessingState = FS_NETWORK_UP; + } + } + + if(wiconnect->internalProcessingState == FS_NETWORK_UP) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("network_up"))) + { +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + if(completeHandler_.isValid()) + { + if(monitorTimer.isRunning()) + { + result = WICONNECT_MONITOR_NOT_AVAILABLE; + } + else + { + completeHandler = completeHandler_; + monitorTimer.start(this, &NetworkInterface::joinStatusMonitor, 1000); + } + } +#endif + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::leave() +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + monitorTimer.stop(); +#endif + result = wiconnect->sendCommand("network_down"); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::getNetworkStatus(NetworkStatus *statusPtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.status"))) + { + int32_t status; + if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status))) + { + *statusPtr = (NetworkStatus)status; + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + +/*************************************************************************************************/ +// this is called every 1s by the monitorTimer +void NetworkInterface::joinStatusMonitor() +{ + monitorTimer.stop(); + QueuedCommand *cmd = new QueuedCommand(32, NULL, "get network.status"); + if(cmd == NULL) + return; + if(wiconnect->enqueueCommand(cmd, Callback(this, &NetworkInterface::joinStatusCheckCallback)) != WICONNECT_SUCCESS) + { + delete cmd; + } +} + +/*************************************************************************************************/ +// this is called on the completion of the 'get'network.status' command above +void NetworkInterface::joinStatusCheckCallback(WiconnectResult result, void *arg1, void *arg2) +{ + bool isComplete = true; + + QueuedCommand *cmd = (QueuedCommand*)arg1; + + if(result == WICONNECT_SUCCESS) + { + int32_t status; + if(!StringUtil::strToInt32(cmd->responseBuffer, &status)) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + } + else if(status == 0) + { + isComplete = false; + } + } + + delete cmd; + + if(isComplete) + { + completeHandler.call(result, NULL, NULL); + } + else + { + monitorTimer.start(this, &NetworkInterface::joinStatusMonitor, 1000); + } +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/network/NetworkScan.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,143 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include "Wiconnect.h" +#include "internal/common.h" + + +#define SCAN_TIMEOUT 15000 + + + + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::scan(ScanResultList &resultList, const uint8_t *channelList, const char* ssid) +{ + WiconnectResult result; + char cmdBuffer[WICONNECT_MAX_CMD_SIZE]; + + CHECK_CALLBACK_AVAILABLE(completeHandler_); + + if(WICONNECT_IS_IDLE()) + { +#define SCAN_CMD "scan -v " + char *cmdBufferPtr = cmdBuffer + sizeof(SCAN_CMD)-1; + + strcpy(cmdBuffer, SCAN_CMD); + + if(channelList != NULL) + { + for(const uint8_t *ch = (const uint8_t *)channelList; *ch != 0; ++ch) + { + cmdBufferPtr += sprintf(cmdBufferPtr, "%d,", *ch); + } + *(cmdBufferPtr-1) = ' '; + } + else + { + strcat(cmdBufferPtr, "all "); + cmdBufferPtr += 4; + } + + if(ssid != NULL) + { + strcpy(cmdBufferPtr, ssid); + } + } + + CHECK_OTHER_COMMAND_EXECUTING(); + + //if(!completeHandler_.isValid()) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(SCAN_TIMEOUT, cmdBuffer))) + { + result = processScanResults(wiconnect->internalBuffer, resultList); + } + } +//#ifdef WICONNECT_ASYNC_TIMER_ENABLED +// else +// { +// QueuedCommand *cmd = new QueuedCommand(NULL, 4096, SCAN_TIMEOUT, cmdBuffer); +// cmd->userData = (void*)resultList; +// completeHandler = completeHandler_; +// if(WICONNECT_FAILED(result, wiconnect->enqueueCommand(cmd, Callback(this, &NetworkInterface::scanCompleteCallback)))) +// { +// delete cmd; +// } +// else +// { +// result = WICONNECT_PROCESSING; +// } +// } +//#endif + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + + + + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::processScanResults(char *resultStr, ScanResultList &resultList) +{ + WiconnectResult result = WICONNECT_SUCCESS; + char *line, *savedLine; + + for(savedLine = resultStr; (line = StringUtil::strtok_r(savedLine, "\r\n", &savedLine)) != NULL;) + { + char *toks[9], *savedTok; + + if(*line != '#') + { + continue; + } + savedTok = line + 2; + + for(int i = 0; i < 8 && (toks[i] = StringUtil::strtok_r(savedTok, " ", &savedTok)) != NULL; ++i) + { + if(toks[i] == NULL) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + goto exit; + } + } + + if(WICONNECT_FAILED(result, resultList.add(toks[1], toks[2], toks[3], toks[4], toks[5], savedTok))) + { + goto exit; + } + } + + exit: + return result; +} + +//#ifdef WICONNECT_ASYNC_TIMER_ENABLED +// +/*************************************************************************************************/ +//void NetworkInterface::scanCompleteCallback(WiconnectResult result, void *arg1, void *arg2) +//{ +// QueuedCommand *cmd = (QueuedCommand*)arg1; +// ScanResultList *listPtr = (ScanResultList*)cmd->userData; +// +// if(result == WICONNECT_SUCCESS) +// { +// result = processScanResults(cmd->responseBuffer, listPtr); +// } +// delete cmd; +// +// completeHandler.call(result, listPtr, NULL); +//} +// +//#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/network/NetworkSoftAp.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,32 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include "Wiconnect.h" + + + +///*************************************************************************************************/ +//WiconnectResult NetworkInterface::startSoftAp(const char* ssid, const char *password, WiconnectAsyncCallback *clientConnected) +//{ +// return WICONNECT_UNSUPPORTED; +//} +// +///*************************************************************************************************/ +//WiconnectResult NetworkInterface::stopSoftAp() +//{ +// return WICONNECT_UNSUPPORTED; +//} +// +///*************************************************************************************************/ +//WiconnectResult NetworkInterface::getSoftApClientList() +//{ +// return WICONNECT_UNSUPPORTED; +//} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/network/NetworkWebSetup.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,163 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include "Wiconnect.h" +#include "internal/common.h" + + + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::startWebSetup(const char *ssid, const char *password, const Callback &completeHandler_) +{ + WiconnectResult result; + + enum + { + FS_SET_SSID, + FS_SET_PASSWORD, + FS_NETWORK_UP + }; + + CHECK_CALLBACK_AVAILABLE(completeHandler_); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(wiconnect->internalProcessingState == FS_SET_SSID) + { + if(ssid == NULL || + WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set setup.web.ssid %s", ssid))) + { + wiconnect->internalProcessingState = FS_SET_PASSWORD; + } + } + + if(wiconnect->internalProcessingState == FS_SET_PASSWORD) + { + if(password == NULL || + WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set setup.web.passkey %s", password))) + { + wiconnect->internalProcessingState = FS_NETWORK_UP; + } + } + + if(wiconnect->internalProcessingState == FS_NETWORK_UP) + { + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("setup web"))) + { +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + if(completeHandler_.isValid()) + { + if(monitorTimer.isRunning()) + { + result = WICONNECT_MONITOR_NOT_AVAILABLE; + } + else + { + completeHandler = completeHandler_; + monitorTimer.start(this, &NetworkInterface::webSetupStatusMonitor, 1000); + } + } +#endif + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::stopWebSetup() +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + #ifdef WICONNECT_ASYNC_TIMER_ENABLED + monitorTimer.stop(); + #endif + result = wiconnect->sendCommand("setup stop"); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +/*************************************************************************************************/ +WiconnectResult NetworkInterface::isWebSetupRunning(bool *isRunningPtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("setup status"))) + { + int32_t status; + if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status))) + { + *isRunningPtr = (bool)status; + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + +/*************************************************************************************************/ +void NetworkInterface::webSetupStatusMonitor() +{ + monitorTimer.stop(); + QueuedCommand *cmd = new QueuedCommand(32, NULL, "setup status"); + if(cmd == NULL) + return; + if(wiconnect->enqueueCommand(cmd, Callback(this, &NetworkInterface::webSetupStatusCheckCallback)) != WICONNECT_SUCCESS) + { + delete cmd; + } +} + +/*************************************************************************************************/ +void NetworkInterface::webSetupStatusCheckCallback(WiconnectResult result, void *arg1, void *arg2) +{ + bool isComplete = true; + + QueuedCommand *cmd = (QueuedCommand*)arg1; + + if(result == WICONNECT_SUCCESS) + { + int32_t status; + if(!StringUtil::strToInt32(cmd->responseBuffer, &status)) + { + result = WICONNECT_RESPONSE_PARSE_ERROR; + } + else if(status > 0) + { + isComplete = false; + } + } + + delete cmd; + + if(isComplete) + { + completeHandler.call(result, NULL, NULL); + } + else + { + monitorTimer.start(this, &NetworkInterface::webSetupStatusMonitor, 1000); + } +} + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/socket/SocketInterface.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,267 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "internal/common.h" +#include "StringUtil.h" + +#include "types/SocketIrqHandlerMap.h" + + + + +/*************************************************************************************************/ +SocketInterface::SocketInterface(Wiconnect *wiconnect_) +{ + wiconnect = wiconnect_; +} + +/*************************************************************************************************/ +SocketInterface::~SocketInterface() +{ +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::connect(Socket &socket, SocketType type, const char *host, uint16_t remortPort, uint16_t localPort, const void *args, Pin irqPin) +{ + WiconnectResult result; + int32_t handle; + char cmdBuffer[WICONNECT_MAX_CMD_SIZE]; + + if(WICONNECT_IS_IDLE()) + { + char gpioOption[8] = ""; + + if(irqPin != NC) + { + PinToGpioMapper mapper = wiconnect->pinToGpioMapper; + if(mapper == NULL) + { + return WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL; + } + int8_t gpio = mapper(irqPin); + if(gpio == -1) + { + return WICONNECT_PINNAME_TO_GPIO_NO_MAPPING; + } + else if(!irqHandlers.pinIsRegistered(irqPin)) + { + return WICONNECT_NOT_FOUND; + } + + sprintf(gpioOption, "-g %d ", gpio); + } + + + switch(type) + { + case SOCKET_TYPE_TCP: + sprintf(cmdBuffer, "tcpc %s%s %d", gpioOption, host, remortPort); + break; + + case SOCKET_TYPE_UDP: { + char tmp[16]; + sprintf(cmdBuffer, "udpc %s%s %d %s", gpioOption, host, remortPort, + (localPort != SOCKET_ANY_PORT) ? StringUtil::uint32ToStr(tmp, localPort) : ""); + } break; + + case SOCKET_TYPE_TLS: + sprintf(cmdBuffer, "tlsc %s%s %d %s", gpioOption, host, remortPort, + (args != NULL) ? (char*)args : ""); + break; + + case SOCKET_TYPE_HTTP: { + const HttpSocketArgs *httpArgs = (const HttpSocketArgs*)args; + switch(httpArgs->type) + { + case SOCKET_HTTP_GET: + sprintf(cmdBuffer, "http_get %s%s %s", httpArgs->openOnly ? "-o " : "", + host, + (httpArgs->certName != NULL) ? httpArgs->certName : ""); + break; + + case SOCKET_HTTP_HEAD: + sprintf(cmdBuffer, "http_head %s%s %s", httpArgs->openOnly ? "-o " : "", + host, + (httpArgs->certName != NULL) ? httpArgs->certName : ""); + break; + + case SOCKET_HTTP_POST: + sprintf(cmdBuffer, "http_post %s%s %s %s", httpArgs->openOnly ? "-o " : "", + host, + httpArgs->contextType, + (httpArgs->certName != NULL) ? httpArgs->certName : ""); + break; + + default: + return WICONNECT_BAD_ARG; + } + + } break; + default: + return WICONNECT_BAD_ARG; + } + } + + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(cmdBuffer))) + { + if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&handle))) + { + socket.init(handle, type, host, remortPort, localPort); + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::tcpConnect(Socket &socket, const char *host, uint16_t remortPort, Pin irqPin) +{ + return connect(socket, SOCKET_TYPE_TCP, host, remortPort, SOCKET_ANY_PORT, NULL, irqPin); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::tlsConnect(Socket &socket, const char *host, uint16_t remortPort, const char *certFilename, Pin irqPin) +{ + return connect(socket, SOCKET_TYPE_TLS, host, remortPort, SOCKET_ANY_PORT, certFilename, irqPin); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::udpConnect(Socket &socket, const char *host, uint16_t remortPort, uint16_t localPort, Pin irqPin) +{ + return connect(socket, SOCKET_TYPE_UDP, host, remortPort, localPort, NULL, irqPin); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpConnect(Socket &socket, const char *url, const HttpSocketArgs *args) +{ + return connect(socket, SOCKET_TYPE_HTTP, url, SOCKET_ANY_PORT, SOCKET_ANY_PORT, args, NC); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpGet(Socket &socket, const char *url, bool openOnly, const char *certFilename) +{ + const HttpSocketArgs args + { + NULL, + certFilename, + openOnly, + SOCKET_HTTP_GET + }; + return httpConnect(socket, url, &args); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpPost(Socket &socket, const char *url, const char *contextType, bool openOnly, const char *certFilename) +{ + const HttpSocketArgs args + { + contextType, + certFilename, + openOnly, + SOCKET_HTTP_POST + }; + return httpConnect(socket, url, &args); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpHead(Socket &socket, const char *url, const char *certFilename) +{ + const HttpSocketArgs args + { + NULL, + certFilename, + false, + SOCKET_HTTP_HEAD + }; + return httpConnect(socket, url, &args); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpAddHeader(Socket &socket, const char *key, const char *value) +{ + WiconnectResult result; + char cmdBuffer[WICONNECT_MAX_CMD_SIZE]; + + if(WICONNECT_IS_IDLE()) + { + sprintf(cmdBuffer, "http_add_header %d %s %s", socket.getHandle(), key, value); + } + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand(cmdBuffer); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::httpGetStatus(Socket &socket, uint32_t *statusCodePtr) +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand("http_read_status %d", socket.getHandle()); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::closeAllSockets() +{ + WiconnectResult result; + + CHECK_OTHER_COMMAND_EXECUTING(); + + result = wiconnect->sendCommand("close all"); + + CHECK_CLEANUP_COMMAND(); + + return result; +} + + +/*************************************************************************************************/ +WiconnectResult SocketInterface::registerSocketIrqHandler(Pin irqPin, const Callback &handler) +{ + PinToGpioMapper mapper = wiconnect->pinToGpioMapper; + if(irqHandlers.pinIsRegistered(irqPin)) + { + return WICONNECT_DUPLICATE; + } + else if(mapper == NULL) + { + return WICONNECT_PINNAME_TO_GPIO_MAPPER_NULL; + } + int8_t gpio = mapper(irqPin); + if(gpio == -1) + { + return WICONNECT_PINNAME_TO_GPIO_NO_MAPPING; + } + + return irqHandlers.registerHandler(irqPin, handler); +} + +/*************************************************************************************************/ +WiconnectResult SocketInterface::unregisterSocketIrqHandler(Pin irqPin) +{ + return irqHandlers.unregisterHandler(irqPin); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/types/File.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,284 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include <assert.h> +#include "Wiconnect.h" +#include "internal/common.h" + +#define CHECK_OPENED_FOR_READING() if(!readEnabled) return WICONNECT_NOT_OPENED_FOR_READING + + + + +/*************************************************************************************************/ +File::File(int rxBufferLen, void *rxBuffer_) +{ + wiconnect = Wiconnect::getInstance(); + + memset(&rxBuffer, 0, sizeof(Buffer)); + + rxBuffer.size = !wiconnect->nonBlocking ? rxBufferLen : 0; + rxBuffer.buffer = (uint8_t*)rxBuffer_; + + if(rxBuffer.size > 0) + { + if(rxBuffer_ == NULL) + { +#ifdef WICONNECT_ENABLE_MALLOC + assert(wiconnect->_malloc != NULL); + rxBuffer.buffer = (uint8_t*)wiconnect->_malloc(rxBufferLen); + assert(rxBuffer.buffer != NULL); + rxBuffer.allocated = true; +#else + assert(0); +#endif + } + } + + previous = next = NULL; + handle = 0xff; + readEnabled = false; + *name = 0; + size = 0; + type = FILE_TYPE_UNKNOWN; + version = 0; + flags = FILE_FLAG_NONE; +} + +/*************************************************************************************************/ +File::~File() +{ + while(close() == WICONNECT_PROCESSING) + { + } + +#ifdef WICONNECT_ENABLE_MALLOC + if(rxBuffer.allocated && rxBuffer.size > 0) + { + assert(wiconnect->_free != NULL); + wiconnect->_free(rxBuffer.buffer); + } +#endif +} + +/*************************************************************************************************/ +WiconnectResult File::openForRead(uint8_t handle_, const char *filename) +{ + handle = handle_; + readEnabled = true; + strcpy(name, filename); + + return WICONNECT_SUCCESS; +} + +/*************************************************************************************************/ +WiconnectResult File::initWithListing(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr) +{ + uint32_t tmp; + + if(!StringUtil::strHexToUint32(&typeStr[2], &tmp)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + type = (FileType)tmp; + + if(!StringUtil::strHexToUint32(flagsStr, &tmp)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + flags = (FileFlags)tmp; + + if(!StringUtil::strToUint32(sizeStr, &tmp)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + size = (uint32_t)tmp; + + if(!FileInterface::fileVersionStrToInt(versionStr, &version)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + + strcpy(name, nameStr); + + return WICONNECT_SUCCESS; +} + +/*************************************************************************************************/ +void* File::operator new(size_t size) +{ + assert(Wiconnect::getInstance()->_malloc != NULL); + return Wiconnect::getInstance()->_malloc(size); +} + +/*************************************************************************************************/ +void File::operator delete(void* ptr) +{ + assert(Wiconnect::getInstance()->_free != NULL); + Wiconnect::getInstance()->_free(ptr); +} + + +/*************************************************************************************************/ +WiconnectResult File::close() +{ + WiconnectResult result; + CHECK_OPENED_FOR_READING(); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("close %d", handle))) + { + readEnabled = false; + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +const char* File::getName() const +{ + return name; +} + +/*************************************************************************************************/ +uint32_t File::getSize() const +{ + return size; +} + +/*************************************************************************************************/ +FileType File::getType() const +{ + return type; +} + +/*************************************************************************************************/ +FileFlags File::getFlags() const +{ + return flags; +} + +/*************************************************************************************************/ +uint32_t File::getVersion() const +{ + return version; +} + +/*************************************************************************************************/ +const char* File::getVersionStr(char *buffer) const +{ + return FileInterface::fileVersionIntToStr(version, true, buffer); +} + +/*************************************************************************************************/ +const File* File::getNext() const +{ + return next; +} + +/*************************************************************************************************/ +const File* File::getPrevious() const +{ + return previous; +} + + +/*************************************************************************************************/ +WiconnectResult File::read(void* buffer, uint16_t maxLength, uint16_t *bytesRead) +{ + WiconnectResult result; + + CHECK_OPENED_FOR_READING(); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand((char*)buffer, maxLength, "read %d %d", handle, maxLength-2))) + { + *bytesRead = wiconnect->getLastCommandResponseLength(); + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult File::read(uint8_t **bufferPtr, uint16_t *bytesReadPtr) +{ + WiconnectResult result = WICONNECT_SUCCESS; + + CHECK_OPENED_FOR_READING(); + + if(rxBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + else if(bufferPtr != NULL && bytesReadPtr == NULL) + { + return WICONNECT_BAD_ARG; + } + else if(rxBuffer.bytesPending < rxBuffer.size - 2) + { + const int bytesToRead = rxBuffer.size - rxBuffer.bytesPending - 2; + char* ptr = (char*)&rxBuffer.buffer[rxBuffer.bytesPending]; + if(!WICONNECT_FAILED(result, wiconnect->sendCommand(ptr, bytesToRead+2, "read %d %d", handle, bytesToRead))) + { + rxBuffer.bytesPending += wiconnect->getLastCommandResponseLength(); + } + } + + if(bufferPtr != NULL) + { + *bufferPtr = rxBuffer.buffer; + *bytesReadPtr = rxBuffer.bytesPending; + clearRxBuffer(); + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult File::getc(uint8_t *c) +{ + WiconnectResult result; + + if(rxBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + + read_data: + if(rxBuffer.bytesPending == 0 && + WICONNECT_FAILED(result, read())) + { + return result; + } + else if(rxBuffer.ptr < &rxBuffer.buffer[rxBuffer.bytesPending]) + { + *c = *rxBuffer.ptr; + ++rxBuffer.ptr; + return WICONNECT_SUCCESS; + } + else + { + clearRxBuffer(); + goto read_data; + } +} + +/*************************************************************************************************/ +void File::clearRxBuffer() +{ + rxBuffer.bytesPending = 0; + rxBuffer.ptr = rxBuffer.buffer; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/types/FileList.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,125 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + + +#include "Wiconnect.h" +#include "types/FileList.h" + + + +/*************************************************************************************************/ +FileList::FileList(int bufferLen_, void *buffer_) +{ + count = 0; + listHead = listTail = NULL; + buffer = (uint8_t*)buffer_; + bufferPtr = buffer; + bufferLen = bufferLen_; +} + +/*************************************************************************************************/ +FileList::~FileList() +{ + if(buffer == NULL) + { + File* result = listHead; + while(result != NULL) + { + File* tmp = result; + result = result->next; + delete tmp; + } + } +} + +/*************************************************************************************************/ +WiconnectResult FileList::add(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr) +{ + WiconnectResult result; + File *res; + + if(buffer == NULL) + { + res = new File(); + if(res == NULL) + { + return WICONNECT_NULL_BUFFER; + } + } + else + { + if(bufferLen < sizeof(File)) + { + return WICONNECT_OVERFLOW; + } + res = (File*)bufferPtr; + memset(res, 0, sizeof(File)); + bufferLen -= sizeof(File); + bufferPtr += sizeof(File); + } + + if(WICONNECT_FAILED(result, res->initWithListing(typeStr, flagsStr, sizeStr, versionStr, nameStr))) + { + if(buffer == NULL) + { + delete res; + } + } + else + { + if(listHead == NULL) + { + listHead = listTail = res; + } + else + { + res->previous = listTail; + listTail->next = res; + listTail = res; + } + ++count; + } + + return result; +} + +/*************************************************************************************************/ +const File* FileList::getListHead() const +{ + return listHead; +} + +/*************************************************************************************************/ +int FileList::getCount() const +{ + return count; +} + +/*************************************************************************************************/ +const File* FileList::getResult(int i) const +{ + if(i >= count) + return NULL; + + File* result = listHead; + while(i-- != 0) + result = result->next; + + return result; +} + +/*************************************************************************************************/ +const File* FileList::operator [](int i) const +{ + return getResult(i); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/types/QueuedCommand.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,171 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include <assert.h> + +#include "Wiconnect.h" + + +/*************************************************************************************************/ +QueuedCommand::QueuedCommand(int responseBufferLen_, char *responseBuffer_, int timeoutMs_, const ReaderFunc &reader_, void *user_, const char *cmd_, va_list vaList) +{ + initialize(responseBufferLen_, responseBuffer_, timeoutMs_, reader_, user_, cmd_, vaList); +} + +/*************************************************************************************************/ +QueuedCommand::QueuedCommand(int responseBufferLen_, char* responseBuffer_, int timeoutMs_, const char *cmd_, ...) +{ + va_list args; + va_start(args, cmd_); + initialize(responseBufferLen_, responseBuffer_, timeoutMs_, NULL, NULL, cmd_, args); + va_end(args); +} + +/*************************************************************************************************/ +QueuedCommand::QueuedCommand(int responseBufferLen_, char *responseBuffer_, const char *cmd_, ...) +{ + va_list args; + va_start(args, cmd_); + initialize(responseBufferLen_, responseBuffer_, WICONNECT_DEFAULT_TIMEOUT, NULL, NULL, cmd_, args); + va_end(args); +} + +/*************************************************************************************************/ +QueuedCommand::QueuedCommand(int timeoutMs_, const char *cmd_, ...) +{ + va_list args; + va_start(args, cmd_); + initialize(0, NULL, timeoutMs_, NULL, NULL, cmd_, args); + va_end(args); +} + +/*************************************************************************************************/ +QueuedCommand::QueuedCommand(const char *cmd_, ...) +{ + va_list args; + va_start(args, cmd_); + initialize(0, NULL, WICONNECT_DEFAULT_TIMEOUT, NULL, NULL, cmd_, args); + va_end(args); +} + +/*************************************************************************************************/ +QueuedCommand::~QueuedCommand() +{ +#ifdef WICONNECT_ENABLE_MALLOC + if(allocatedBuffer) + { + Wiconnect::getInstance()->_free(responseBuffer); + } +#endif +} + +/*************************************************************************************************/ +char *QueuedCommand::getResponseBuffer() +{ + return responseBuffer; +} +/*************************************************************************************************/ +int QueuedCommand::getResponseBufferLen() +{ + return responseBufferLen; +} +/*************************************************************************************************/ +int QueuedCommand::getTimeoutMs() +{ + return timeoutMs; +} +/*************************************************************************************************/ +ReaderFunc QueuedCommand::getReader() +{ + return reader; +} +/*************************************************************************************************/ +void * QueuedCommand::getReaderUserData() +{ + return user; +} +/*************************************************************************************************/ +char* QueuedCommand::getCommand() +{ + return command; +} +/*************************************************************************************************/ +Callback QueuedCommand::getCompletedCallback() +{ + return completeCallback; +} +/*************************************************************************************************/ +void QueuedCommand::setCompletedCallback(const Callback &cb) +{ + completeCallback = cb; +} + +/*************************************************************************************************/ +QueuedCommand& QueuedCommand::operator=( const QueuedCommand& other ) +{ + responseBuffer = other.responseBuffer; + responseBufferLen = other.responseBufferLen; + timeoutMs = other.timeoutMs; + reader = other.reader; + user = other.user; + completeCallback = other.completeCallback; + memcpy(command, other.command, sizeof(command)); + return *this; +} + +/*************************************************************************************************/ +void* QueuedCommand::operator new(size_t size) +{ + assert(Wiconnect::getInstance()->_malloc != NULL); + return Wiconnect::getInstance()->_malloc(size); +} + +/*************************************************************************************************/ +void QueuedCommand::operator delete(void* ptr) +{ + assert(Wiconnect::getInstance()->_free != NULL); + Wiconnect::getInstance()->_free(ptr); +} + +/*************************************************************************************************/ +void QueuedCommand::initialize(int responseBufferLen_, char *responseBuffer_, int timeoutMs_, const ReaderFunc &reader_, void *user_, const char *cmd_, va_list vaList) +{ + if(responseBufferLen_ > 0) + { +#ifdef WICONNECT_ENABLE_MALLOC + allocatedBuffer = false; + if(responseBuffer_ == NULL) + { + assert(Wiconnect::getInstance()->_malloc != NULL); + responseBuffer = (char*)Wiconnect::getInstance()->_malloc(responseBufferLen_); + allocatedBuffer = true; + } + else +#endif + { + assert(responseBuffer_ != NULL); + responseBuffer = responseBuffer_; + } + } + responseBufferLen = responseBufferLen_; + timeoutMs = timeoutMs_; + reader = reader_; + user = user_; + userData = NULL; + + if(cmd_ != NULL) + { + int len = vsnprintf(command, sizeof(command)-3, cmd_, vaList); + command[len++] = '\r'; + command[len++] = '\n'; + command[len] = 0; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/types/ScanResult.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,167 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include <assert.h> + +#include "Wiconnect.h" +#include "types/ScanResult.h" +#include "NetworkInterface.h" +#include "internal/common.h" + + +static inline bool floatToFixedPointInt(const char *str, uint32_t *res); + + + +/*************************************************************************************************/ +ScanResult::ScanResult() +{ + next = NULL; + previous = NULL; + channel = 0xff; + rssi = -9999; + rate = 0; + security = NETWORK_SECURITY_UNKNOWN; + memset(&mac, 0, (uint32_t)sizeof(mac)); + memset(&ssid, 0, (uint32_t)sizeof(ssid)); +} + +/*************************************************************************************************/ +WiconnectResult ScanResult::init(const char *channelStr, const char *rssiStr, const char* macStr, const char *rateStr, const char *secStr, const char *ssidStr) +{ + intmax_t r; + if(!StringUtil::parseInt(channelStr, &r, 0, 15)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + channel = (int)r; + if(!StringUtil::parseInt(rssiStr, &r, -200, 100)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + rssi = (int)r; + + if(!Wiconnect::strToMacAddress(macStr, &mac)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + + if(!floatToFixedPointInt(rateStr, &rate)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + security = Wiconnect::strToNetworkSecurity(secStr); + + if(!Wiconnect::strToSsid(ssidStr, &ssid)) + { + return WICONNECT_RESPONSE_PARSE_ERROR; + } + + return WICONNECT_SUCCESS; +} + +/*************************************************************************************************/ +void* ScanResult::operator new(size_t size) +{ + assert(Wiconnect::getInstance()->_malloc != NULL); + return Wiconnect::getInstance()->_malloc(size); +} + +/*************************************************************************************************/ +void ScanResult::operator delete(void* ptr) +{ + assert(Wiconnect::getInstance()->_free != NULL); + Wiconnect::getInstance()->_free(ptr); +} + +/*************************************************************************************************/ +uint8_t ScanResult::getChannel() const +{ + return channel; +} +/*************************************************************************************************/ +NetworkSignalStrength ScanResult::getSignalStrength() const +{ + return Wiconnect::rssiToSignalStrength(rssi); +} +/*************************************************************************************************/ +const MacAddress* ScanResult::getMacAddress() const +{ + return &mac; +} +/*************************************************************************************************/ +uint32_t ScanResult::getRate() const +{ + return rate; +} +/*************************************************************************************************/ +const char* ScanResult::getRateStr(char *buffer) const +{ + SET_STR_BUFFER(buffer, 16); + uint32_t i = rate / 10; + uint32_t f = rate % 10; + sprintf(ptr, "%u.%u", i, f); + return ptr; +} +/*************************************************************************************************/ +NetworkSecurity ScanResult::getSecurityType() const +{ + return security; +} +/*************************************************************************************************/ +const Ssid* ScanResult::getSsid() const +{ + return &ssid; +} + +/*************************************************************************************************/ +const ScanResult* ScanResult::getNext() const +{ + return next; +} + +/*************************************************************************************************/ +const ScanResult* ScanResult::getPrevious() const +{ + return previous; +} + + +/*************************************************************************************************/ +static inline bool floatToFixedPointInt(const char *str, uint32_t *res) +{ + intmax_t i; + intmax_t f = 0; + char buffer[32]; + + strcpy(buffer, str); + + char* frac = strchr(buffer, '.'); + if(frac != NULL) + { + *frac = 0; + ++frac; + } + + if(!StringUtil::parseInt(buffer, &i, 0, 1000)) + { + return false; + } + if(frac != NULL && !StringUtil::parseInt(frac, &f, 0, 9)) + { + return false; + } + + *res = (((uint32_t)i) * 10) + (uint32_t)f; + + return true; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/types/ScanResultList.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,129 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include <assert.h> +#include "Wiconnect.h" +#include "types/ScanResult.h" + + + +/*************************************************************************************************/ +ScanResultList::ScanResultList(int bufferLen_, void *buffer_) +{ + assert((bufferLen_ == 0 && buffer_ == NULL) || (bufferLen_ != 0 && buffer_ != NULL)); + count = 0; + listHead = listTail = NULL; + buffer = (uint8_t*)buffer_; + bufferPtr = buffer; + bufferLen = bufferLen_; +} + +/*************************************************************************************************/ +ScanResultList::~ScanResultList() +{ + if(buffer == NULL) + { + ScanResult* result = listHead; + while(result != NULL) + { + ScanResult* tmp = result; + result = result->next; + delete tmp; + } + } +} + +/*************************************************************************************************/ +WiconnectResult ScanResultList::add(const char *channelStr, const char *rssiStr, const char* macStr, const char *rateStr, const char *secStr, const char *ssidStr) +{ + WiconnectResult result; + ScanResult *res; + + if(buffer == NULL) + { + res = new ScanResult(); + if(res == NULL) + { + return WICONNECT_NULL_BUFFER; + } + } + else + { + if(bufferLen < sizeof(ScanResult)) + { + return WICONNECT_OVERFLOW; + } + res = (ScanResult*)bufferPtr; + memset(res, 0, sizeof(ScanResult)); + bufferLen -= sizeof(ScanResult); + bufferPtr += sizeof(ScanResult); + } + + if(WICONNECT_FAILED(result, res->init(channelStr, rssiStr, macStr, rateStr, secStr, ssidStr))) + { + if(buffer == NULL) + { + delete res; + } + } + else + { + if(listHead == NULL) + { + listHead = listTail = res; + } + else + { + res->previous = listTail; + listTail->next = res; + listTail = res; + } + ++count; + } + + return result; +} + +/*************************************************************************************************/ +const ScanResult* ScanResultList::getListHead() const +{ + return listHead; +} + +/*************************************************************************************************/ +int ScanResultList::getCount() const +{ + return count; +} + +/*************************************************************************************************/ +const ScanResult* ScanResultList::getResult(int i) const +{ + if(i >= count) + return NULL; + + ScanResult* result = listHead; + while(i-- != 0) + result = result->next; + + return result; +} + +/*************************************************************************************************/ +const ScanResult* ScanResultList::operator [](int i) const +{ + return getResult(i); +} + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/types/Socket.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,490 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include <assert.h> +#include <stdarg.h> +#include "Wiconnect.h" +#include "internal/common.h" +#include "StringUtil.h" + + +#define CHECK_CONNECTED() if(!isConnected()) return WICONNECT_NOT_CONNECTED + + +/*************************************************************************************************/ +Socket::Socket(int rxBufferLen_, void *rxBuffer_, int txBufferLen_, void *txBuffer_) +{ + wiconnect = Wiconnect::getInstance(); + + memset(&txBuffer, 0, sizeof(Buffer)); + memset(&rxBuffer, 0, sizeof(Buffer)); + + txBuffer.size = !wiconnect->nonBlocking ? txBufferLen_ : 0; + txBuffer.buffer = (uint8_t*)txBuffer_; + + rxBuffer.size = !wiconnect->nonBlocking ? rxBufferLen_ : 0; + rxBuffer.buffer = (uint8_t*)rxBuffer_; + + if(txBuffer.size > 0) + { + if(txBuffer_ == NULL) + { +#ifdef WICONNECT_ENABLE_MALLOC + assert(wiconnect->_malloc != NULL); + txBuffer.buffer = (uint8_t*)wiconnect->_malloc(txBufferLen_); + assert(txBuffer.buffer != NULL); + txBuffer.allocated = true; +#else + assert(0); +#endif + } + } + + if(rxBuffer.size > 0) + { + if(rxBuffer_ == NULL) + { +#ifdef WICONNECT_ENABLE_MALLOC + assert(wiconnect->_malloc != NULL); + rxBuffer.buffer = (uint8_t*)wiconnect->_malloc(rxBufferLen_); + assert(rxBuffer.buffer != NULL); + rxBuffer.allocated = true; +#else + assert(0); +#endif + } + } + + init(SOCKET_INVALID_HANDLE, SOCKET_TYPE_UNKNOWN, NULL, 0, 0); +} + + +/*************************************************************************************************/ +WiconnectResult Socket::init(uint8_t handle_, SocketType type_, const char *host_, uint16_t remotePort_, uint16_t localPort_) +{ + handle = handle_; + type = type_; + remotePort = remotePort_; + localPort = localPort_; + connected = true; + + txBuffer.ptr = txBuffer.buffer; + rxBuffer.ptr = rxBuffer.buffer; + + strncpy(host, host_, sizeof(host)-1); + + return WICONNECT_SUCCESS; +} + +/*************************************************************************************************/ +Socket::~Socket() +{ + while((handle != SOCKET_INVALID_HANDLE) && (close() == WICONNECT_PROCESSING)) + { + } + +#ifdef WICONNECT_ENABLE_MALLOC + if(txBuffer.allocated && txBuffer.size > 0) + { + assert(wiconnect->_free != NULL); + wiconnect->_free(txBuffer.buffer); + } + if(rxBuffer.allocated && rxBuffer.size > 0) + { + assert(wiconnect->_free != NULL); + wiconnect->_free(rxBuffer.buffer); + } +#endif +} + +/*************************************************************************************************/ +bool Socket::isConnected() +{ + return connected; +} + +/*************************************************************************************************/ +SocketType Socket::getType() +{ + return type; +} + +/*************************************************************************************************/ +const char* Socket::getHost() +{ + return host; +} + +/*************************************************************************************************/ +uint16_t Socket::getLocalPort() +{ + return localPort; +} + +/*************************************************************************************************/ +uint16_t Socket::getRemotePort() +{ + return remotePort; +} + +/*************************************************************************************************/ +uint8_t Socket::getHandle() +{ + return handle; +} + + +/*************************************************************************************************/ +WiconnectResult Socket::close() +{ + WiconnectResult result; + CHECK_CONNECTED(); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("close %d", handle))) + { + connected = false; + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::poll(bool *rxDataAvailablePtr) +{ + WiconnectResult result; + int32_t status; + + CHECK_CONNECTED(); + CHECK_OTHER_COMMAND_EXECUTING(); + + *rxDataAvailablePtr = false; + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("poll %d", handle))) + { + if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status))) + { + if(status == 2) + { + connected = false; + } + else if(status == 1) + { + *rxDataAvailablePtr = true; + } + } + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::write(int length, bool flush) +{ + CHECK_CONNECTED(); + + if( txBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + else if(length > txBuffer.size) + { + return WICONNECT_OVERFLOW; + } + txBuffer.bytesPending = length; + + return flush ? flushTxBuffer() : WICONNECT_SUCCESS; +} + +/*************************************************************************************************/ +WiconnectResult Socket::write(const void* buffer, int length, bool flush) +{ + WiconnectResult result = WICONNECT_SUCCESS; + CHECK_CONNECTED(); + + if(txBuffer.size > 0) + { + // NOTE: txBuffer only available in blocking mode (so no need to check if a cmd is executing) + + const uint8_t *src = (const uint8_t *)buffer; + + while(length > 0) + { + int bytesToWrite = MIN(length, txBuffer.size - txBuffer.bytesPending); + uint8_t *dst = (uint8_t*)&txBuffer.buffer[txBuffer.bytesPending]; + memcpy(dst, src, bytesToWrite); + txBuffer.bytesPending += bytesToWrite; + length -= bytesToWrite; + src += bytesToWrite; + + if((txBuffer.bytesPending >= txBuffer.size) && + WICONNECT_FAILED(result, flushTxBuffer())) + { + break; + } + } + + if(flush && txBuffer.bytesPending > 0) + { + result = flushTxBuffer(); + } + } + else + { + if(WICONNECT_IS_IDLE()) + { + txBuffer.ptr = (uint8_t*)buffer; + txBuffer.bytesPending = length; + } + + result = flushTxBuffer(); + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::read(void* buffer, uint16_t maxLength, uint16_t *bytesRead) +{ + WiconnectResult result; + + CHECK_CONNECTED(); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand((char*)buffer, maxLength, "read %d %d", handle, maxLength-2))) + { + *bytesRead = wiconnect->getLastCommandResponseLength(); + } + + CHECK_CLEANUP_COMMAND(); + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::read(uint8_t **bufferPtr, uint16_t *bytesReadPtr) +{ + WiconnectResult result = WICONNECT_SUCCESS; + + CHECK_CONNECTED(); + + if(rxBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + else if(bufferPtr != NULL && bytesReadPtr == NULL) + { + return WICONNECT_BAD_ARG; + } + else if(rxBuffer.bytesPending < rxBuffer.size - 2) + { + const int bytesToRead = rxBuffer.size - rxBuffer.bytesPending - 2; + char* ptr = (char*)&rxBuffer.buffer[rxBuffer.bytesPending]; + if(!WICONNECT_FAILED(result, wiconnect->sendCommand(ptr, bytesToRead+2, "read %d %d", handle, bytesToRead))) + { + rxBuffer.bytesPending += wiconnect->getLastCommandResponseLength(); + } + } + + if(bufferPtr != NULL) + { + *bufferPtr = rxBuffer.buffer; + *bytesReadPtr = rxBuffer.bytesPending; + clearRxBuffer(); + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::getc(uint8_t *c) +{ + WiconnectResult result; + + if(rxBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + + read_data: + if(rxBuffer.bytesPending == 0 && + WICONNECT_FAILED(result, read())) + { + return result; + } + else if(rxBuffer.ptr < &rxBuffer.buffer[rxBuffer.bytesPending]) + { + *c = *rxBuffer.ptr; + ++rxBuffer.ptr; + return WICONNECT_SUCCESS; + } + else + { + clearRxBuffer(); + goto read_data; + } +} + +/*************************************************************************************************/ +WiconnectResult Socket::putc(uint8_t c, bool flush) +{ + WiconnectResult result = WICONNECT_SUCCESS; + CHECK_CONNECTED(); + + if(txBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + else if(txBuffer.bytesPending < txBuffer.size) + { + uint8_t *ptr = (uint8_t*)&txBuffer.buffer[txBuffer.bytesPending]; + *ptr = c; + ++txBuffer.bytesPending; + + if(flush || txBuffer.bytesPending >= txBuffer.size) + { + result = flushTxBuffer(); + } + } + else + { + result = WICONNECT_OVERFLOW; + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::puts(const char *s, bool flush) +{ + const int len = strlen(s); + return write(s, len, flush); +} + +/*************************************************************************************************/ +WiconnectResult Socket::printf(const char* format, ...) +{ + WiconnectResult result = WICONNECT_SUCCESS; + + CHECK_CONNECTED(); + if(txBuffer.size == 0) + { + return WICONNECT_UNSUPPORTED; + } + + const int available = txBuffer.size - txBuffer.bytesPending; + char *ptr = (char*)&txBuffer.buffer[txBuffer.bytesPending]; + va_list args; + va_start(args, format); + const int len = vsnprintf(ptr, available, format, args); + if(len > available) + { + return WICONNECT_OVERFLOW; + } + else + { + txBuffer.bytesPending += len; + } + + if(txBuffer.bytesPending >= txBuffer.size) + { + result = flushTxBuffer(); + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult Socket::flushTxBuffer() +{ + WiconnectResult result = WICONNECT_SUCCESS; + + CHECK_CONNECTED(); + CHECK_OTHER_COMMAND_EXECUTING(); + + if(txBuffer.bytesPending > 0) + { + result = wiconnect->sendCommand(ReaderFunc(this, &Socket::writeDataCallback), NULL, "write %d %d", handle, txBuffer.bytesPending); + } + + CHECK_CLEANUP_COMMAND(); + + if(result != WICONNECT_PROCESSING) + { + txBuffer.ptr = txBuffer.buffer; + txBuffer.bytesPending = 0; + } + + return result; +} + +/*************************************************************************************************/ +void Socket::clearRxBuffer() +{ + rxBuffer.bytesPending = 0; + rxBuffer.ptr = rxBuffer.buffer; +} + +/*************************************************************************************************/ +uint8_t* Socket::getTxBuffer() +{ + return txBuffer.buffer; +} +/*************************************************************************************************/ +int Socket::getTxBufferSize() +{ + return txBuffer.size; +} +/*************************************************************************************************/ +int Socket::getTxBufferBytesPending() +{ + return txBuffer.bytesPending; +} +/*************************************************************************************************/ +uint8_t* Socket::getRxBuffer() +{ + return rxBuffer.buffer; +} +/*************************************************************************************************/ +int Socket::getRxBufferSize() +{ + return rxBuffer.size; +} +/*************************************************************************************************/ +int Socket::getRxBufferBytesPending() +{ + return rxBuffer.bytesPending; +} + + +/*************************************************************************************************/ +WiconnectResult Socket::writeDataCallback(void *user, void *data, int maxReadSize, int *bytesRead) +{ + if(txBuffer.bytesPending == 0) + { + *bytesRead = EOF; + } + else + { + int bytesToWrite = MIN(maxReadSize, txBuffer.bytesPending); + memcpy(data, txBuffer.ptr, bytesToWrite); + txBuffer.ptr += bytesToWrite; + txBuffer.bytesPending -= bytesToWrite; + *bytesRead = bytesToWrite; + } + + return WICONNECT_SUCCESS; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/wiconnect/AsyncCommand.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,100 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "CommandCommon.h" + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + + + +/*************************************************************************************************/ +WiconnectResult Wiconnect::enqueueCommand(QueuedCommand *command, const Callback &commandCompleteHandler) +{ + if(commandQueue.isFull()) + { + return WICONNECT_OVERFLOW; + } + command->setCompletedCallback(commandCompleteHandler); + DEBUG_INFO("Queuing command: %s", command->getCommand()); + commandQueue.push(command); + processNextQueuedCommand(); + return WICONNECT_SUCCESS; +} + +/*************************************************************************************************/ +void Wiconnect::processNextQueuedCommand() +{ + if(commandQueue.isEmpty()) + { + return; + } + else if(commandExecuting) + { + return; + } + + WiconnectResult result = WICONNECT_SUCCESS; + CommandContext *context = (CommandContext*)commandContext; + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + + commandExecuting = true; + currentQueuedCommand = commandQueue.pop(); + + DEBUG_INFO("Processing next cmd in queue"); + + strcpy(commandFormatBuffer, currentQueuedCommand->command); + + RESET_CMD_HEADER(header); + + memset(context, 0, sizeof(CommandContext)); + if(currentQueuedCommand->responseBufferLen > 0) + { + context->responseBuffer = currentQueuedCommand->responseBuffer; + context->responseBufferLen = currentQueuedCommand->responseBufferLen; + } + else + { + context->responseBuffer = internalBuffer; + context->responseBufferLen = internalBufferSize; + } + + context->responseBufferPtr = context->responseBuffer; + context->commandLen = strlen(commandFormatBuffer); + context->commandPtr = commandFormatBuffer; + context->reader = currentQueuedCommand->reader; + context->user = currentQueuedCommand->userData; + context->timeoutMs = currentQueuedCommand->timeoutMs; + context->callback = currentQueuedCommand->completeCallback; + context->nonBlocking = true; + + DEBUG_CMD_SEND(commandFormatBuffer); + + commandExecuting = true; + timeoutTimer.reset(); + + commandProcessorTimer.start(this, &Wiconnect::commandProcessingTimerHandler, commandProcessingPeriod); +} + +/*************************************************************************************************/ +void Wiconnect::setCommandProcessingPeriod(uint32_t periodMs) +{ + commandProcessingPeriod = periodMs; +} + +/*************************************************************************************************/ +void Wiconnect::commandProcessingTimerHandler() +{ + checkCurrentCommand(); +} + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/wiconnect/CommandCommon.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include <stdio.h> +#include <stdarg.h> +#include "Wiconnect.h" +#include "internal/common.h" +#include "StringUtil.h" + + + +#define CHECK_NULL_BUFFER(buf) if(buf == NULL) return WICONNECT_NULL_BUFFER +#define CHECK_INITIALIZED() if(!initialized) return WICONNECT_NOT_INITIALIZED +#define RESET_CMD_HEADER(header) memset(header, 0, sizeof(CommandHeader)); header->bytes_remaining = WICONNECT_HEADER_LENGTH + +#define DEBUG_CMD_SEND(cmd) debugLog(">> CMD: %s", cmd) +#define DEBUG_CMD_LOG(res) debugLog("<< LOG: %s", res) +#define DEBUG_CMD_RESPONSE(res) debugLog("<< RES: %s", res) +#define DEBUG_CMD_ERROR(code) debugLog("<< ERR:(%d) %s", code, getLastCommandResponseCodeStr()) +#define DEBUG_ERROR(msg, ...) debugLog(" ERR: " msg, ## __VA_ARGS__) +#define DEBUG_INFO(msg, ...) debugLog(" DBG: " msg, ## __VA_ARGS__) + + + +typedef enum +{ + WICONNECT_CMD_TYPE_NULL = 0, + WICONNECT_CMD_TYPE_REPLY = 'R', + WICONNECT_CMD_TYPE_LOG = 'L', + WICONNECT_CMD_TYPE_SAFEMODE = 'S' +} ResponseType; + +typedef enum +{ + WICONNECT_CMD_CODE_NULL = 0, + WICONNECT_CMD_SUCCESS = 1, // The command was successful + WICONNECT_CMD_FAILED = 2, // The command failed, most likely in the firmware + WICONNECT_CMD_PARSE_ERROR = 3, // Failed to parse the command + WICONNECT_CMD_UNKNOWN = 4, // Unknown command + WICONNECT_CMD_TOO_FEW_ARGS = 5, // Not enough command arguments + WICONNECT_CMD_TOO_MANY_ARGS = 6, // Too many command arguments + WICONNECT_CMD_UNKNOWN_OPTION = 7, // Unknown option (e.g. known 'set' command option) + WICONNECT_CMD_BAD_ARGS = 8, // Invalid command arguments +} ResponseCode; + +#define WICONNECT_HEADER_LENGTH 9 +typedef struct +{ + ResponseType response_type; + ResponseCode response_code; + uint16_t response_len; + uint8_t len_buffer[WICONNECT_HEADER_LENGTH]; + uint8_t *len_buffer_ptr; + uint8_t bytes_remaining; +} CommandHeader; + +typedef struct +{ + char *responseBuffer; + char *responseBufferPtr; + int responseBufferLen; + ReaderFunc reader; + void *user; + char *commandPtr; + int commandLen; + int bytesToWrite; + int bytesToRead; + int timeoutMs; + Callback callback; + bool nonBlocking; +} CommandContext; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/wiconnect/ProcessCommand.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,319 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "CommandCommon.h" + + + +/*************************************************************************************************/ +WiconnectResult Wiconnect::checkCurrentCommand() +{ + WiconnectResult result; + + start: + CHECK_INITIALIZED(); + if(!commandExecuting) + { + return WICONNECT_IDLE; + } + + CommandContext *context = (CommandContext*)commandContext; + + if(context->commandLen > 0) + { + const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); + const int bytesToWrite = context->commandLen; + const int bytesWritten = serial.write(context->commandPtr, bytesToWrite, timeout); + context->commandPtr += bytesWritten; + context->commandLen -= bytesWritten; + if(bytesToWrite != bytesWritten) + { + if(timeoutTimer.timedOut(context->timeoutMs)) + { + issueCommandCallback(WICONNECT_TIMEOUT); + return WICONNECT_TIMEOUT; + } + else + { + return WICONNECT_PROCESSING; + } + } + } + + while(context->reader.isValid()) + { + if(context->bytesToWrite == 0) + { + context->responseBufferPtr = context->responseBuffer; + if(WICONNECT_FAILED(result, context->reader.call(context->user, context->responseBuffer, context->responseBufferLen, &context->bytesToWrite))) + { + issueCommandCallback(result); + return result; + } + else if(context->bytesToWrite == EOF) + { + context->reader.setInvalid(); + context->bytesToWrite = 0; + context->responseBufferPtr = context->responseBuffer; + break; + } + else + { + timeoutTimer.reset(); + } + } + if(context->bytesToWrite > 0) + { + const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); + const int bytesToWrite = context->bytesToWrite; + const int bytesWritten = serial.write(context->responseBufferPtr, bytesToWrite, timeout); + context->responseBufferPtr += bytesWritten; + context->bytesToWrite -= bytesWritten; + if(bytesToWrite != bytesWritten) + { + if(timeoutTimer.timedOut(context->timeoutMs)) + { + issueCommandCallback(WICONNECT_TIMEOUT); + return WICONNECT_TIMEOUT; + } + else + { + return WICONNECT_PROCESSING; + } + } + } + } + + result = receiveResponse(); + if(result == WICONNECT_PROCESSING && !context->nonBlocking) + { + goto start; + } + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::receiveResponse() +{ + for(;;) + { + WiconnectResult result = receivePacket(); + + if(result == WICONNECT_PROCESSING) + { + return WICONNECT_PROCESSING; + } + else if(result == WICONNECT_SUCCESS) + { + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + CommandContext *context = (CommandContext*)commandContext; + + // TODO: need to notify safemode + + if(header->response_type == WICONNECT_CMD_TYPE_REPLY || header->response_type == WICONNECT_CMD_TYPE_SAFEMODE) + { + if(header->response_code != WICONNECT_CMD_SUCCESS) + { + DEBUG_CMD_ERROR(header->response_code); + flush(); + issueCommandCallback(WICONNECT_CMD_RESPONSE_ERROR); + return WICONNECT_CMD_RESPONSE_ERROR; + } + else if(header->response_len > 0) + { + DEBUG_CMD_RESPONSE(context->responseBuffer); + header->response_len -= 2; + context->responseBuffer[header->response_len] = 0; + } + else + { + *context->responseBuffer = 0; + } + + issueCommandCallback(WICONNECT_SUCCESS); + + return WICONNECT_SUCCESS; + } + else + { + DEBUG_CMD_LOG(context->responseBuffer); + RESET_CMD_HEADER(header); + context->responseBufferPtr = context->responseBuffer; + } + } + else + { + issueCommandCallback(result); + return result; + } + } + + // shouldn't get here... + return WICONNECT_ERROR; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::receivePacket() +{ + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + CommandContext *context = (CommandContext*)commandContext; + + if(header->bytes_remaining > 0) + { + uint16_t bytesReceived; + uint8_t buffer[WICONNECT_HEADER_LENGTH]; + + while(header->bytes_remaining > 0) + { + const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); + bytesReceived = serial.read((char*)buffer, header->bytes_remaining, timeout); + if(bytesReceived == 0) + { + return timeoutTimer.timedOut(context->timeoutMs) ? WICONNECT_TIMEOUT : WICONNECT_PROCESSING; + } + + for(uint8_t *ptr = buffer; bytesReceived > 0; ++ptr) + { + if(header->response_type == WICONNECT_CMD_TYPE_NULL) + { + if( *ptr == WICONNECT_CMD_TYPE_REPLY || + *ptr == WICONNECT_CMD_TYPE_LOG || + *ptr == WICONNECT_CMD_TYPE_SAFEMODE) + { + header->response_type = (ResponseType)*ptr; + -- header->bytes_remaining; + } + --bytesReceived; + } + else if(header->response_code == WICONNECT_CMD_CODE_NULL) + { + if(*ptr >= '0' && *ptr <= '7') + { + header->response_code = (ResponseCode)(*ptr - '0' + 1); + --header->bytes_remaining; + header->len_buffer_ptr = header->len_buffer; + } + else + { + RESET_CMD_HEADER(header); + } + --bytesReceived; + } + else if(header->bytes_remaining > 2) + { + uint8_t len_chars = MIN((int)bytesReceived, (int)(header->bytes_remaining-2)); + header->bytes_remaining -= len_chars; + bytesReceived -= len_chars; + while(len_chars-- > 0) + { + *header->len_buffer_ptr++ = *ptr++; + } + --ptr; // need to decrement since the for loop increments + if(header->bytes_remaining == 2) + { + uint32_t packetLen; + *header->len_buffer_ptr = 0; + if(!StringUtil::strToUint32((const char*)header->len_buffer, &packetLen)) + { + RESET_CMD_HEADER(header); + } + else + { + if((int)packetLen > context->responseBufferLen) + { + DEBUG_ERROR("Packet larger than response buffer: %d > %d", packetLen, context->responseBufferLen); + return WICONNECT_OVERFLOW; + } + header->response_len = (uint16_t)packetLen; + context->bytesToRead = packetLen; + } + } + } + else if(header->bytes_remaining == 2) + { + --bytesReceived; + if(*ptr == '\r') + { + header->bytes_remaining = 1; + } + else + { + RESET_CMD_HEADER(header); + } + } + else + { + --bytesReceived; + if(*ptr == '\n') + { + header->bytes_remaining = 0; + break; + } + else + { + RESET_CMD_HEADER(header); + } + } + } + } + } + + while(context->bytesToRead > 0) + { + const int timeout = context->nonBlocking ? 0 : timeoutTimer.remainingMs(context->timeoutMs); + const int bytesToRead = context->bytesToRead; + const int bytesReceived = serial.read(context->responseBufferPtr, bytesToRead, timeout); + context->responseBufferPtr += bytesReceived; + context->bytesToRead -= bytesReceived; + + if(bytesReceived != bytesToRead) + { + return timeoutTimer.timedOut(context->timeoutMs) ? WICONNECT_TIMEOUT : WICONNECT_PROCESSING; + } + else if(context->bytesToRead == 0) + { + *context->responseBufferPtr = 0; + } + } + + return (header->response_code != WICONNECT_CMD_CODE_NULL && + header->response_type != WICONNECT_CMD_TYPE_NULL && + context->bytesToRead == 0) ? WICONNECT_SUCCESS : WICONNECT_PROCESSING; +} + +/*************************************************************************************************/ +void Wiconnect::issueCommandCallback(WiconnectResult result) +{ + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + CommandContext *context = (CommandContext*)commandContext; +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + void *returnPtr = (currentQueuedCommand != NULL) ? (void*)currentQueuedCommand : (void*)context->responseBuffer; + currentQueuedCommand = NULL; + commandProcessorTimer.stop(); +#else + void *returnPtr = (void*)context->responseBuffer; +#endif + context->callback.call(result, returnPtr, (void*)(uint32_t)header->response_len); + commandExecuting = false; + +#ifdef WICONNECT_ASYNC_TIMER_ENABLED + processNextQueuedCommand(); +#endif +} + +/*************************************************************************************************/ +void Wiconnect::stopCurrentCommand() +{ + internalProcessingState = 0; + issueCommandCallback(WICONNECT_ABORTED); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/wiconnect/SendCommand.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,193 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "CommandCommon.h" + + + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const Callback &completeCallback, char *responseBuffer, + int responseBufferLen, int timeoutMs, const ReaderFunc &reader, void *user, + const char *cmd, va_list vaList) +{ + // preprocessor assertion + ct_assert(sizeof(commandContext) >=sizeof(CommandContext)); + CHECK_INITIALIZED(); + CHECK_NULL_BUFFER(responseBuffer); + if(commandExecuting) + { + return checkCurrentCommand(); + } + + CommandContext *context = (CommandContext*)commandContext; + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + + int len = vsnprintf(commandFormatBuffer, sizeof(commandFormatBuffer)-3, cmd, vaList); + + if(len > (int)(sizeof(commandFormatBuffer)-3)) + { + DEBUG_ERROR("Command overflowed: %d > %d", len, sizeof(commandFormatBuffer)-3); + return WICONNECT_OVERFLOW; + } + + commandFormatBuffer[len++] = '\r'; + commandFormatBuffer[len++] = '\n'; + commandFormatBuffer[len] = 0; + + RESET_CMD_HEADER(header); + + memset(context, 0, sizeof(CommandContext)); + context->responseBuffer = responseBuffer; + context->responseBufferPtr = context->responseBuffer; + context->responseBufferLen = responseBufferLen; + context->commandLen = len; + context->commandPtr = commandFormatBuffer; + context->reader = reader; + context->user = user; + context->timeoutMs = timeoutMs; + context->callback = completeCallback; + context->nonBlocking = nonBlocking; + + DEBUG_CMD_SEND(commandFormatBuffer); + + commandExecuting = true; + flush(0); + timeoutTimer.reset(); + + return checkCurrentCommand(); +} + + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(char *responseBuffer, int responseBufferLen, int timeoutMs, + const ReaderFunc &reader, void *user, const char *cmd, va_list vaList) +{ + return sendCommand(Callback(), responseBuffer, responseBufferLen, timeoutMs, reader, user, cmd, vaList); +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(char *responseBuffer, int responseBufferLen, int timeoutMs, + const ReaderFunc &reader, void *user, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), responseBuffer, responseBufferLen, timeoutMs, reader, user, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand( int timeoutMs, const ReaderFunc &reader, void *user, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), internalBuffer, internalBufferSize, timeoutMs, reader, user, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const ReaderFunc &reader, void *user, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), internalBuffer, internalBufferSize, defaultTimeoutMs, reader, user, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(char *responseBuffer, int responseBufferLen, int timeoutMs, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), responseBuffer, responseBufferLen, timeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const Callback &completeCallback, char *responseBuffer, int responseBufferLen, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(completeCallback, responseBuffer, responseBufferLen, defaultTimeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(char *responseBuffer, int responseBufferLen, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), responseBuffer, responseBufferLen, defaultTimeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const Callback &completeCallback, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(completeCallback, internalBuffer, internalBufferSize, defaultTimeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), internalBuffer, internalBufferSize, defaultTimeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const Callback &completeCallback, int timeoutMs, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(completeCallback, internalBuffer, internalBufferSize, timeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(int timeoutMs, const char *cmd, ...) +{ + WiconnectResult result; + va_list args; + va_start(args, cmd); + result = sendCommand(Callback(), internalBuffer, internalBufferSize, timeoutMs, ReaderFunc(), NULL, cmd, args); + va_end(args); + return result; +} + +/*************************************************************************************************/ +WiconnectResult Wiconnect::sendCommand(const char *cmd, va_list vaList) +{ + return sendCommand(Callback(), internalBuffer, internalBufferSize, defaultTimeoutMs, ReaderFunc(), NULL, cmd, vaList); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/wiconnect/Wiconnect.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,297 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <assert.h> + +#include "WiconnectInterface.h" +#include "internal/common.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) + { + assert(_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, void *internalBuffer, int internalBufferSize, Pin reset, Pin wake, bool nonBlocking MALLOC_ARGS) : + NetworkInterface(this), SocketInterface(this), FileInterface(this), serial(serialConfig, this), resetGpio(reset), wakeGpio(wake) MALLOC_CONSTRUCTORS +{ + prepare(internalBuffer, internalBufferSize, nonBlocking); +} + +/*************************************************************************************************/ +Wiconnect::Wiconnect(const SerialConfig &serialConfig, Pin reset, Pin wake, bool nonBlocking MALLOC_ARGS) : + NetworkInterface(this), SocketInterface(this), FileInterface(this), serial(serialConfig, this), resetGpio(reset), wakeGpio(wake) MALLOC_CONSTRUCTORS +{ + 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 savedNonBlocking = nonBlocking; + + if(WICONNECT_FAILED(result, reset())) + { + return result; + } + + delayMs(1000); + + initialized = true; + nonBlocking = false; + + for(retries = 3; retries > 0; --retries) + { + result = sendCommand(CMD_SET_SYSTEM_COMMAND_MODE, "machine"); + if(result != WICONNECT_SUCCESS) + { + delayMs(1000); + } + else + { + break; + } + } + + 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) +{ + if(versionBuffer != NULL && versionBufferSize == 0) + { + return WICONNECT_BAD_ARG; + } + return sendCommand(completeCallback, versionBuffer, versionBufferSize, CMD_GET_VERSION); +} + +/*************************************************************************************************/ +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 + }; + + if((int)wiconnectResult >= (int)WICONNECT_SUCCESS) + { + return wiconnectSuccessStrTable[wiconnectResult]; + } + else + { + wiconnectResult = (WiconnectResult)(-((int)wiconnectResult)); + return wiconnectErrorStrTable[wiconnectResult]; + } +} + + +/*************************************************************************************************/ +void Wiconnect::setDebugLogger(LogFunc logFunc) +{ + debugLogger = logFunc; +} + +/*************************************************************************************************/ +void Wiconnect::debugLog(const char *msg, ...) +{ + if(!debugLogger.isValid()) + { + return; + } + + char buffer[96]; + va_list args; + va_start(args, msg); + int len = vsnprintf(buffer, sizeof(buffer), 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); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/internal/wiconnect/WiconnectCommand.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "CommandCommon.h" +#include "StringUtil.h" + + + +/*************************************************************************************************/ +void Wiconnect::setCommandDefaultTimeout(int timeoutMs) +{ + defaultTimeoutMs = timeoutMs; +} + +/*************************************************************************************************/ +int Wiconnect::getCommandDefaultTimeout() +{ + return defaultTimeoutMs; +} + +/*************************************************************************************************/ +char* Wiconnect::getResponseBuffer() +{ + return internalBuffer; +} + +/*************************************************************************************************/ +uint16_t Wiconnect::getLastCommandResponseLength() +{ + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + return header->response_len; +} + +/*************************************************************************************************/ +const char* Wiconnect::getLastCommandResponseCodeStr() +{ + if(!initialized) + { + return NULL; + } + static const char* const response_error_strings[] ={ + "Null", + "Success", + "Failed", + "Parse error", + "Unknown command", + "Too few arguments", + "Too many arguments", + "Unknown command option", + "Bad command arguments" + }; + CommandHeader *header = (CommandHeader*)commandHeaderBuffer; + + return response_error_strings[header->response_code]; +} + + +/*************************************************************************************************/ +WiconnectResult Wiconnect::responseToUint32(uint32_t *uint32Ptr) +{ + CHECK_INITIALIZED(); + return StringUtil::strToUint32(internalBuffer, uint32Ptr) ? WICONNECT_SUCCESS : WICONNECT_RESPONSE_PARSE_ERROR; +} + + +/*************************************************************************************************/ +WiconnectResult Wiconnect::responseToInt32(int32_t *int32Ptr) +{ + CHECK_INITIALIZED(); + return StringUtil::strToInt32(internalBuffer, int32Ptr) ? WICONNECT_SUCCESS : WICONNECT_RESPONSE_PARSE_ERROR; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/mbed/Gpio.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,50 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "internal/common.h" + +#include "platform.h" +#include "gpio_api.h" + + + +/*************************************************************************************************/ +Gpio::Gpio(Pin pin) : DigitalOut(pin) +{ +} + +/*************************************************************************************************/ +void Gpio::write(bool value) +{ + gpio_write(&gpio, (int)value); +} + +/*************************************************************************************************/ +bool Gpio::read(void) +{ + const int v = gpio_read(&gpio); + return (bool)v; +} + +/*************************************************************************************************/ +Gpio& Gpio::operator= (bool value) +{ + write(value); + return *this; +} + +/*************************************************************************************************/ +Gpio& Gpio::operator= (const Gpio& other) +{ + memcpy((void*)&gpio, (void*)&other.gpio, sizeof(gpio)); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/mbed/PeriodicTimer.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "internal/common.h" + +#include "Ticker.h" + + +/*************************************************************************************************/ +PeriodicTimer::PeriodicTimer() +{ + running = false; +} + +/*************************************************************************************************/ +template<typename T> +void PeriodicTimer::start(T* tptr, void (T::*mptr)(void), int timeoutMs) +{ + attach_us(tptr, mptr, timeoutMs*1000); + running = true; +} +template void PeriodicTimer::start<Wiconnect>(Wiconnect* tptr, void (Wiconnect::*mptr)(void), int timeoutMs); +template void PeriodicTimer::start<NetworkInterface>(NetworkInterface* tptr, void (NetworkInterface::*mptr)(void), int timeoutMs); + +/*************************************************************************************************/ +void PeriodicTimer::stop(void) +{ + detach(); + running = false; +} + +/*************************************************************************************************/ +bool PeriodicTimer::isRunning() +{ + return running; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/mbed/PinIrqHandler.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,40 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + + +#include "Wiconnect.h" +#include "types/PinIrqHandler.h" + + + +/*************************************************************************************************/ +PinIrqHandler::PinIrqHandler(PinName irqPin_, const Callback &callback_) : InterruptIn(irqPin_) +{ + irqPin = irqPin_; + callback = callback_; + mode(PullDown); + rise(this, &PinIrqHandler::irqHandler); + enable_irq(); +} + +/*************************************************************************************************/ +PinIrqHandler::~PinIrqHandler() +{ + disable_irq(); +} + + +/*************************************************************************************************/ +void PinIrqHandler::irqHandler() +{ + callback.call(WICONNECT_SUCCESS, (void*)irqPin, NULL); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/mbed/TimeoutTimer.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,47 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + + +#include "Wiconnect.h" +#include "us_ticker_api.h" + +/*************************************************************************************************/ +TimeoutTimer::TimeoutTimer() +{ + _start = 0; + us_ticker_init(); +} + +/*************************************************************************************************/ +void TimeoutTimer::reset(void) +{ + _start = us_ticker_read(); +} + +/*************************************************************************************************/ +uint32_t TimeoutTimer::remainingMs(uint32_t timeoutMs) +{ + const uint32_t diff = readUs() / 1000; + return (timeoutMs > diff) ? timeoutMs - diff : 0; +} + +/*************************************************************************************************/ +uint32_t TimeoutTimer::readUs() +{ + return us_ticker_read() - _start; +} + +/*************************************************************************************************/ +bool TimeoutTimer::timedOut(uint32_t timeoutMs) +{ + timeoutMs *= 1000; + return (timeoutMs <= readUs()); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/mbed/WiconnectSerial.cpp Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,180 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#include <assert.h> + +#include "Wiconnect.h" +#include "internal/common.h" + +#ifndef WICONNECT_SERIAL_RX_BUFFER +#error WICONNECT_SERIAL_RX_BUFFER NOT defined NOT currently supported +#endif + + + + +typedef struct +{ + uint16_t size; + uint8_t *start, *end; + volatile uint8_t *head; + volatile uint8_t *tail; + volatile uint16_t count; +} SerialRxBuffer; + + +/*************************************************************************************************/ +WiconnectSerial::WiconnectSerial(const SerialConfig &config, Wiconnect *wiconnect) : RawSerial(config.tx, config.rx) +{ + ct_assert(sizeof(ringBuffer) >= sizeof(SerialRxBuffer)); + + baud(config.baud); + + SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; + memset(rxBuffer, 0, sizeof(SerialRxBuffer)); + bufferAlloc = false; + if(config.serialRxBufferSize > 0) + { + if(config.serialRxBuffer != NULL) + { + rxBuffer->head = (uint8_t*)config.serialRxBuffer; + } +#ifdef WICONNECT_ENABLE_MALLOC + else + { + assert(wiconnect->_malloc != NULL); + rxBuffer->start = (uint8_t*)wiconnect->_malloc(config.serialRxBufferSize); + bufferAlloc = true; + } +#endif + rxBuffer->head = rxBuffer->tail = (volatile uint8_t*)rxBuffer->start; + rxBuffer->end = (uint8_t*)rxBuffer->head + config.serialRxBufferSize; + rxBuffer->size = config.serialRxBufferSize; + attach(this, &WiconnectSerial::rxIrqHandler, SerialBase::RxIrq); + } +} + +/*************************************************************************************************/ +WiconnectSerial::~WiconnectSerial() +{ +#ifdef WICONNECT_ENABLE_MALLOC + if(bufferAlloc) + { + SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; + Wiconnect::getInstance()->_free(rxBuffer->start); + } +#endif +} + +/*************************************************************************************************/ +void WiconnectSerial::flush(void) +{ + while (readable()) + { + int c = getc(); + } + + SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; + rxBuffer->tail = rxBuffer->head = rxBuffer->start; + rxBuffer->count = 0; +} + +/*************************************************************************************************/ +int WiconnectSerial::write(const void *data, int bytesToWrite, int timeoutMs) +{ + uint8_t *ptr = (uint8_t*)data; + int remaining = bytesToWrite; + + while(remaining > 0) + { + if(!writeable()) + { + timeoutTimer.reset(); + while(!writeable()) + { + if(timeoutMs == 0) + { + if(timeoutTimer.readUs() >= 500) + { + goto exit; + } + } + else + { + if(timeoutTimer.readUs() >= timeoutMs*1000) + { + goto exit; + } + } + } + } + + putc(*ptr); + ++ptr; + --remaining; + } + + exit: + return bytesToWrite - remaining; +} + +/*************************************************************************************************/ +int WiconnectSerial::read(void *data, int bytesToRead, int timeoutMs) +{ + SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; + uint8_t *ptr = (uint8_t*)data; + int remaining = bytesToRead; + + while(remaining > 0) + { + if(rxBuffer->count == 0) + { + if(timeoutMs == 0) + { + break; + } + else + { + timeoutTimer.reset(); + while(rxBuffer->count == 0) + { + if(timeoutTimer.readUs() >= timeoutMs*1000) + { + goto exit; + } + } + } + } + + *ptr++ = *rxBuffer->tail++; + --remaining; + --rxBuffer->count; + if(rxBuffer->tail >= rxBuffer->end) + rxBuffer->tail = rxBuffer->start; + } + +exit: + return bytesToRead - remaining; +} + +/*************************************************************************************************/ +void WiconnectSerial::rxIrqHandler(void) +{ + SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; + + while (readable() && rxBuffer->count < rxBuffer->size) + { + *rxBuffer->head++ = (uint8_t)getc(); + ++rxBuffer->count; + if(rxBuffer->head >= rxBuffer->end) + rxBuffer->head = rxBuffer->start; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdk/mbed/sdk.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,96 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#define MBED_SDK + +#include "mbed.h" + +namespace wiconnect +{ + +#define WICONNECT_ASYNC_TIMER_ENABLED +#define WICONNECT_ENABLE_MALLOC +#define WICONNECT_SERIAL_RX_BUFFER +#define WICONNECT_USE_DEFAULT_STRING_BUFFERS + +#define WICONNECT_DEFAULT_MALLOC malloc +#define WICONNECT_DEFAULT_FREE free + +#define WICONNECT_DEFAULT_BAUD 115200 +#define WICONNECT_DEFAULT_TIMEOUT 3000 // ms +#define WICONNECT_MAX_QUEUED_COMMANDS 8 +#define WICONNECT_DEFAULT_COMMAND_PROCESSING_PERIOD 50 // ms + +#define WICONNECT_SOCKET_DEFAULT_RX_BUFFER_SIZE 256 +#define WICONNECT_SOCKET_DEFAULT_TX_BUFFER_SIZE 256 + +#define WICONNECT_DEFAULT_NONBLOCKING false + +#define WICONNECT_GPIO_BASE_CLASS : DigitalOut +#define WICONNECT_SERIAL_BASE_CLASS : RawSerial +#define WICONNECT_PERIODIC_TIMER_BASE_CLASS : Ticker +#define WICONNECT_EXTERNAL_INTERRUPT_GPIO_BASE_CLASS : InterruptIn + + +#define WICONNECT_MAX_PIN_IRQ_HANDLERS 3 +#define WICONNECT_MAX_HOST_SIZE 64 +#define WICONNECT_MAX_FILENAME_SIZE 96 + +#define PIN_NC NC + + +typedef PinName Pin; + +typedef struct _SerialConfig +{ + Pin rx; + Pin tx; + Pin cts; + Pin rts; + int baud; + void *serialRxBuffer; + int serialRxBufferSize; + + _SerialConfig(Pin rx, Pin tx, Pin cts, Pin rts, int baud = WICONNECT_DEFAULT_BAUD, void *serialRxBuffer = NULL, int serialRxBufferSize = 0) + { + this->rx =rx; + this->tx =tx; + this->cts =cts; + this->rts =rts; + this->baud = baud; + this->serialRxBuffer =serialRxBuffer; + this->serialRxBufferSize =serialRxBufferSize; + } + + _SerialConfig(Pin rx, Pin tx, int baud = WICONNECT_DEFAULT_BAUD) + { + this->rx =rx; + this->tx =tx; + this->cts =PIN_NC; + this->rts =PIN_NC; + this->baud = baud; + this->serialRxBuffer =NULL; + this->serialRxBufferSize =0; + } + +} SerialConfig; + + + +#define delayMs(ms) wait_ms(ms) + + + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/Callback.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "WiconnectTypes.h" +#include "FunctionPointer.h" + + + +namespace wiconnect +{ + + +typedef void (*_Callback)(WiconnectResult result, void *arg1, void *arg2); + +class Callback : public FunctionPointer +{ +public: + /*************************************************************************************************/ + Callback(_Callback func = 0) + { + _function = (void*)func; + _membercaller = NULL; + _object = NULL; + } + + /*************************************************************************************************/ + template<typename T> + Callback(T *object, void (T::*member)(WiconnectResult result, void *arg1, void *arg2)) + { + _object = static_cast<void*>(object); + memcpy(_member, (char*)&member, sizeof(member)); + _membercaller = (void*)&Callback::membercaller<T>; + _function = 0; + } + + /*************************************************************************************************/ + void call(WiconnectResult result, void *arg1, void *arg2) + { + if (_function) + { + ((_Callback)_function)(result, arg1, arg2); + } + else if (_object) + { + typedef void (*membercallerFunc)(void*, char*, WiconnectResult result, void *arg1, void *arg2); + ((membercallerFunc)_membercaller)(_object, _member, result, arg1, arg2); + } + } + +private: + + /*************************************************************************************************/ + template<typename T> + static void membercaller(void *object, char *member, WiconnectResult result, void *arg1, void *arg2) + { + T* o = static_cast<T*>(object); + void (T::*m)(WiconnectResult result, void *arg1, void *arg2); + memcpy((char*)&m, member, sizeof(m)); + (o->*m)(result, arg1, arg2); + } + +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/CommandQueue.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,86 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "WiconnectTypes.h" + + +namespace wiconnect +{ + + +class CommandQueue +{ +public: + /*************************************************************************************************/ + CommandQueue() + { + head = tail = queue; + count = 0; + } + + /*************************************************************************************************/ + bool isFull() + { + return count == WICONNECT_MAX_QUEUED_COMMANDS; + } + + /*************************************************************************************************/ + bool isEmpty() + { + return count == 0; + } + + /*************************************************************************************************/ + bool push(QueuedCommand *cmd) + { + if(isFull()) + { + return false; + } + ++count; + *tail = cmd; + if(++tail >= queue + WICONNECT_MAX_QUEUED_COMMANDS) + { + tail = queue; + } + + return true; + } + + /*************************************************************************************************/ + QueuedCommand* pop() + { + if(isEmpty()) + return NULL; + + QueuedCommand* cmd = *head; + --count; + if(++head >= queue + WICONNECT_MAX_QUEUED_COMMANDS) + { + head = queue; + } + return cmd; + } + +protected: + QueuedCommand* queue[WICONNECT_MAX_QUEUED_COMMANDS]; + QueuedCommand** head; + QueuedCommand** tail; + int count; +}; + + + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/File.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,67 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "Wiconnect.h" + +namespace wiconnect +{ + + +class File +{ +public: + File(int rxBufferLen = 0, void *rxBuffer = NULL); + ~File(); + + const char* getName() const; + uint32_t getSize() const; + FileType getType() const; + FileFlags getFlags() const; + uint32_t getVersion() const; + const char* getVersionStr(char *buffer = NULL) const; + + WiconnectResult close(); + WiconnectResult read(void* buffer, uint16_t maxLength, uint16_t *bytesRead); + WiconnectResult read(uint8_t **bufferPtr = NULL, uint16_t *bytesReadPtr = NULL); + WiconnectResult getc(uint8_t *c); + void clearRxBuffer(); + + const File* getNext() const; + const File* getPrevious() const; + +protected: + WiconnectResult openForRead(uint8_t handle, const char *filename); + WiconnectResult initWithListing(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr); + + uint8_t handle; + bool readEnabled; + char name[WICONNECT_MAX_FILENAME_SIZE]; + uint32_t size; + FileType type; + FileFlags flags; + uint32_t version; + Wiconnect *wiconnect; + File *next; + File *previous; + + Buffer rxBuffer; + + void* operator new(size_t size); + void operator delete(void*); + + friend class FileInterface; + friend class FileList; +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/FileList.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "Wiconnect.h" +#include "types/File.h" + +namespace wiconnect +{ + +class FileList +{ +public: + FileList(int bufferLen = 0, void *buffer = NULL); + ~FileList(); + + const File* getListHead() const; + int getCount() const; + const File* getResult(int i) const; + const File* operator [](int i) const; + +protected: + File *listHead, *listTail; + uint8_t *buffer; + uint8_t *bufferPtr; + int bufferLen; + int count; + + WiconnectResult add(const char *typeStr, const char *flagsStr, const char* sizeStr, const char *versionStr, const char *nameStr); + + friend class FileInterface; +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/FunctionPointer.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +namespace wiconnect +{ + +class FunctionPointer +{ +public: + /*************************************************************************************************/ + FunctionPointer& operator=( const FunctionPointer& other ) + { + _object = other._object; + _function = other._function; + _membercaller = other._membercaller; + memcpy(_member, other._member, sizeof(_member)); + return *this; + } + + /*************************************************************************************************/ + bool isValid() const + { + return (_function != NULL) || (_object != NULL); + } + + /*************************************************************************************************/ + void setInvalid() + { + _function = NULL; + _object = NULL; + } + +protected: + void *_object; + void *_function; + char _member[16]; + void *_membercaller; +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/Gpio.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "WiconnectTypes.h" + + +namespace wiconnect +{ + +class Gpio WICONNECT_GPIO_BASE_CLASS +{ +public: + Gpio(Pin pin); + + void write(bool value); + + bool read(void); + + Gpio& operator= (bool value); + + Gpio& operator= (const Gpio& other); + +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/LogFunc.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "WiconnectTypes.h" +#include "FunctionPointer.h" + +namespace wiconnect +{ + +typedef int (*_LogFunc)(const char *str); + +class LogFunc : public FunctionPointer +{ +public: + /*************************************************************************************************/ + LogFunc(_LogFunc func = 0) + { + _function = (void*)func; + _membercaller = NULL; + _object = NULL; + } + + /*************************************************************************************************/ + template<typename T> + LogFunc(T *object, WiconnectResult (T::*member)(const char *str)) + { + _object = static_cast<void*>(object); + memcpy(_member, (char*)&member, sizeof(member)); + _membercaller = (void*)&LogFunc::membercaller<T>; + _function = 0; + } + + /*************************************************************************************************/ + int call(const char *str) + { + if (_function) + { + return ((_LogFunc)_function)(str); + } + else if (_object) + { + typedef int (*membercallerFunc)(void*, char*, const char *str); + return ((membercallerFunc)_membercaller)(_object, _member, str); + } + else + { + return -1; + } + } + +private: + + /*************************************************************************************************/ + template<typename T> + static int membercaller(void *object, char *member, const char *str) + { + T* o = static_cast<T*>(object); + int (T::*m)(const char *str); + memcpy((char*)&m, member, sizeof(m)); + return (o->*m)(str); + } +}; + + + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/PeriodicTimer.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,34 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "WiconnectTypes.h" + + +namespace wiconnect +{ + +class PeriodicTimer WICONNECT_PERIODIC_TIMER_BASE_CLASS +{ +public: + PeriodicTimer(); + + template<typename T> + void start(T* tptr, void (T::*mptr)(void), int timeoutMs); + void stop(void); + bool isRunning(); +protected: + bool running; +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/PinIrqHandler.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + + + +namespace wiconnect +{ + + +class SocketIrqHandlerMap; + +class PinIrqHandler WICONNECT_EXTERNAL_INTERRUPT_GPIO_BASE_CLASS +{ +public: + PinIrqHandler(Pin irqPin, const Callback &callback); + //~PinIrqHandler(); + + void irqHandler(); + +protected: + PinName irqPin; + Callback callback; + + friend class SocketIrqHandlerMap; +}; + + +typedef uint8_t PinIrqHandlerBuffer[sizeof(PinIrqHandler)]; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/QueuedCommand.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "WiconnectTypes.h" + + +namespace wiconnect +{ + +class QueuedCommand +{ +public: + void *userData; + + + QueuedCommand(int responseBufferLen, char *responseBuffer, int timeoutMs, const ReaderFunc &reader, void *user, const char *cmd, va_list vaList); + QueuedCommand(int responseBufferLen, char *responseBuffer, int timeoutMs, const char *cmd, ...); + QueuedCommand(int responseBufferLen, char *responseBuffer, const char *cmd, ...); + QueuedCommand(int timeoutMs_, const char *cmd, ...); + QueuedCommand(const char *cmd, ...); + ~QueuedCommand(); + + char *getResponseBuffer(); + int getResponseBufferLen(); + int getTimeoutMs(); + ReaderFunc getReader(); + void * getReaderUserData(); + char* getCommand(); + Callback getCompletedCallback(); + void setCompletedCallback(const Callback &cb); + + QueuedCommand& operator=( const QueuedCommand& other ); + void* operator new(size_t size); + void operator delete(void*); + +protected: + char *responseBuffer; + int responseBufferLen; + int timeoutMs; + ReaderFunc reader; + void *user; + char command[WICONNECT_MAX_CMD_SIZE]; + Callback completeCallback; +#ifdef WICONNECT_ENABLE_MALLOC + bool allocatedBuffer; +#endif + friend class NetworkInterface; + friend class Wiconnect; + + void initialize(int responseBufferLen, char *responseBuffer_, int timeoutMs_, const ReaderFunc &reader_, void *user_, const char *cmd_, va_list vaList); +}; + + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/ReaderFunc.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "WiconnectTypes.h" +#include "FunctionPointer.h" + + +namespace wiconnect +{ + +typedef WiconnectResult (*_ReaderFunc)(void *user, void *data, int maxReadSize, int *bytesRead); + +class ReaderFunc : public FunctionPointer +{ +public: + + /*************************************************************************************************/ + ReaderFunc(_ReaderFunc func = 0) + { + _function = (void*)func; + _membercaller = NULL; + _object = NULL; + } + + /*************************************************************************************************/ + template<typename T> + ReaderFunc(T *object, WiconnectResult (T::*member)(void *user, void *data, int maxReadSize, int *bytesRead)) + { + _object = static_cast<void*>(object); + memcpy(_member, (char*)&member, sizeof(member)); + _membercaller = (void*)&ReaderFunc::membercaller<T>; + _function = 0; + } + + /*************************************************************************************************/ + WiconnectResult call(void *user, void *data, int maxReadSize, int *bytesRead) + { + if (_function) + { + return ((_ReaderFunc)_function)(user, data, maxReadSize, bytesRead); + } + else if (_object) + { + typedef WiconnectResult (*membercallerFunc)(void*, char*, void *user, void *data, int maxReadSize, int *bytesRead); + return ((membercallerFunc)_membercaller)(_object, _member, user, data, maxReadSize, bytesRead); + } + else + { + return WICONNECT_ERROR; + } + } + +private: + + /*************************************************************************************************/ + template<typename T> + static WiconnectResult membercaller(void *object, char *member, void *user, void *data, int maxReadSize, int *bytesRead) + { + T* o = static_cast<T*>(object); + WiconnectResult (T::*m)(void *user, void *data, int maxReadSize, int *bytesRead); + memcpy((char*)&m, member, sizeof(m)); + return (o->*m)(user, data, maxReadSize, bytesRead); + } +}; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/ScanResult.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + + +#include "WiconnectTypes.h" +#include "StringUtil.h" + + +namespace wiconnect +{ + + +class ScanResult +{ +public: + uint8_t getChannel() const; + NetworkSignalStrength getSignalStrength() const; + const MacAddress* getMacAddress() const; + NetworkSecurity getSecurityType() const; + uint32_t getRate() const; + const char* getRateStr(char *buffer = NULL) const; + const Ssid* getSsid() const; + + const ScanResult* getNext() const; + const ScanResult* getPrevious() const; + +protected: + ScanResult(); + + WiconnectResult init(const char *channelStr, const char *rssiStr, const char* macStr, const char *rateStr, const char *secStr, const char *ssidStr); + ScanResult *next; + ScanResult *previous; + uint8_t channel; + int16_t rssi; + MacAddress mac; + uint32_t rate; + NetworkSecurity security; + Ssid ssid; + + void* operator new(size_t size); + void operator delete(void*); + + friend class ScanResultList; +}; + + + + + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/ScanResultList.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "WiconnectTypes.h" +#include "types/ScanResult.h" + + + +namespace wiconnect +{ + + + +class ScanResultList +{ +public: + ScanResultList(int bufferLen = 0, void *buffer = NULL); + ~ScanResultList(); + + const ScanResult* getListHead() const; + int getCount() const; + const ScanResult* getResult(int i) const; + const ScanResult* operator [](int i) const; + +protected: + ScanResult *listHead, *listTail; + uint8_t *buffer; + uint8_t *bufferPtr; + int bufferLen; + int count; + + WiconnectResult add(const char *channelStr, const char *rssiStr, const char* macStr, const char *rateStr, const char *secStr, const char *ssidStr); + + + friend class NetworkInterface; +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/Socket.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +#include "WiconnectTypes.h" + +namespace wiconnect +{ + + +class Socket +{ +public: + Socket(int rxBufferLen = 0, void *rxBuffer = NULL, int txBufferLen = 0, void *txBuffer = NULL); + ~Socket(); + + WiconnectResult close(); + WiconnectResult poll(bool *rxDataAvailablePtr); + WiconnectResult write(const void* buffer, int length, bool flush = false); + WiconnectResult write(int length, bool flush = true); + WiconnectResult read(void* buffer, uint16_t maxLength, uint16_t *bytesRead); + WiconnectResult read(uint8_t **bufferPtr = NULL, uint16_t *bytesReadPtr = NULL); + WiconnectResult putc(uint8_t c, bool flush = false); + WiconnectResult puts(const char *s, bool flush = false); + WiconnectResult getc(uint8_t *c); + WiconnectResult printf(const char* format, ...); + WiconnectResult flushTxBuffer(); + void clearRxBuffer(); + + uint8_t *getTxBuffer(); + int getTxBufferSize(); + int getTxBufferBytesPending(); + uint8_t *getRxBuffer(); + int getRxBufferSize(); + int getRxBufferBytesPending(); + + bool isConnected(); + SocketType getType(); + const char* getHost(); + uint16_t getLocalPort(); + uint16_t getRemotePort(); + uint8_t getHandle(); + +protected: + bool connected; + SocketType type; + uint8_t handle; + char host[WICONNECT_MAX_HOST_SIZE]; + uint16_t localPort; + uint16_t remotePort; + Wiconnect *wiconnect; + Buffer txBuffer; + Buffer rxBuffer; + + WiconnectResult init(uint8_t handle, SocketType type, const char *host, uint16_t remotePort, uint16_t localPort); + + WiconnectResult writeDataCallback(void *user, void *data, int maxReadSize, int *bytesRead); + + friend class SocketInterface; +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/SocketIrqHandlerMap.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,106 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "Wiconnect.h" +#include "types/PinIrqHandler.h" + +namespace wiconnect +{ + +class SocketIrqHandlerMap +{ +public: + /*************************************************************************************************/ + SocketIrqHandlerMap() + { + memset(handlers, 0, sizeof(handlers)); + } + + /*************************************************************************************************/ + ~SocketIrqHandlerMap() + { + for(int i = 0; i < WICONNECT_MAX_PIN_IRQ_HANDLERS; ++i) + { + if(handlers[i] != NULL) + { + handlers[i]->~PinIrqHandler(); + } + } + } + + /*************************************************************************************************/ + bool pinIsRegistered(Pin pin) + { + for(int i = 0; i < WICONNECT_MAX_PIN_IRQ_HANDLERS; ++i) + { + if(handlers[i] != NULL && handlers[i]->irqPin == pin) + { + return true; + } + } + return false; + } + + /*************************************************************************************************/ + WiconnectResult registerHandler(Pin pin, const Callback &callback) + { + if(pinIsRegistered(pin)) + { + return WICONNECT_DUPLICATE; + } + + PinIrqHandler *handler = NULL; + + for(int i = 0; i < WICONNECT_MAX_PIN_IRQ_HANDLERS; ++i) + { + if(handlers[i] == NULL) + { + handler = (PinIrqHandler*)&handlerBuffers[i]; + handlers[i] = handler; + } + } + + if(handler == NULL) + { + return WICONNECT_NOT_FOUND; + } + + *handler = PinIrqHandler(pin, callback); + + return WICONNECT_SUCCESS; + } + + /*************************************************************************************************/ + WiconnectResult unregisterHandler(Pin pin) + { + for(int i = 0; i < WICONNECT_MAX_PIN_IRQ_HANDLERS; ++i) + { + if(handlers[i] != NULL && handlers[i]->irqPin == pin) + { + handlers[i]->~PinIrqHandler(); + handlers[i] = NULL; + return WICONNECT_SUCCESS; + } + } + + return WICONNECT_NOT_FOUND; + } + +private: + PinIrqHandler *handlers[WICONNECT_MAX_PIN_IRQ_HANDLERS]; + PinIrqHandlerBuffer handlerBuffers[WICONNECT_MAX_PIN_IRQ_HANDLERS]; +}; + + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/TimeoutTimer.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + + +namespace wiconnect +{ + +class TimeoutTimer +{ +public: + TimeoutTimer(); + + void reset(void); + + uint32_t remainingMs(uint32_t timeoutMs); + uint32_t readUs(); + + bool timedOut(uint32_t timeoutMs); + +protected: + uint32_t _start; + +}; + + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/types/WiconnectSerial.h Mon Aug 11 09:58:24 2014 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright 2014, ACKme Networks + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks; + * the contents of this file may not be disclosed to third parties, copied + * or duplicated in any form, in whole or in part, without the prior + * written permission of ACKme Networks. + */ + +#pragma once + +#include "WiconnectTypes.h" + + +namespace wiconnect +{ + +class WiconnectSerial WICONNECT_SERIAL_BASE_CLASS +{ +public: + WiconnectSerial(const SerialConfig &config, Wiconnect *wiconnect = NULL); + //~WiconnectSerial(); + + void flush(void); + int write(const void *data, int bytesToWrite, int timeoutMs); + int read(void *data, int bytesToRead, int timeoutMs); + +protected: + TimeoutTimer timeoutTimer; +#ifdef WICONNECT_SERIAL_RX_BUFFER + uint8_t ringBuffer[32]; + bool bufferAlloc; + void rxIrqHandler(void); +#endif +}; + + +} + + +