ACKme
/
wiconnect-test-console
Test serial console demonstrating various API functions of WiConnect library.
Revision 0:836c9a6383e0, committed 2014-08-11
- Comitter:
- dan_ackme
- Date:
- Mon Aug 11 11:31:32 2014 +0000
- Child:
- 1:5137ec8f4c45
- Commit message:
- Initial check-in
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ConsoleSerial.h Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,75 @@ +/* + * 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 <stdarg.h> + +#include "mbed.h" + + + + +class ConsoleSerial : public Serial +{ +public: + + ConsoleSerial(PinName tx, PinName rx) : Serial(tx, rx) + { + + } + + void setBaud(int baud) + { + this->baud(baud); + } + + int read() + { + return getc(); + } + + void write(int c) + { + putc(c); + } + + void write(const char *s) + { + puts(s); + } + + void write(char *s) + { + puts(s); + } + + void write(const void *data, int size) + { + Serial::write(data, size); + } + + void printf(const char *fmt, ...) + { + va_list va; + va_start(va, fmt); + vprintf(fmt, va); + va_end(va); + } + + void vprintf(const char *fmt, va_list va) + { + char buf[512]; + vsnprintf(buf, sizeof(buf), fmt, va); + write(buf); + } + +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wiconnect.lib Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/ACKme/code/Wiconnect/#8d91a87ebba2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,102 @@ +/* + * 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 "util/log/log.h" +#include "util/CommandProcessor/CommandProcessor.h" +#include "tests/Tests.h" +#include "target_config.h" + + +#if TEST_NONBLOCKING_API +#error 'TEST_NONBLOCKING_API = true' NOT currently supported for the mbed sdk +#endif + + +int wiconnectLogDebug(const char *str); + + +static const CommandListEntry commandList[] = +{ + CMD_HELP_ENTRY, + WICONNECT_TEST_CMD_LIST, + NETWORK_TEST_CMD_LIST, + SOCKET_TEST_CMD_LIST, + FILE_TEST_CMD_LIST, + CMD_LIST_TERMINATOR +}; + +static const SerialConfig serialConfig(WICONNECT_RX_PIN, WICONNECT_TX_PIN, WICONNECT_CTS_PIN, WICONNECT_RTS_PIN, WICONNECT_DEFAULT_BAUD, NULL, WICONNECT_SERIAL_RX_BUFFER_SIZE); +static Wiconnect wiconnectIfc(serialConfig, NULL, WICONNECT_INTERNAL_BUFFER_SIZE, WICONNECT_RESET_PIN, WICONNECT_WAKE_PIN, TEST_NONBLOCKING_API); + +ConsoleSerial consoleSerial(SERIAL_TX, SERIAL_RX); +CommandProcessor cmdProcessor(&consoleSerial, commandList); +char testBuffer[TEST_BUFFER_LENGTH]; + + +/*************************************************************************************************/ +int main(int argc, char *argv[]) +{ + WiconnectResult result; + + consoleSerial.setBaud(CONSOLE_BAUD); + +#ifdef ENABLE_WICONNECT_DEBUG + wiconnectIfc.setDebugLogger(LogFunc(wiconnectLogDebug)); +#endif + + initialize_loop: + { + LOG_INFO("\r\n\r\nInitializing WiConnect..."); + if(WICONNECT_FAILED(result, wiconnectIfc.init(true))) + { + LOG_WICONNECT_ERROR(result, "Failed to initialize Wiconnect"); + LOG_INFO("Press any key to retry initialization..."); + int c = consoleSerial.getc(); + goto initialize_loop; + } + } + + { + char version[WICONNECT_MAX_VERSION_SIZE]; + if(!WICONNECT_FAILED(result, wiconnectIfc.getVersion(version, WICONNECT_MAX_VERSION_SIZE))) + { + LOG_INFO("Version: %s", version); + } + } + + LOG_INFO("WiConnect test app ready..."); + + for(;;) + { + Command cmd; + cmdProcessor.waitForCommand(&cmd); + if(WICONNECT_FAILED(result, cmd.execute())) + { + LOG_WICONNECT_ERROR(result, "Failed to execute command"); + if(result == WICONNECT_CMD_RESPONSE_ERROR) + { + LOG_ERROR("WiConnect command response code: %s", wiconnectIfc.getLastCommandResponseCodeStr()); + } + } + } + + return 0; +} + + +/*************************************************************************************************/ +int wiconnectLogDebug(const char *str) +{ + logDebug(str); + return 0; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/6213f644d804 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target_config.h Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,81 @@ +/* + * 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 + +#ifndef TARGET_SEABASS +//#define TARGET_NUCLEO_F401RE +#endif + +// The BAUD rate your PC/MAC/Linux terminal uses with the eval board +#define CONSOLE_BAUD 115200 + + +// Uncomment this to enable WiConnect serial interface hardware flow control +// NOTE: your platform must support the serial flow control api functions +//#define ENABLE_FLOW_CONTROL + +// Uncomment to view debug messages from WiConnect library +#define ENABLE_WICONNECT_DEBUG + + +#define WICONNECT_INTERNAL_BUFFER_SIZE (4*1024) +#define WICONNECT_SERIAL_RX_BUFFER_SIZE (4*1024) + +#define DEFAULT_CMD_GETCHAR_TIMEOUT 250 +#define DEFAULT_COMMAND_LINE_LENGTH_MAX 128 +#define DEFAULT_COMMAND_MAX_HISTORY 16 +#define DEFAULT_CMD_PROMPT_STR "> " +#define DEFAULT_COMMAND_MAX_ARGV 16 + +#define TEST_NONBLOCKING_API false +#define TEST_BUFFER_LENGTH 4*1024 + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Seabass Target Configuration +#ifdef TARGET_SEABASS + +#define WICONNECT_TX_PIN PA_9 +#define WICONNECT_RX_PIN PA_10 +#define WICONNECT_RESET_PIN PB_0 +#define WICONNECT_WAKE_PIN NC + +#ifdef ENABLE_FLOW_CONTROL +#define WICONNECT_CTS_PIN PA_11 +#define WICONNECT_RTS_PIN PA_12 +#else +#define WICONNECT_CTS_PIN NC +#define WICONNECT_RTS_PIN NC +#endif + +#endif + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Nucleo F401RE Target Configuration +#ifdef TARGET_NUCLEO_F401RE + +#define WICONNECT_TX_PIN PA_9 +#define WICONNECT_RX_PIN PA_10 +#define WICONNECT_RESET_PIN PB_8 +#define WICONNECT_WAKE_PIN NC + +#ifdef ENABLE_FLOW_CONTROL +#define WICONNECT_CTS_PIN PA_11 +#define WICONNECT_RTS_PIN PA_12 +#else +#define WICONNECT_CTS_PIN NC +#define WICONNECT_RTS_PIN NC +#endif + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/Tests.h Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,44 @@ +/* + * 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 "Wiconnect.h" +#include "util/log/log.h" +#include "ConsoleSerial.h" + + +#if TEST_NONBLOCKING_API +//#include "nonblocking/wiconnect/WiconnectTests.h" +//#include "nonblocking/network/NetworkTests.h" +//#include "nonblocking/socket/SocketTests.h" +#else +#include "blocking/wiconnect/WiconnectTests.h" +#include "blocking/network/NetworkTests.h" +#include "blocking/socket/SocketTests.h" +#include "blocking/file/FileTests.h" +#endif + + + + +#include "StringUtil.h" + +#include "target_config.h" + + +extern char testBuffer[TEST_BUFFER_LENGTH]; + +extern ConsoleSerial consoleSerial; + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/file/FileCreateTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,127 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + +typedef struct +{ + uint32_t bytesRemaining; +} fileInfo_t; + + +static WiconnectResult fileReadCallback(void *user, void *data, int maxReadSize, int *bytesRead); + + + + + +/*************************************************************************************************/ +WiconnectResult fileCreateCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + const char *name; + uint32_t size; + uint32_t version = 0; + uint32_t type = FILE_TYPE_ANY; + const int savedTimeOut = wiconnect->getCommandDefaultTimeout(); + fileInfo_t fileInfo; + + + if(argc < 2) + { + LOG_ERROR("must specify file name and size"); + return WICONNECT_BAD_ARG; + } + + name = argv[0]; + if(!StringUtil::strToUint32(argv[1], &size)) + { + LOG_ERROR("invalid file size"); + return WICONNECT_BAD_ARG; + } + + if(argc > 2) + { + if(!Wiconnect::fileVersionStrToInt(argv[2], &version)) + { + LOG_ERROR("invalid file version"); + return WICONNECT_BAD_ARG; + } + } + if(argc > 3) + { + if(!StringUtil::strHexToUint32(argv[3], &type)) + { + LOG_ERROR("invalid file type"); + return WICONNECT_BAD_ARG; + } + } + + fileInfo.bytesRemaining = size; + wiconnect->setCommandDefaultTimeout(30000); // increase the timeout so the user can enter data + + if(!WICONNECT_FAILED(result, wiconnect->createFile(ReaderFunc(fileReadCallback), &fileInfo, name, size, version, (FileType)type))) + { + LOG_INFO("File created"); + } + wiconnect->setCommandDefaultTimeout(savedTimeOut); + + return result; +} + +/*************************************************************************************************/ +static WiconnectResult fileReadCallback(void *user, void *data, int maxReadSize, int *bytesReadPtr) +{ + fileInfo_t *info = (fileInfo_t*)user; + int bytesToRead = MIN(maxReadSize, info->bytesRemaining); + + if(info->bytesRemaining == 0) + { + LOG_INFO("All data written"); + *bytesReadPtr = EOF; + return WICONNECT_SUCCESS; + } + + LOG_INFO("Enter up to %d bytes (%d bytes remaining,\r\n Issue $$$ terminate current write):", bytesToRead, info->bytesRemaining); + + uint8_t *ptr = (uint8_t*)data; + int bytesRead = 0; + int terminateCount = 0; + + while(bytesToRead > 0) + { + int c = consoleSerial.getc(); + consoleSerial.putc(c); + terminateCount = (c == '$') ? terminateCount+1 : 0; + if(terminateCount >= 3) + { + break; + } + *ptr++ = (uint8_t)c; + ++bytesRead; + --bytesToRead; + } + + // remove '$$' from data if we terminated + if(terminateCount == 3) + { + bytesRead -= 2; + } + + info->bytesRemaining -= bytesRead; + *bytesReadPtr = bytesRead; + consoleSerial.write("\r\n"); + + return WICONNECT_SUCCESS; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/file/FileDeleteTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,35 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + + +/*************************************************************************************************/ +WiconnectResult fileDeleteCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + if(argc != 1) + { + LOG_ERROR("must specify file name to delete"); + return WICONNECT_BAD_ARG; + } + + if(!WICONNECT_FAILED(result, wiconnect->deleteFile(argv[0]))) + { + LOG_INFO("File delete"); + } + return result; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/file/FileListTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,98 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + + +static void printFileList(const FileList &fileList); + + + +/*************************************************************************************************/ +WiconnectResult fileListCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + FileList fileList; + uint32_t type = FILE_TYPE_ANY; + const char *name = NULL; + uint32_t version = 0; + + while(argc > 0) + { + if(argv[0][0] != '-' || argc < 2) + { + LOG_ERROR("Invalid command line argument"); + return WICONNECT_BAD_ARG; + } + + switch(argv[0][1]) + { + case 'v': { + if(!Wiconnect::fileVersionStrToInt(argv[1], &version)) + { + LOG_ERROR("Invalid file version"); + return WICONNECT_BAD_ARG; + } + } break; + case 'n': + name = argv[1]; + break; + case 't': { + if(!StringUtil::strHexToUint32((const char*)argv[1], &type)) + { + LOG_ERROR("Invalid file type"); + return WICONNECT_BAD_ARG; + } + } break; + default: + LOG_ERROR("Unknown command option: %c", argv[0][1]); + return WICONNECT_BAD_ARG; + } + + argc -= 2; + argv += 2; + } + + + if(!WICONNECT_FAILED(result, wiconnect->listFiles(fileList, name, (FileType)type, version))) + { + printFileList(fileList); + } + + return result; + +} + +/*************************************************************************************************/ +static void printFileList(const FileList &fileList) +{ + int i = 1; + + LOG_INFO("File count: %d", fileList.getCount()); + for(const File *file = fileList.getListHead(); file != NULL; file = file->getNext(), ++i) + { + LOG_INFO("------------------------\r\n" + "%d: %s\r\n" + "\tVersion: %s\r\n" + "\tSize: %d\r\n" + "\tType: %s\r\n" + "\tFlags: %s\r\n", + i, file->getName(), + file->getVersionStr(), + file->getSize(), + Wiconnect::fileTypeToStr(file->getType()), + Wiconnect::fileFlagsToStr(file->getFlags())); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/file/FileReadTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,57 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + +static WiconnectResult readFile(File &file); + + + +/*************************************************************************************************/ +WiconnectResult fileReadCommand(int argc, char **argv) +{ + WiconnectResult result; + File file(512); + Wiconnect *wiconnect = Wiconnect::getInstance(); + + if(argc != 1) + { + LOG_ERROR("must specify file name to read"); + return WICONNECT_BAD_ARG; + } + + + if(!WICONNECT_FAILED(result, wiconnect->openFile(file, argv[0]))) + { + readFile(file); + } + + return result; +} + +/*************************************************************************************************/ +static WiconnectResult readFile(File &file) +{ + uint8_t *ptr; + uint16_t size; + + while(file.read(&ptr, &size) == WICONNECT_SUCCESS) + { + LOG_INFO("File data: (%d)\r\n", size); + logWrite(ptr, size); + } + + return WICONNECT_SUCCESS; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/file/FileTests.h Mon Aug 11 11:31:32 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 + +#define FILE_TEST_CMD_LIST \ + ADD_HEADER("File commands:"), \ + ADD_CMD("ls", fileList, "list files (optionally by name, type, version)", \ + "Usage: ls [-n <name>] [-t <type>] [-v <version>]\n" \ + "Examples:\n" \ + "> ls // list all files\n" \ + "> ls -n *.exe // list all executable files\n" \ + "> ls -v 1.2 // list all files with version 1.2\n" \ + "> ls -t FE // list all miscellaneous files"), \ + ADD_CMD("create", fileCreate, "create a file", \ + "Usage: create <name> <size> [<version> [<type>]]\n" \ + "Example:\n" \ + "> create my_file.txt 100 4.56 // create file name 'my_file.txt'\n" \ + " // immediately following should be 100 bytes of data"), \ + ADD_CMD("read", fileRead, "read a file", \ + "Usage: read <name>\n" \ + "Example:\n" \ + "> read my_file.txt "), \ + ADD_CMD("delete", fileDelete, "delete a file", \ + "Usage: delete <name>\n" \ + "Example:\n" \ + "> delete my_file.txt ") + + +WiconnectResult fileListCommand(int argc, char **argv); +WiconnectResult fileCreateCommand(int argc, char **argv); +WiconnectResult fileReadCommand(int argc, char **argv); +WiconnectResult fileDeleteCommand(int argc, char **argv); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/network/JoinNetworkTest.cpp Mon Aug 11 11:31:32 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. + */ + + +#include "tests/Tests.h" +#include "Wiconnect.h" + + + +static void joinCompleteCallback(WiconnectResult result, void *arg1, void *arg2); + + +/*************************************************************************************************/ +WiconnectResult networkJoinCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + const char *ssid = (argc > 0) ? argv[0] : NULL; + const char *password = (argc > 1) ? argv[1] : NULL; + + if(!WICONNECT_FAILED(result, wiconnect->join(ssid, password, Callback(joinCompleteCallback)))) + { + LOG_INFO("Joining network"); + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult networkLeaveCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + if(!WICONNECT_FAILED(result, wiconnect->leave())) + { + LOG_INFO("Successfully disconnected from network"); + } + return result; +} + +/*************************************************************************************************/ +static void joinCompleteCallback(WiconnectResult result, void *arg1, void *arg2) +{ + if(result == WICONNECT_SUCCESS) + { + LOG_INFO("Successfully joined network"); + } + else + { + LOG_WICONNECT_ERROR(result, "Errors occurred while joining network"); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/network/NetworkTests.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,103 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + + +/*************************************************************************************************/ +WiconnectResult networkStatsCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + NetworkStatus status; + NetworkSignalStrength signal; + uint32_t ip, nm, gw; + bool dhcpEnabled; + + if(WICONNECT_FAILED(result, wiconnect->getIpSettings(&ip, &nm, &gw))) + { + LOG_INFO("Failed to get IP Settings"); + } + else if(WICONNECT_FAILED(result, wiconnect->setDhcpEnabled(&dhcpEnabled))) + { + LOG_INFO("Failed to get DHCP setting"); + } + else if(WICONNECT_FAILED(result, wiconnect->getNetworkStatus(&status))) + { + LOG_INFO("Failed to get network status"); + } + else if(WICONNECT_FAILED(result, wiconnect->getSignalStrength(&signal))) + { + LOG_INFO("Failed to get signal strength"); + } + else + { + char ipStr[16], gwStr[16], nmStr[16]; + + LOG_INFO("\r\n------------------------\r\n" + "IP: %s\r\n" + "Netmask: %s\r\n" + "Gateway: %s\r\n" + "DHCP enabled: %s\r\n" + "Status: %s\r\n" + "Signal: %s\r\n" + "------------------------", + Wiconnect::ipToStr(ip, ipStr), + Wiconnect::ipToStr(nm, nmStr), + Wiconnect::ipToStr(gw, gwStr), + dhcpEnabled ? "true" : "false", + Wiconnect::networkStatusToStr(status), + Wiconnect::signalStrengthToStr(signal)); + + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult networkPingCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + uint32_t pingTimeMs; + const char *domain = (argc > 0) ? argv[0] : NULL; + + if(!WICONNECT_FAILED(result, wiconnect->ping(domain, &pingTimeMs))) + { + LOG_INFO("Ping reply: %dms", pingTimeMs); + } + return result; +} + +/*************************************************************************************************/ +WiconnectResult networkLookupCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + if(argc != 1) + { + return WICONNECT_BAD_ARG; + } + + uint32_t ipAddress; + + if(!WICONNECT_FAILED(result, wiconnect->lookup(argv[0], &ipAddress))) + { + IpStrBuffer buffer; + LOG_INFO("IP Address: %s", Wiconnect::ipToStr(ipAddress, buffer)); + } + return result; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/network/NetworkTests.h Mon Aug 11 11:31:32 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 + + +#define NETWORK_TEST_CMD_LIST \ + ADD_HEADER("Network commands:"), \ + ADD_CMD("setup", networkSetupWeb, "start/stop/check web setup", \ + "Usage: setup <start/stop/status> [<ssid> [<password>]]\n" \ + "Examples:\n" \ + "> setup start MySSID password\n" \ + "> setup check\n" \ + "> setup stop"), \ + ADD_CMD("join", networkJoin, "Join a network", \ + "Usage: join [<ssid> [<password>]]"), \ + ADD_CMD("leave", networkLeave, "Leave a network", \ + "Usage: leave"), \ + ADD_CMD("netstat", networkStats, "Get network information", \ + "Usage: netstat"), \ + ADD_CMD("scan", networkScan, "Return list of available networks", \ + "Usage: scan [<channel list>/<all> [<ssid>]]\n" \ + "Examples:\n" \ + "> scan 1,6,11\n" \ + "> scan all \"My Network's Name\""), \ + ADD_CMD("ping", networkPing, "Ping a network", \ + "Usage: ping [<host/IP address>]\n" \ + "Examples:\n" \ + "> ping // ping the gateway\n" \ + "> ping www.ack.me"), \ + ADD_CMD("lookup", networkLookup, "Resolve domain name to IP address", \ + "Usage: lookup <domain>\n" \ + "Examples:\n" \ + "> lookup www.ack.me") + + +WiconnectResult networkSetupWebCommand(int argc, char **argv); +WiconnectResult networkJoinCommand(int argc, char **argv); +WiconnectResult networkLeaveCommand(int argc, char **argv); +WiconnectResult networkStatsCommand(int argc, char **argv); +WiconnectResult networkScanCommand(int argc, char **argv); +WiconnectResult networkPingCommand(int argc, char **argv); +WiconnectResult networkLookupCommand(int argc, char **argv); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/network/ScanNetworkTest.cpp Mon Aug 11 11:31:32 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 "tests/Tests.h" +#include "Wiconnect.h" + + + +static void printScanResults(const ScanResultList &scanResultList); + + + + +/*************************************************************************************************/ +WiconnectResult networkScanCommand(int argc, char **argv) +{ + WiconnectResult result = WICONNECT_BAD_ARG; + Wiconnect *wiconnect = Wiconnect::getInstance(); + ScanResultList scanResultList; + uint8_t channelList[16]; + const char* ssid = NULL; + uint8_t *channelListPtr = NULL; + + if(argc > 0) + { + if(strcmp(argv[0], "all") != 0) + { + char *ch_tok; + char *chListPtr = argv[0]; + uint8_t ch_count = 0; + + while((ch_tok = strtok(chListPtr, ",")) != NULL) + { + intmax_t x; + + if(!StringUtil::parseInt(ch_tok, &x, 1, 14)) + { + return WICONNECT_BAD_ARG; + } + channelList[ch_count++] = (uint8_t)x; + chListPtr = NULL; + } + channelList[ch_count] = 0; + channelListPtr = channelList; + } + --argc; + ++argv; + } + + if(argc > 0) + { + ssid = argv[0]; + } + + if(!WICONNECT_FAILED(result, wiconnect->scan(scanResultList, channelListPtr, ssid))) + { + printScanResults(scanResultList); + } + + return result; +} + + + +/*************************************************************************************************/ +static void printScanResults(const ScanResultList &scanResultList) +{ + SsidStrBuffer ssidBuffer; + MacAddressStrBuffer macBuffer; + char rateBuffer[16]; + int i = 1; + + LOG_INFO("Scan result count: %d", scanResultList.getCount()); + for(const ScanResult *res = scanResultList.getListHead(); res != NULL; res = res->getNext(), ++i) + { + LOG_INFO("------------------------\r\n" + "%d: %s\r\n" + "\tChannel: %d\r\n" + "\tSignal: %s\r\n" + "\tSecurity: %s\r\n" + "\tRate: %s\r\n" + "\tBSSID: %s", + i, Wiconnect::ssidToStr(res->getSsid(), ssidBuffer), + res->getChannel(), + Wiconnect::signalStrengthToStr(res->getSignalStrength()), + Wiconnect::networkSecurityToStr(res->getSecurityType()), + res->getRateStr(rateBuffer), + Wiconnect::macAddressToStr(res->getMacAddress(), macBuffer)); + } + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/network/WebSetupNetworkTest.cpp Mon Aug 11 11:31:32 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. + */ + + +#include "tests/Tests.h" +#include "Wiconnect.h" + + +static void webSetupCompleteCallback(WiconnectResult result, void *arg1, void *arg2); + + +/*************************************************************************************************/ +WiconnectResult networkSetupWebCommand(int argc, char **argv) +{ + WiconnectResult result = WICONNECT_BAD_ARG; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + if(strcmp(argv[0], "status") == 0) + { + bool isRunning; + + if(!WICONNECT_FAILED(result, wiconnect->isWebSetupRunning(&isRunning))) + { + LOG_INFO("Web setup is %s", isRunning ? "running" : "stopped"); + } + } + else if(strcmp(argv[0], "start") == 0) + { + const char *ssid = (argc > 1) ? argv[1] : NULL; + const char *password = (argc > 2) ? argv[2] : NULL; + + if(!WICONNECT_FAILED(result, wiconnect->startWebSetup(ssid, password, Callback(webSetupCompleteCallback)))) + { + LOG_INFO("Web setup started"); + } + } + else if(strcmp(argv[0], "stop") == 0) + { + if(!WICONNECT_FAILED(result, wiconnect->stopWebSetup())) + { + LOG_INFO("Web setup stopped"); + } + } + + return result; +} + +/*************************************************************************************************/ +static void webSetupCompleteCallback(WiconnectResult result, void *arg1, void *arg2) +{ + if(result == WICONNECT_SUCCESS) + { + LOG_INFO("Web setup successfully completed"); + } + else + { + LOG_WICONNECT_ERROR(result, "Web setup finished with errors"); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/socket/HttpGetTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,133 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + + +static WiconnectResult addHeadersPrompt(Wiconnect *wiconnect, Socket &socket); +static WiconnectResult readResponse(Socket &socket); + + + +/*************************************************************************************************/ +WiconnectResult socketHttpGetCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + Socket socket(sizeof(testBuffer), testBuffer); + const char *url; + bool addHeaders = false; + + if(argc < 1) + { + LOG_ERROR("must specify url"); + return WICONNECT_BAD_ARG; + } + url = argv[0]; + + if(argc > 1) + { + addHeaders = true; + } + + + if(!WICONNECT_FAILED(result, wiconnect->httpGet(socket, url, addHeaders))) + { + uint32_t status; + if(addHeaders) + { + if(WICONNECT_FAILED(result, addHeadersPrompt(wiconnect, socket))) + { + goto exit; + } + else if(WICONNECT_FAILED(result, wiconnect->httpGetStatus(socket, &status))) + { + goto exit; + } + LOG_INFO("HTTP Status: %d", status); + } + + result = readResponse(socket); + } + +exit: + return result; +} + + + + +/*************************************************************************************************/ +static WiconnectResult addHeadersPrompt(Wiconnect *wiconnect, Socket &socket) +{ + WiconnectResult result; + + char buffer[128]; + for(;;) + { + LOG_INFO("Enter header 'key,value\\n' (or 'done\\n' to issue request):"); + char *ptr = buffer; + + for(;;) + { + int c = consoleSerial.getc(); + consoleSerial.putc(c); + if(c == '\r') + continue; + if(c == '\n') + { + *ptr = 0; + break; + } + *ptr++ = (char)c; + } + + if(strcmp(buffer, "done") == 0) + { + return WICONNECT_SUCCESS; + } + + char *value = strchr(buffer, ','); + if(value == NULL) + { + LOG_ERROR("Mal-formed key,value pair. Must be: <key>,<value>"); + continue; + } + + *value++ = 0; + + if(WICONNECT_FAILED(result, wiconnect->httpAddHeader(socket, buffer, value))) + { + LOG_ERROR("Failed to add header key, value"); + break; + } + } + + return result; +} + +/*************************************************************************************************/ +static WiconnectResult readResponse(Socket &socket) +{ + uint8_t c; + + LOG_INFO("Response data:"); + while(socket.getc(&c) == WICONNECT_SUCCESS) // NOTE: getc() is extremely inefficient here, + // is only used to test its functionality + { + logWrite(&c, 1); + } + + return WICONNECT_SUCCESS; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/socket/HttpPostTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,94 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + +#define TEST_SERVER_URL "http://www.posttestserver.com" +#define CONTEXT_TYPE "text/plain" + + +static WiconnectResult addPostData(Socket &socket); +static WiconnectResult readResponse(Socket &socket); + + +/*************************************************************************************************/ +WiconnectResult socketHttpPostCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + Socket socket(0, NULL, sizeof(testBuffer), testBuffer); + uint32_t status; + + if(WICONNECT_FAILED(result, wiconnect->httpPost(socket, TEST_SERVER_URL, CONTEXT_TYPE))) + { + LOG_ERROR("Failed to open POST connection"); + } + else if(WICONNECT_FAILED(result, addPostData(socket))) + { + LOG_ERROR("Failed to add POST data"); + } + else if(WICONNECT_FAILED(result, wiconnect->httpGetStatus(socket, &status))) + { + LOG_ERROR("Failed to read HTTP status"); + } + else if(WICONNECT_FAILED(result, readResponse(socket))) + { + LOG_ERROR("Failed to read POST response"); + } + + return result; +} + +/*************************************************************************************************/ +static WiconnectResult addPostData(Socket &socket) +{ + WiconnectResult result; + + LOG_INFO("Enter post data ('\\n' issues request):"); + + int c; + + for(;;) + { + c = consoleSerial.getc(); + consoleSerial.putc(c); + if(c == '\r') + continue; + if(c == '\n') + break; + + if(WICONNECT_FAILED(result, socket.putc(c))) + { + return result; + } + } + + return socket.flushTxBuffer(); +} + +/*************************************************************************************************/ +static WiconnectResult readResponse(Socket &socket) +{ + uint8_t *buffer; + uint16_t size; + + LOG_INFO("Response data:"); + + while(socket.read(&buffer, &size) == WICONNECT_SUCCESS) + { + logWrite(buffer, size); + } + + return WICONNECT_SUCCESS; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/socket/SocketTests.h Mon Aug 11 11:31:32 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 + + +#define SOCKET_TEST_CMD_LIST \ + ADD_HEADER("Socket commands:"), \ + ADD_CMD("get", socketHttpGet, "Issue HTTP GET request with optional headers", \ + "Usage: get <url> [true]\n" \ + "Examples:\n" \ + "> get ack.me // immediately issue GET and print page\n" \ + "> get ack.me true // issue GET then add HTTP headers\n"), \ + ADD_CMD("post", socketHttpPost, "Issue HTTP POST request to http://www.posttestserver.com/", \ + "Usage: post\n" \ + "Examples:\n" \ + "> post // opens POST connection then enter the post data"), \ + ADD_CMD("tcp", socketTcpClientEcho, "Open TCP connection, transmit data and receivd echoed data", \ + "Usage: tcp <host> <port> [<packets count> [<delay> <size>]]]"), \ + ADD_CMD("udp", socketUdpClientEcho, "Open UDP connection, transmit data and receivd echoed data", \ + "Usage: udp <host> <port> [<packets count> [<delay> <size>]]]") + + + +WiconnectResult socketTcpClientEchoCommand(int argc, char **argv); +WiconnectResult socketUdpClientEchoCommand(int argc, char **argv); +WiconnectResult socketHttpGetCommand(int argc, char **argv); +WiconnectResult socketHttpPostCommand(int argc, char **argv); +WiconnectResult socketHttpHeadCommand(int argc, char **argv); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/socket/TcpEchoTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,152 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + + +static WiconnectResult processData(Socket &socket, uint32_t count, uint32_t delay, uint32_t size); + + + +/*************************************************************************************************/ +WiconnectResult socketTcpClientEchoCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + Socket socket(sizeof(testBuffer)/2, testBuffer, sizeof(testBuffer)/2, testBuffer + sizeof(testBuffer)/2); + const char *host; + uint32_t port; + uint32_t delay = 5; + uint32_t count = 1000; + uint32_t size = 256; + + if(argc < 2) + { + LOG_ERROR("Must specify host and port"); + return WICONNECT_BAD_ARG; + } + host = argv[0]; + + if(!StringUtil::strToUint32((const char*)argv[1], &port)) + { + LOG_ERROR("Invalid port"); + return WICONNECT_BAD_ARG; + } + if(argc > 2 && !StringUtil::strToUint32((const char*)argv[2], &count)) + { + LOG_ERROR("Invalid packet count"); + return WICONNECT_BAD_ARG; + } + if(argc > 3 && !StringUtil::strToUint32((const char*)argv[3], &delay)) + { + LOG_ERROR("Invalid packet delay"); + return WICONNECT_BAD_ARG; + } + if(argc > 4 && (!StringUtil::strToUint32((const char*)argv[4], &size) || size > sizeof(testBuffer)/2)) + { + LOG_ERROR("Invalid packet size"); + return WICONNECT_BAD_ARG; + } + + if(WICONNECT_FAILED(result, wiconnect->tcpConnect(socket, host, port))) + { + LOG_ERROR("Failed to connect to server"); + } + else + { + result = processData(socket, count, delay, size); + } + + return result; +} + + +/*************************************************************************************************/ +static WiconnectResult processData(Socket &socket, uint32_t count, uint32_t delay, uint32_t size) +{ + WiconnectResult result; + uint8_t *txBuffer = socket.getTxBuffer(); + const int txBufferLen = socket.getTxBufferSize(); + uint8_t writeCounter = 32; + uint8_t readCounter = 32; + uint32_t bytesSent = 0; + uint32_t bytesReceived = 0; + + LOG_INFO("\r\n------------------\r\n" + "Starting TCP Echo Test:\r\n" + "Packet count: %d\r\n" + "Packet size: %d\r\n" + "Packet delay: %d\r\n" + "(Press any key to terminate)", + count, size, delay); + + for(int i = 0; i < count || bytesReceived < bytesSent; ++i) + { + if(i < count) + { + uint8_t *ptr = txBuffer; + int l = size; + while(l--) + { + *ptr++ = writeCounter++; + if(writeCounter == 128) + writeCounter = 32; + } + + if(WICONNECT_FAILED(result, socket.write(size))) + { + break; + } + bytesSent += size; + consoleSerial.putc('.'); + } + + if(consoleSerial.readable()) + { + int c = consoleSerial.getc(); + break; + } + + delayMs(delay); + + uint8_t *readPtr; + uint16_t readLen; + if(WICONNECT_FAILED(result, socket.read(&readPtr, &readLen))) + { + break; + } + bytesReceived += readLen; + + while(readLen--) + { + if(*readPtr != readCounter) + { + LOG_ERROR("Invalid: %02X != %02X", *readPtr, readCounter); + } + ++readPtr; + ++readCounter; + if(readCounter == 128) + readCounter = 32; + } + } + + consoleSerial.write("\r\n"); + LOG_INFO("------------------\r\n" + "TCP Echo Test Complete:\r\n" + "Bytes sent: %d\r\n" + "Bytes received: %d\r\n", + bytesSent, bytesReceived); + + return result; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/socket/UdpEchoTest.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,153 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + + + +static WiconnectResult processData(Socket &socket, uint32_t count, uint32_t delay, uint32_t size); + + + +/*************************************************************************************************/ +WiconnectResult socketUdpClientEchoCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + Socket socket(sizeof(testBuffer)/2, testBuffer, sizeof(testBuffer)/2, testBuffer + sizeof(testBuffer)/2); + const char *host; + uint32_t port; + uint32_t delay = 5; + uint32_t count = 1000; + uint32_t size = 256; + + if(argc < 2) + { + LOG_ERROR("Must specify host and port"); + return WICONNECT_BAD_ARG; + } + host = argv[0]; + + if(!StringUtil::strToUint32((const char*)argv[1], &port)) + { + LOG_ERROR("Invalid port"); + return WICONNECT_BAD_ARG; + } + if(argc > 2 && !StringUtil::strToUint32((const char*)argv[2], &count)) + { + LOG_ERROR("Invalid packet count"); + return WICONNECT_BAD_ARG; + } + if(argc > 3 && !StringUtil::strToUint32((const char*)argv[3], &delay)) + { + LOG_ERROR("Invalid packet delay"); + return WICONNECT_BAD_ARG; + } + if(argc > 4 && (!StringUtil::strToUint32((const char*)argv[4], &size) || size > sizeof(testBuffer)/2)) + { + LOG_ERROR("Invalid packet size"); + return WICONNECT_BAD_ARG; + } + + if(WICONNECT_FAILED(result, wiconnect->udpConnect(socket, host, port))) + { + LOG_ERROR("Failed to connect to server"); + } + else + { + result = processData(socket, count, delay, size); + } + + return result; +} + + +/*************************************************************************************************/ +static WiconnectResult processData(Socket &socket, uint32_t count, uint32_t delay, uint32_t size) +{ + WiconnectResult result; + uint8_t *txBuffer = socket.getTxBuffer(); + const int txBufferLen = socket.getTxBufferSize(); + uint8_t writeCounter = 32; + uint8_t readCounter = 32; + uint32_t bytesSent = 0; + uint32_t bytesReceived = 0; + + LOG_INFO("\r\n------------------\r\n" + "Starting UDP Echo Test:\r\n" + "Packet count: %d\r\n" + "Packet size: %d\r\n" + "Packet delay: %d\r\n" + "(Press any key to terminate)", + count, size, delay); + + for(int i = 0; i < count || bytesReceived < bytesSent; ++i) + { + if(i < count) + { + uint8_t *ptr = txBuffer; + int l = size; + while(l--) + { + *ptr++ = writeCounter++; + if(writeCounter == 128) + writeCounter = 32; + } + + if(WICONNECT_FAILED(result, socket.write(size))) + { + break; + } + bytesSent += size; + consoleSerial.putc('.'); + } + + if(consoleSerial.readable()) + { + int c = consoleSerial.getc(); + break; + } + + delayMs(delay); + + uint8_t *readPtr; + uint16_t readLen; + if(WICONNECT_FAILED(result, socket.read(&readPtr, &readLen))) + { + break; + } + bytesReceived += readLen; + + while(readLen--) + { + if(*readPtr != readCounter) + { + LOG_ERROR("Invalid: %02X != %02X", *readPtr, readCounter); + } + ++readPtr; + ++readCounter; + if(readCounter == 128) + readCounter = 32; + } + } + + consoleSerial.write("\r\n"); + LOG_INFO("------------------\r\n" + "UDP Echo Test Complete:\r\n" + "Bytes sent: %d\r\n" + "Bytes received: %d\r\n", + bytesSent, bytesReceived); + + return result; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/wiconnect/WiconnectTests.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,137 @@ +/* + * 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 "tests/Tests.h" +#include "Wiconnect.h" + + +#define TIMEOUT 10000 // ms + + +static volatile bool wiconnectNonBlockingCommandFinished = false; + + + +/*************************************************************************************************/ +WiconnectResult wiconnectSendRawBlockingCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + strcpy(testBuffer, argv[0]); + --argc; + ++argv; + + while(argc--) + { + strcat(testBuffer, " "); + strcat(testBuffer, argv[0]); + ++argv; + } + + if(!WICONNECT_FAILED(result, wiconnect->sendCommand(TIMEOUT, testBuffer, TEST_BUFFER_LENGTH, testBuffer))) + { + LOG_INFO_WRITE_STR("Response:\r\n", wiconnect->getResponseBuffer()); + } + + return result; +} + + + +/*************************************************************************************************/ +static void responseHandler(WiconnectResult result, void *response, void *responseLen) +{ + Wiconnect *wiconnect = Wiconnect::getInstance(); + + wiconnectNonBlockingCommandFinished = true; + + if(result == WICONNECT_SUCCESS) + { + LOG_INFO_WRITE_STR("Non-blocking Response:\r\n", (const char*)response); + } + else + { + LOG_WICONNECT_ERROR(result, "Non-blocking command failed"); + } +} + +/*************************************************************************************************/ +WiconnectResult wiconnectSendRawNonBlockingCommand(int argc, char **argv) +{ + + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + char *ptr = testBuffer; + + strcpy(testBuffer, argv[0]); + --argc; + ++argv; + + while(argc--) + { + strcat(testBuffer, " "); + strcat(testBuffer, argv[0]); + ++argv; + } + + wiconnectNonBlockingCommandFinished = false; + if(WICONNECT_FAILED(result, wiconnect->sendCommand(Callback(responseHandler), testBuffer, TEST_BUFFER_LENGTH, TIMEOUT, testBuffer))) + { + } + else if(!wiconnectNonBlockingCommandFinished) + { + LOG_INFO("Non-blocking command processing..."); + } + + return result; +} + +/*************************************************************************************************/ +WiconnectResult wiconnectGetVersionCommand(int argc, char **argv) +{ + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + + if(!WICONNECT_FAILED(result, wiconnect->getVersion(testBuffer, sizeof(testBuffer)))) + { + LOG_INFO("Version: %s", testBuffer); + } + return result; +} + +/*************************************************************************************************/ +WiconnectResult wiconnectDebugEnableCommand(int argc, char **argv) +{ + extern int wiconnectLogDebug(const char *str); + WiconnectResult result; + Wiconnect *wiconnect = Wiconnect::getInstance(); + bool enabled; + + if(!StringUtil::parseBool(argv[0], &enabled)) + { + return WICONNECT_BAD_ARG; + } + + if(enabled) + { + wiconnect->setDebugLogger(LogFunc(wiconnectLogDebug)); + LOG_INFO("WiConnet debugging enabled"); + } + else + { + wiconnect->setDebugLogger(LogFunc()); + LOG_INFO("WiConnet debugging disabled"); + } + + return WICONNECT_SUCCESS; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/blocking/wiconnect/WiconnectTests.h Mon Aug 11 11:31:32 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 + + +#define WICONNECT_TEST_CMD_LIST \ + ADD_HEADER("WiConnect commands:"), \ + ADD_CMD(":", wiconnectSendRawBlocking, "Send a blocking raw wiconnect command to module", \ + "Usage: : <wiconnet command> [command options]\n" \ + "Example:\n> : get network.status"), \ + ADD_CMD("#", wiconnectSendRawNonBlocking, "Send a non-blocking raw wiconnect command to module", \ + "Usage: # <wiconnet command> [command options]\n" \ + "Example:\n> # get network.status"), \ + ADD_CMD("ver", wiconnectGetVersion, "Get WiConnect version string", \ + "Usage: ver"), \ + ADD_CMD("debug", wiconnectDebugEnable, "Enabled/disable wiconnect library debug messages", \ + "Usage: debug <on/off>") + + + + +WiconnectResult wiconnectSendRawBlockingCommand(int argc, char **argv); +WiconnectResult wiconnectSendRawNonBlockingCommand(int argc, char **argv); +WiconnectResult wiconnectGetVersionCommand(int argc, char **argv); +WiconnectResult wiconnectDebugEnableCommand(int argc, char **argv); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/CommandProcessor/CommandProcessor.h Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,316 @@ +/* + * 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 <ctype.h> + +#include "Wiconnect.h" +#include "Console.h" +#include "StringUtil.h" +#include "util/log/log.h" + + + +#define ADD_HEADER(header) { header, NULL, NULL, NULL} +#define ADD_CMD(key, func, desc, ext) { key, func ## Command, desc, ext } +#define CMD_LIST_TERMINATOR { NULL, NULL, NULL, NULL } +#define CMD_HELP_ENTRY { "?", NULL, "Print list of commands. Add '-v' option to print verbosely", NULL }, \ + { "help", NULL, "Print list of commands. Add '-v' option to print verbosely", NULL } + +typedef WiconnectResult (*CommandProcessorFunc)(int, char**); + +typedef struct +{ + const char *key; + CommandProcessorFunc func; + const char *desc; + const char *extendedDesc; +} CommandListEntry; + + +/*************************************************************************************************/ +class Command +{ +public: + Command() + { + argc = -1; + func = NULL; + } + + void init(int argc_, CommandProcessorFunc func_) + { + argc = argc_; + func = func_; + } + + char** getArgvBuffer() + { + return argv; + } + + WiconnectResult execute() + { + return func(argc, argv); + } + +private: + int argc; + char *argv[DEFAULT_COMMAND_MAX_ARGV]; + CommandProcessorFunc func; +}; + + + +/*************************************************************************************************/ +class CommandProcessor +{ +private: + const CommandListEntry *commandList; + Console console; + ConsoleSerial *serial; + int commandListSize; + +public: + /*************************************************************************************************/ + CommandProcessor(ConsoleSerial *serial_, const CommandListEntry *commandList_) : + commandList(commandList_), console(serial_), serial(serial_), commandListSize(0) + { + for(const CommandListEntry *cmd = commandList; cmd->key != NULL; ++cmd) + { + ++commandListSize; + } + } + + /*************************************************************************************************/ + ~CommandProcessor() + { + } + + /*************************************************************************************************/ + void waitForCommand(Command *cmdPtr) + { + for(;;) + { + char *line; + char **argv; + intmax_t index; + int lineLength; + const CommandListEntry *foundCmd = NULL; + + console.readLine(&line, &lineLength); + + if(lineLength == 0) + { + continue; + } + + argv = cmdPtr->getArgvBuffer(); + int argc = parseArgs(line, DEFAULT_COMMAND_MAX_ARGV, argv); + if(argc == -1) + { + LOG_ERROR("Failed to parse commandline"); + continue; + } + + if(argv[0][0] == '?' || strcmp(argv[0], "help") == 0) + { + bool verbose = (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'v'); + printHelp(verbose); + continue; + } + + for(const CommandListEntry *cmd = commandList; cmd->key != NULL; ++cmd) + { + if(cmd->desc != NULL && strcmp(cmd->key, argv[0]) == 0) + { + foundCmd = cmd; + break; + } + } + + if(foundCmd == NULL) + { + if(StringUtil::parseInt(argv[0], &index, 0, commandListSize)) + { + foundCmd = &commandList[(int)index]; + } + else + { + LOG_ERROR("Unknown command. Enter: 'help' to list available commands"); + continue; + } + } + + --argc; + memmove(argv, &argv[1], sizeof(char*)*argc); + + if(argc == 1 && (argv[0][0] == '?' || (strstr(argv[0], "help") != NULL))) + { + printCommandHelp(foundCmd, true, -1); + continue; + } + else + { + cmdPtr->init(argc, foundCmd->func); + } + break; + } + } + +protected: + + /*************************************************************************************************/ + void printHelp(bool verbose) + { + int i = 0; + for(const CommandListEntry *cmd = commandList; cmd->key != NULL; ++cmd, ++i) + { + if(cmd->desc == NULL) + { + --i; + serial->printf("\r\n--------------------------------\r\n" + "%s\r\n", cmd->key); + continue; + } + printCommandHelp(cmd, verbose, i); + } + } + + + /*************************************************************************************************/ + void printCommandHelp(const CommandListEntry *cmd, bool verbose, int i) + { + if(i != -1) + serial->printf("%2d: %10s : %s\r\n", i, cmd->key, cmd->desc); + else + serial->printf(" %10s : %s\r\n", cmd->key, cmd->desc); + + if(verbose) + { + if(cmd->extendedDesc != NULL) + { + const char *newline, *ptr = cmd->extendedDesc; + + print_extended_help: + paddHelpSpaces(); + newline = strchr(ptr, '\n'); + if(newline == NULL) + { + puts(ptr); + return; + } + else + { + while(ptr < newline) + serial->write(*ptr++); + serial->write('\r'); + serial->write('\n'); + ++ptr; + goto print_extended_help; + } + } + } + } + + /*************************************************************************************************/ + void paddHelpSpaces() + { + int spaces = 17; + while(spaces--) + serial->write(' '); + } + + + /*************************************************************************************************/ + int parseArgs(char *line, int max_argc, char **argv) + { + // TODO: \x00 style escaping + char *p; + unsigned char c; + int argc = 0; + char *tokenstart = NULL; + enum states + { + INITIAL, + WORD, + STRING + } state = INITIAL; + + for (p = line; *p != '\0'; p++) + { + c = (unsigned char) * p; + /* One less because word at end-of-line case increments again */ + if (argc >= max_argc - 1) + { + return argc; + } + switch (state) + { + case INITIAL: + if (isspace(c)) + { + continue; + } + if (c == '"') + { + state = STRING; + tokenstart = p + 1; + continue; + } + tokenstart = p; + state = WORD; + continue; + case STRING: + if (c == '"') + { + state = INITIAL; + *p = 0; + argv[argc++] = tokenstart; + } + continue; + case WORD: + if (c == '"') + { + state = STRING; + *p = 0; + argv[argc++] = tokenstart; + tokenstart = p + 1; + } + else if (isspace(c)) + { + state = INITIAL; + *p = 0; + argv[argc++] = tokenstart; + } + continue; + } + } + if (state == WORD) + { + *p = 0; + argv[argc++] = tokenstart; + argv[argc] = NULL; + } + else if (state == STRING) + { + argc = -1; /* Unterminated string */ + } + else + { + argv[argc] = NULL; + } + + return argc; + } + +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/CommandProcessor/Console.h Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,450 @@ +/* + * 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 "ConsoleSerial.h" +#include "target_config.h" + + +typedef struct +{ + int index; + int count; + const char **choices; + char cmd_buffer[32]; + char *cmd_buffer_ptr; + char cmp_offset; +} console_tab_info_t; + +typedef struct context +{ + char line[DEFAULT_COMMAND_LINE_LENGTH_MAX]; + int line_length; + //int max_line_length; + volatile int cursor_position; + char history[DEFAULT_COMMAND_MAX_HISTORY][DEFAULT_COMMAND_LINE_LENGTH_MAX]; + int history_count; + int history_index; + //int hisory_length; + char CR_char; + console_tab_info_t tab_info; +} console_context_t; + + +class Console +{ +private: + ConsoleSerial *serial; + console_context_t context; +public: + + /*************************************************************************************************/ + Console(ConsoleSerial *serial_) : serial(serial_) + { + memset((void*)&context, 0, sizeof(console_context_t)); + } + + /*************************************************************************************************/ + ~Console() + { + } + + /*************************************************************************************************/ + int readLine(char **line, int *lineLength) + { + bool in_escape_sequence = false; + context.line[0] = 0; + context.line_length = 0; + context.cursor_position = 0; + context.history_index = -1; + + serial->write(DEFAULT_CMD_PROMPT_STR); + + while(context.cursor_position < (DEFAULT_COMMAND_LINE_LENGTH_MAX-1)) + { + int c; + + c = serial->read(); + if(c == -1) + { + continue; + } + + if(c == '\r' || c == '\n') + { + context.CR_char = c; + } + + if(in_escape_sequence) + { + in_escape_sequence = process_escape_sequence(c, true); + } + else + { + switch((unsigned char)c) + { + case '\t' : // tab + //process_tab(); + break; + case '\r': // newline + case '\n': // linefeed + if(context.CR_char == c) + { + if(c == '\r') + { + // retrieve \n as well + serial->read(); + } + serial->write('\r'); + serial->write('\n');; + goto console_readline_finish; + } + break; + case 27: // escape character + case 0xE0: + in_escape_sequence = true; + break; + case '\b': // backspace + case '\x7F':// delete + do_backspace(true); + break; + default: { + if((c >= 32) && (c < 127)) + { + add_char(c, true); + } + } break; + } + *lineLength = context.line_length; + } + +// if(c != '\t') +// { +// clear_tab_choices(); +// } + + } + + return -1; + + console_readline_finish: + { + *line = context.line; + *lineLength = context.line_length; + + if(context.line_length > 0) + { + update_history(context.line); + } + } + + return 0; + } + +protected: + + /*************************************************************************************************/ + bool process_escape_sequence(char c, bool echo) + { + char previous_char; + bool still_in_esc_seq = false; + + #ifdef __WIN32__ + #define UP_ARROW 'H' + //#define RIGHT_ARROW 'M' + #define DOWN_ARROW 'P' + //#define LEFT_ARROW 'K' + //#define HOME 'G' + //#define END 'O' + #else + #define UP_ARROW 'A' + #define RIGHT_ARROW 'C' + #define DOWN_ARROW 'B' + #define LEFT_ARROW 'D' + #define HOME 'H' + #define END 'F' + #endif + + switch((unsigned char)c) + { + #ifndef __WIN32__ + case 'O': + #endif + case ';': + case '[': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 0xE0: + still_in_esc_seq = true; + break; + case UP_ARROW: /* up arrow */ + cycle_history(false); + break; + case DOWN_ARROW: /* down arrow */ + cycle_history(true); + break; + #ifdef RIGHT_ARROW + case RIGHT_ARROW: /* right arrow */ + update_cursor_position(true); + break; + #endif + #ifdef LEFT_ARROW + case LEFT_ARROW: /* left arrow */ + update_cursor_position(false); + break; + #endif + #ifdef END + case END: /* end */ + move_cursor_position(true); + break; + #endif + #ifdef HOME + case HOME: /* home */ + move_cursor_position(false); + break; + #endif + case '~': {/* vt320 style control codes */ + switch(previous_char) + { + case '1': /* home */ + move_cursor_position(false); + break; + case '4': /* end */ + move_cursor_position(true); + break; + default: + break; + } + } break; + default: + break; + } + + previous_char = c; + + return still_in_esc_seq; + } + + /*************************************************************************************************/ + void update_history(char *line) + { + int copy_start_index = DEFAULT_COMMAND_MAX_HISTORY - 2; + + for(int i = 0; i < context.history_count; ++i) + { + if(strcmp(context.history[i], line) == 0) + { + copy_start_index = i - 1; + break; + } + } + + if(context.history_count < DEFAULT_COMMAND_MAX_HISTORY) + { + ++context.history_count; + } + + for(int j = copy_start_index; j >= 0; --j) + { + strcpy(context.history[j+1], context.history[j]); + } + strcpy(context.history[0], line); + } + + /*************************************************************************************************/ + void cycle_history(bool cycle_down) + { + if(cycle_down) + { + --context.history_index; + + if(context.history_index <= -1) + { + context.history_index = -1; + clear_line(); + return; + } + } + else + { + if(context.history_index == context.history_count-1) + { + return; + } + else + { + ++context.history_index; + } + } + + const char *line = context.history[context.history_index]; + + clear_line(); + add_string(line); + } + + /*************************************************************************************************/ + void do_backspace( bool echo ) + { + if ( context.cursor_position > 0 ) + { + --context.cursor_position; + if(echo) + { + serial->write('\b'); + } + remove_char(echo); + } + } + + /*************************************************************************************************/ + void add_string(const char *s) + { + while(*s != 0) + { + add_char(*s++, true); + } + } + + /*************************************************************************************************/ + void add_char(char c, bool echo) + { + /* move the end of the line out to make space */ + for (int i = context.line_length + 1; i > context.cursor_position; --i ) + { + context.line[i] = context.line[i - 1]; + } + + /* insert the character */ + ++context.line_length; + context.line[context.cursor_position] = c; + + if(echo) + { + /* print out the modified part of the ConsoleBuffer */ + serial->write(&context.line[context.cursor_position]); + } + + /* move the cursor back to where it's supposed to be */ + ++context.cursor_position; + if(echo) + { + for (int i = context.line_length; i > context.cursor_position; --i ) + { + serial->write('\b'); + } + } + + context.line[context.line_length] = 0; + } + + /*************************************************************************************************/ + void remove_char(bool echo) + { + /* back the rest of the line up a character */ + for (int i = context.cursor_position; i < context.line_length; ++i ) + { + context.line[i] = context.line[i + 1]; + } + + --context.line_length; + + if(echo) + { + /* print out the modified part of the ConsoleBuffer */ + serial->write( &context.line[context.cursor_position] ); + /* overwrite the extra character at the end */ + serial->write(" \b"); + + + /* move the cursor back to where it's supposed to be */ + for (int i = context.line_length; i > context.cursor_position; --i ) + { + serial->write( '\b' ); + } + } + } + + /*************************************************************************************************/ + bool update_cursor_position(bool move_right) + { + bool updated = false; + + if(move_right) + { + if(context.cursor_position < context.line_length) + { + ++context.cursor_position; + updated = true; + serial->write( "\x1B[C"); + } + } + else + { + if(context.cursor_position > 0) + { + --context.cursor_position; + updated = true; + serial->write("\x1B[D"); + } + } + + return updated; + } + + /*************************************************************************************************/ + void clear_line() + { + int len = context.line_length - context.cursor_position; + while(len-- > 0) + { + serial->write(' '); + } + len = context.line_length; + while(len-- > 0) + { + serial->write("\b \b"); + } + context.cursor_position = 0; + context.line_length = 0; + context.line[0] = 0; + } + + /*************************************************************************************************/ + void move_cursor_position(bool far_right) + { + while(update_cursor_position(far_right)) + { + } + } + + /*************************************************************************************************/ + void clear_tab_choices(void) + { + if(context.tab_info.choices != NULL) + { + free(context.tab_info.choices); + context.tab_info.choices = NULL; + } + } + +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/log/log.cpp Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,78 @@ +/* + * 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 "Wiconnect.h" +#include "log.h" +#include "util/CommandProcessor/CommandProcessor.h" + + +extern ConsoleSerial consoleSerial; + + +/*************************************************************************************************/ +void logDebug(const char *msg, ...) +{ + va_list args; + + consoleSerial.write("[DEBUG] "); + va_start(args, msg); + consoleSerial.vprintf(msg, args); + va_end(args); +} + +/*************************************************************************************************/ +void logInfo(const char *msg, ...) +{ + va_list args; + consoleSerial.write("[INFO] "); + va_start(args, msg); + consoleSerial.vprintf(msg, args); + va_end(args); +} + +/*************************************************************************************************/ +void logWrite(const void *data, int size) +{ + consoleSerial.write(data, size); +} + +/*************************************************************************************************/ +void logInfoWriteStr(const char *msg, const char *s) +{ + consoleSerial.printf("[INFO] %s", msg); + consoleSerial.write(s); + consoleSerial.write("\r\n"); +} + +/*************************************************************************************************/ +void logError(const char *msg, ...) +{ + va_list args; + consoleSerial.write("[ERROR] "); + va_start(args, msg); + consoleSerial.vprintf(msg, args); + va_end(args); +} + +/*************************************************************************************************/ +void logWiconnectError(WiconnectResult result, const char *msg, ...) +{ + va_list args; + consoleSerial.write("[ERROR] "); + va_start(args, msg); + consoleSerial.printf("%s, (%d) %s\r\n", msg, result, Wiconnect::getWiconnectResultStr(result)); + va_end(args); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/log/log.h Mon Aug 11 11:31:32 2014 +0000 @@ -0,0 +1,28 @@ +/* + * 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" + +#define LOG_DEBUG(msg, ...) logDebug(msg "\r\n", ## __VA_ARGS__) +#define LOG_INFO(msg, ...) logInfo(msg "\r\n", ## __VA_ARGS__) +#define LOG_INFO_WRITE_STR(msg, s) logInfoWriteStr(msg, s) +#define LOG_ERROR(msg, ...) logError(msg "\r\n", ## __VA_ARGS__) +#define LOG_WICONNECT_ERROR(result, msg, ...) logWiconnectError(result, msg, ## __VA_ARGS__) + + +void logDebug(const char *msg, ...); +void logInfo(const char *msg, ...); +void logInfoWriteStr(const char *msg, const char *s); +void logError(const char *msg, ...); +void logWiconnectError(wiconnect::WiconnectResult result, const char *msg, ...); +void logWrite(const void *data, int size); +