mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-29 05:21:37 +03:00
Migrate from astyle to clang-format (#8464)
This commit is contained in:
committed by
Max Prokhorov
parent
46190b61f1
commit
19b7a29720
@ -1,14 +1,14 @@
|
||||
/*
|
||||
Arduino.cpp - Mocks for common Arduino APIs
|
||||
Copyright © 2016 Ivan Grokhotkov
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
@ -41,7 +41,6 @@ extern "C" unsigned long micros()
|
||||
return ((time.tv_sec - gtod0.tv_sec) * 1000000) + time.tv_usec - gtod0.tv_usec;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void yield()
|
||||
{
|
||||
run_scheduled_recurrent_functions();
|
||||
@ -58,38 +57,35 @@ extern "C" bool can_yield()
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" void optimistic_yield (uint32_t interval_us)
|
||||
extern "C" void optimistic_yield(uint32_t interval_us)
|
||||
{
|
||||
(void)interval_us;
|
||||
}
|
||||
|
||||
extern "C" void esp_suspend()
|
||||
{
|
||||
}
|
||||
extern "C" void esp_suspend() { }
|
||||
|
||||
extern "C" void esp_schedule()
|
||||
{
|
||||
}
|
||||
extern "C" void esp_schedule() { }
|
||||
|
||||
extern "C" void esp_yield()
|
||||
{
|
||||
}
|
||||
extern "C" void esp_yield() { }
|
||||
|
||||
extern "C" void esp_delay (unsigned long ms)
|
||||
extern "C" void esp_delay(unsigned long ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uint32_t intvl_ms) {
|
||||
bool esp_try_delay(const uint32_t start_ms, const uint32_t timeout_ms, const uint32_t intvl_ms)
|
||||
{
|
||||
uint32_t expired = millis() - start_ms;
|
||||
if (expired >= timeout_ms) {
|
||||
if (expired >= timeout_ms)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
esp_delay(std::min((timeout_ms - expired), intvl_ms));
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void __panic_func(const char* file, int line, const char* func) {
|
||||
extern "C" void __panic_func(const char* file, int line, const char* func)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
(void)func;
|
||||
@ -107,15 +103,14 @@ extern "C" void delayMicroseconds(unsigned int us)
|
||||
}
|
||||
|
||||
#include "cont.h"
|
||||
cont_t* g_pcont = NULL;
|
||||
extern "C" void cont_suspend(cont_t*)
|
||||
{
|
||||
}
|
||||
cont_t* g_pcont = NULL;
|
||||
extern "C" void cont_suspend(cont_t*) { }
|
||||
|
||||
extern "C" int __mockverbose (const char* fmt, ...)
|
||||
extern "C" int __mockverbose(const char* fmt, ...)
|
||||
{
|
||||
(void)fmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mockverbose (const char* fmt, ...) __attribute__ ((weak, alias("__mockverbose"), format (printf, 1, 2)));
|
||||
int mockverbose(const char* fmt, ...)
|
||||
__attribute__((weak, alias("__mockverbose"), format(printf, 1, 2)));
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*
|
||||
Arduino.cpp - Mocks for common Arduino APIs
|
||||
Copyright © 2016 Ivan Grokhotkov
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
@ -17,4 +17,3 @@
|
||||
#include <catch.hpp>
|
||||
#include <sys/time.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <user_interface.h> // wifi_get_ip_info()
|
||||
#include <user_interface.h> // wifi_get_ip_info()
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
@ -41,280 +41,280 @@
|
||||
|
||||
#define MOCK_PORT_SHIFTER 9000
|
||||
|
||||
bool user_exit = false;
|
||||
bool run_once = false;
|
||||
const char* host_interface = nullptr;
|
||||
size_t spiffs_kb = 1024;
|
||||
size_t littlefs_kb = 1024;
|
||||
bool ignore_sigint = false;
|
||||
bool restore_tty = false;
|
||||
bool mockdebug = false;
|
||||
int mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
const char* fspath = nullptr;
|
||||
bool user_exit = false;
|
||||
bool run_once = false;
|
||||
const char* host_interface = nullptr;
|
||||
size_t spiffs_kb = 1024;
|
||||
size_t littlefs_kb = 1024;
|
||||
bool ignore_sigint = false;
|
||||
bool restore_tty = false;
|
||||
bool mockdebug = false;
|
||||
int mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
const char* fspath = nullptr;
|
||||
|
||||
#define STDIN STDIN_FILENO
|
||||
|
||||
static struct termios initial_settings;
|
||||
|
||||
int mockverbose (const char* fmt, ...)
|
||||
int mockverbose(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (mockdebug)
|
||||
return fprintf(stderr, MOCK) + vfprintf(stderr, fmt, ap);
|
||||
return 0;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (mockdebug)
|
||||
return fprintf(stderr, MOCK) + vfprintf(stderr, fmt, ap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mock_start_uart(void)
|
||||
{
|
||||
struct termios settings;
|
||||
struct termios settings;
|
||||
|
||||
if (!isatty(STDIN))
|
||||
{
|
||||
perror("setting tty in raw mode: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcgetattr(STDIN, &initial_settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcgetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
settings = initial_settings;
|
||||
settings.c_lflag &= ~(ignore_sigint ? ISIG : 0);
|
||||
settings.c_lflag &= ~(ECHO | ICANON);
|
||||
settings.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IXON);
|
||||
settings.c_oflag |= (ONLCR);
|
||||
settings.c_cc[VMIN] = 0;
|
||||
settings.c_cc[VTIME] = 0;
|
||||
if (tcsetattr(STDIN, TCSANOW, &settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
restore_tty = true;
|
||||
return 0;
|
||||
if (!isatty(STDIN))
|
||||
{
|
||||
perror("setting tty in raw mode: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcgetattr(STDIN, &initial_settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcgetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
settings = initial_settings;
|
||||
settings.c_lflag &= ~(ignore_sigint ? ISIG : 0);
|
||||
settings.c_lflag &= ~(ECHO | ICANON);
|
||||
settings.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IXON);
|
||||
settings.c_oflag |= (ONLCR);
|
||||
settings.c_cc[VMIN] = 0;
|
||||
settings.c_cc[VTIME] = 0;
|
||||
if (tcsetattr(STDIN, TCSANOW, &settings) < 0)
|
||||
{
|
||||
perror("setting tty in raw mode: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
restore_tty = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mock_stop_uart(void)
|
||||
{
|
||||
if (!restore_tty) return 0;
|
||||
if (!isatty(STDIN)) {
|
||||
perror("restoring tty: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcsetattr(STDIN, TCSANOW, &initial_settings) < 0)
|
||||
{
|
||||
perror("restoring tty: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
printf("\e[?25h"); // show cursor
|
||||
return (0);
|
||||
if (!restore_tty)
|
||||
return 0;
|
||||
if (!isatty(STDIN))
|
||||
{
|
||||
perror("restoring tty: isatty(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
if (tcsetattr(STDIN, TCSANOW, &initial_settings) < 0)
|
||||
{
|
||||
perror("restoring tty: tcsetattr(STDIN)");
|
||||
return -1;
|
||||
}
|
||||
printf("\e[?25h"); // show cursor
|
||||
return (0);
|
||||
}
|
||||
|
||||
static uint8_t mock_read_uart(void)
|
||||
{
|
||||
uint8_t ch = 0;
|
||||
return (read(STDIN, &ch, 1) == 1) ? ch : 0;
|
||||
uint8_t ch = 0;
|
||||
return (read(STDIN, &ch, 1) == 1) ? ch : 0;
|
||||
}
|
||||
|
||||
void help (const char* argv0, int exitcode)
|
||||
void help(const char* argv0, int exitcode)
|
||||
{
|
||||
printf(
|
||||
"%s - compiled with esp8266/arduino emulator\n"
|
||||
"options:\n"
|
||||
"\t-h\n"
|
||||
"\tnetwork:\n"
|
||||
"\t-i <interface> - use this interface for IP address\n"
|
||||
"\t-l - bind tcp/udp servers to interface only (not 0.0.0.0)\n"
|
||||
"\t-s - port shifter (default: %d, when root: 0)\n"
|
||||
"\tterminal:\n"
|
||||
"\t-b - blocking tty/mocked-uart (default: not blocking tty)\n"
|
||||
"\t-T - show timestamp on output\n"
|
||||
"\tFS:\n"
|
||||
"\t-P - path for fs-persistent files (default: %s-)\n"
|
||||
"\t-S - spiffs size in KBytes (default: %zd)\n"
|
||||
"\t-L - littlefs size in KBytes (default: %zd)\n"
|
||||
"\t (spiffs, littlefs: negative value will force mismatched size)\n"
|
||||
"\tgeneral:\n"
|
||||
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
||||
"\t-f - no throttle (possibly 100%%CPU)\n"
|
||||
"\t-1 - run loop once then exit (for host testing)\n"
|
||||
"\t-v - verbose\n"
|
||||
, argv0, MOCK_PORT_SHIFTER, argv0, spiffs_kb, littlefs_kb);
|
||||
exit(exitcode);
|
||||
printf("%s - compiled with esp8266/arduino emulator\n"
|
||||
"options:\n"
|
||||
"\t-h\n"
|
||||
"\tnetwork:\n"
|
||||
"\t-i <interface> - use this interface for IP address\n"
|
||||
"\t-l - bind tcp/udp servers to interface only (not 0.0.0.0)\n"
|
||||
"\t-s - port shifter (default: %d, when root: 0)\n"
|
||||
"\tterminal:\n"
|
||||
"\t-b - blocking tty/mocked-uart (default: not blocking tty)\n"
|
||||
"\t-T - show timestamp on output\n"
|
||||
"\tFS:\n"
|
||||
"\t-P - path for fs-persistent files (default: %s-)\n"
|
||||
"\t-S - spiffs size in KBytes (default: %zd)\n"
|
||||
"\t-L - littlefs size in KBytes (default: %zd)\n"
|
||||
"\t (spiffs, littlefs: negative value will force mismatched size)\n"
|
||||
"\tgeneral:\n"
|
||||
"\t-c - ignore CTRL-C (send it via Serial)\n"
|
||||
"\t-f - no throttle (possibly 100%%CPU)\n"
|
||||
"\t-1 - run loop once then exit (for host testing)\n"
|
||||
"\t-v - verbose\n",
|
||||
argv0, MOCK_PORT_SHIFTER, argv0, spiffs_kb, littlefs_kb);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
static struct option options[] =
|
||||
{
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "fast", no_argument, NULL, 'f' },
|
||||
{ "local", no_argument, NULL, 'l' },
|
||||
{ "sigint", no_argument, NULL, 'c' },
|
||||
{ "blockinguart", no_argument, NULL, 'b' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "timestamp", no_argument, NULL, 'T' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "fspath", required_argument, NULL, 'P' },
|
||||
{ "spiffskb", required_argument, NULL, 'S' },
|
||||
{ "littlefskb", required_argument, NULL, 'L' },
|
||||
{ "portshifter", required_argument, NULL, 's' },
|
||||
{ "once", no_argument, NULL, '1' },
|
||||
static struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "fast", no_argument, NULL, 'f' },
|
||||
{ "local", no_argument, NULL, 'l' },
|
||||
{ "sigint", no_argument, NULL, 'c' },
|
||||
{ "blockinguart", no_argument, NULL, 'b' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "timestamp", no_argument, NULL, 'T' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "fspath", required_argument, NULL, 'P' },
|
||||
{ "spiffskb", required_argument, NULL, 'S' },
|
||||
{ "littlefskb", required_argument, NULL, 'L' },
|
||||
{ "portshifter", required_argument, NULL, 's' },
|
||||
{ "once", no_argument, NULL, '1' },
|
||||
};
|
||||
|
||||
void cleanup ()
|
||||
void cleanup()
|
||||
{
|
||||
mock_stop_spiffs();
|
||||
mock_stop_littlefs();
|
||||
mock_stop_uart();
|
||||
mock_stop_spiffs();
|
||||
mock_stop_littlefs();
|
||||
mock_stop_uart();
|
||||
}
|
||||
|
||||
void make_fs_filename (String& name, const char* fspath, const char* argv0)
|
||||
void make_fs_filename(String& name, const char* fspath, const char* argv0)
|
||||
{
|
||||
name.clear();
|
||||
if (fspath)
|
||||
{
|
||||
int lastSlash = -1;
|
||||
for (int i = 0; argv0[i]; i++)
|
||||
if (argv0[i] == '/')
|
||||
lastSlash = i;
|
||||
name = fspath;
|
||||
name += '/';
|
||||
name += &argv0[lastSlash + 1];
|
||||
}
|
||||
else
|
||||
name = argv0;
|
||||
name.clear();
|
||||
if (fspath)
|
||||
{
|
||||
int lastSlash = -1;
|
||||
for (int i = 0; argv0[i]; i++)
|
||||
if (argv0[i] == '/')
|
||||
lastSlash = i;
|
||||
name = fspath;
|
||||
name += '/';
|
||||
name += &argv0[lastSlash + 1];
|
||||
}
|
||||
else
|
||||
name = argv0;
|
||||
}
|
||||
|
||||
void control_c (int sig)
|
||||
void control_c(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
(void)sig;
|
||||
|
||||
if (user_exit)
|
||||
{
|
||||
fprintf(stderr, MOCK "stuck, killing\n");
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
user_exit = true;
|
||||
if (user_exit)
|
||||
{
|
||||
fprintf(stderr, MOCK "stuck, killing\n");
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
user_exit = true;
|
||||
}
|
||||
|
||||
int main (int argc, char* const argv [])
|
||||
int main(int argc, char* const argv[])
|
||||
{
|
||||
bool fast = false;
|
||||
blocking_uart = false; // global
|
||||
bool fast = false;
|
||||
blocking_uart = false; // global
|
||||
|
||||
signal(SIGINT, control_c);
|
||||
signal(SIGTERM, control_c);
|
||||
if (geteuid() == 0)
|
||||
mock_port_shifter = 0;
|
||||
else
|
||||
mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
signal(SIGINT, control_c);
|
||||
signal(SIGTERM, control_c);
|
||||
if (geteuid() == 0)
|
||||
mock_port_shifter = 0;
|
||||
else
|
||||
mock_port_shifter = MOCK_PORT_SHIFTER;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL);
|
||||
if (n < 0)
|
||||
break;
|
||||
switch (n)
|
||||
{
|
||||
case 'h':
|
||||
help(argv[0], EXIT_SUCCESS);
|
||||
break;
|
||||
case 'i':
|
||||
host_interface = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
global_ipv4_netfmt = NO_GLOBAL_BINDING;
|
||||
break;
|
||||
case 's':
|
||||
mock_port_shifter = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
ignore_sigint = true;
|
||||
break;
|
||||
case 'f':
|
||||
fast = true;
|
||||
break;
|
||||
case 'S':
|
||||
spiffs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'L':
|
||||
littlefs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
fspath = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
blocking_uart = true;
|
||||
break;
|
||||
case 'v':
|
||||
mockdebug = true;
|
||||
break;
|
||||
case 'T':
|
||||
serial_timestamp = true;
|
||||
break;
|
||||
case '1':
|
||||
run_once = true;
|
||||
break;
|
||||
default:
|
||||
help(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL);
|
||||
if (n < 0)
|
||||
break;
|
||||
switch (n)
|
||||
{
|
||||
case 'h':
|
||||
help(argv[0], EXIT_SUCCESS);
|
||||
break;
|
||||
case 'i':
|
||||
host_interface = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
global_ipv4_netfmt = NO_GLOBAL_BINDING;
|
||||
break;
|
||||
case 's':
|
||||
mock_port_shifter = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
ignore_sigint = true;
|
||||
break;
|
||||
case 'f':
|
||||
fast = true;
|
||||
break;
|
||||
case 'S':
|
||||
spiffs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'L':
|
||||
littlefs_kb = atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
fspath = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
blocking_uart = true;
|
||||
break;
|
||||
case 'v':
|
||||
mockdebug = true;
|
||||
break;
|
||||
case 'T':
|
||||
serial_timestamp = true;
|
||||
break;
|
||||
case '1':
|
||||
run_once = true;
|
||||
break;
|
||||
default:
|
||||
help(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
mockverbose("server port shifter: %d\n", mock_port_shifter);
|
||||
mockverbose("server port shifter: %d\n", mock_port_shifter);
|
||||
|
||||
if (spiffs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-spiffs";
|
||||
name += String(spiffs_kb > 0? spiffs_kb: -spiffs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_spiffs(name, spiffs_kb);
|
||||
}
|
||||
if (spiffs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-spiffs";
|
||||
name += String(spiffs_kb > 0 ? spiffs_kb : -spiffs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_spiffs(name, spiffs_kb);
|
||||
}
|
||||
|
||||
if (littlefs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-littlefs";
|
||||
name += String(littlefs_kb > 0? littlefs_kb: -littlefs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_littlefs(name, littlefs_kb);
|
||||
}
|
||||
if (littlefs_kb)
|
||||
{
|
||||
String name;
|
||||
make_fs_filename(name, fspath, argv[0]);
|
||||
name += "-littlefs";
|
||||
name += String(littlefs_kb > 0 ? littlefs_kb : -littlefs_kb, DEC);
|
||||
name += "KB";
|
||||
mock_start_littlefs(name, littlefs_kb);
|
||||
}
|
||||
|
||||
// setup global global_ipv4_netfmt
|
||||
wifi_get_ip_info(0, nullptr);
|
||||
// setup global global_ipv4_netfmt
|
||||
wifi_get_ip_info(0, nullptr);
|
||||
|
||||
if (!blocking_uart)
|
||||
{
|
||||
// set stdin to non blocking mode
|
||||
mock_start_uart();
|
||||
}
|
||||
if (!blocking_uart)
|
||||
{
|
||||
// set stdin to non blocking mode
|
||||
mock_start_uart();
|
||||
}
|
||||
|
||||
// install exit handler in case Esp.restart() is called
|
||||
atexit(cleanup);
|
||||
// install exit handler in case Esp.restart() is called
|
||||
atexit(cleanup);
|
||||
|
||||
// first call to millis(): now is millis() and micros() beginning
|
||||
millis();
|
||||
// first call to millis(): now is millis() and micros() beginning
|
||||
millis();
|
||||
|
||||
setup();
|
||||
while (!user_exit)
|
||||
{
|
||||
uint8_t data = mock_read_uart();
|
||||
setup();
|
||||
while (!user_exit)
|
||||
{
|
||||
uint8_t data = mock_read_uart();
|
||||
|
||||
if (data)
|
||||
uart_new_data(UART0, data);
|
||||
if (!fast)
|
||||
usleep(1000); // not 100% cpu, ~1000 loops per second
|
||||
loop();
|
||||
loop_end();
|
||||
check_incoming_udp();
|
||||
if (data)
|
||||
uart_new_data(UART0, data);
|
||||
if (!fast)
|
||||
usleep(1000); // not 100% cpu, ~1000 loops per second
|
||||
loop();
|
||||
loop_end();
|
||||
check_incoming_udp();
|
||||
|
||||
if (run_once)
|
||||
user_exit = true;
|
||||
}
|
||||
cleanup();
|
||||
if (run_once)
|
||||
user_exit = true;
|
||||
}
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,15 +3,14 @@
|
||||
|
||||
LittleFSMock* littlefs_mock = nullptr;
|
||||
|
||||
void mock_start_littlefs (const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
void mock_start_littlefs(const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
{
|
||||
littlefs_mock = new LittleFSMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
littlefs_mock = new LittleFSMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
}
|
||||
|
||||
void mock_stop_littlefs ()
|
||||
void mock_stop_littlefs()
|
||||
{
|
||||
if (littlefs_mock)
|
||||
delete littlefs_mock;
|
||||
littlefs_mock = nullptr;
|
||||
if (littlefs_mock)
|
||||
delete littlefs_mock;
|
||||
littlefs_mock = nullptr;
|
||||
}
|
||||
|
||||
|
@ -3,15 +3,14 @@
|
||||
|
||||
SpiffsMock* spiffs_mock = nullptr;
|
||||
|
||||
void mock_start_spiffs (const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
void mock_start_spiffs(const String& fname, size_t size_kb, size_t block_kb, size_t page_b)
|
||||
{
|
||||
spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
spiffs_mock = new SpiffsMock(size_kb * 1024, block_kb * 1024, page_b, fname);
|
||||
}
|
||||
|
||||
void mock_stop_spiffs ()
|
||||
void mock_stop_spiffs()
|
||||
{
|
||||
if (spiffs_mock)
|
||||
delete spiffs_mock;
|
||||
spiffs_mock = nullptr;
|
||||
if (spiffs_mock)
|
||||
delete spiffs_mock;
|
||||
spiffs_mock = nullptr;
|
||||
}
|
||||
|
||||
|
@ -33,28 +33,28 @@
|
||||
#include <poll.h>
|
||||
#include <map>
|
||||
|
||||
std::map<int,UdpContext*> udps;
|
||||
std::map<int, UdpContext*> udps;
|
||||
|
||||
void register_udp (int sock, UdpContext* udp)
|
||||
void register_udp(int sock, UdpContext* udp)
|
||||
{
|
||||
if (udp)
|
||||
udps[sock] = udp;
|
||||
else
|
||||
udps.erase(sock);
|
||||
if (udp)
|
||||
udps[sock] = udp;
|
||||
else
|
||||
udps.erase(sock);
|
||||
}
|
||||
|
||||
void check_incoming_udp ()
|
||||
void check_incoming_udp()
|
||||
{
|
||||
// check incoming udp
|
||||
for (auto& udp: udps)
|
||||
{
|
||||
pollfd p;
|
||||
p.fd = udp.first;
|
||||
p.events = POLLIN;
|
||||
if (poll(&p, 1, 0) && p.revents == POLLIN)
|
||||
{
|
||||
mockverbose("UDP poll(%d) -> cb\r", p.fd);
|
||||
udp.second->mock_cb();
|
||||
}
|
||||
}
|
||||
// check incoming udp
|
||||
for (auto& udp : udps)
|
||||
{
|
||||
pollfd p;
|
||||
p.fd = udp.first;
|
||||
p.events = POLLIN;
|
||||
if (poll(&p, 1, 0) && p.revents == POLLIN)
|
||||
{
|
||||
mockverbose("UDP poll(%d) -> cb\r", p.fd);
|
||||
udp.second->mock_cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,168 +39,173 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
int mockSockSetup (int sock)
|
||||
int mockSockSetup(int sock)
|
||||
{
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
perror("socket fcntl(O_NONBLOCK)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
perror("socket fcntl(O_NONBLOCK)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
int i = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i) == -1)
|
||||
{
|
||||
perror("sockopt(SO_NOSIGPIPE)(macOS)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
int i = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &i, sizeof i) == -1)
|
||||
{
|
||||
perror("sockopt(SO_NOSIGPIPE)(macOS)");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
return sock;
|
||||
}
|
||||
|
||||
int mockConnect (uint32_t ipv4, int& sock, int port)
|
||||
int mockConnect(uint32_t ipv4, int& sock, int port)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
if ((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext:connect: ::socket()");
|
||||
return 0;
|
||||
}
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
memcpy(&server.sin_addr, &ipv4, 4);
|
||||
if (::connect(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext::connect: ::connect()");
|
||||
return 0;
|
||||
}
|
||||
struct sockaddr_in server;
|
||||
if ((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext:connect: ::socket()");
|
||||
return 0;
|
||||
}
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
memcpy(&server.sin_addr, &ipv4, 4);
|
||||
if (::connect(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "ClientContext::connect: ::connect()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mockSockSetup(sock) == -1? 0: 1;
|
||||
return mockSockSetup(sock) == -1 ? 0 : 1;
|
||||
}
|
||||
|
||||
ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize)
|
||||
ssize_t mockFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize)
|
||||
{
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::read(sock, ccinbuf + ccinbufsize, maxread);
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::read(sock, ccinbuf + ccinbufsize, maxread);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
// connection closed
|
||||
// nothing is read
|
||||
return 0;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
// connection closed
|
||||
// nothing is read
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::(read/peek fd=%i): filling buffer for %zd bytes: %s\n", sock, maxread, strerror(errno));
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
{
|
||||
fprintf(stderr,
|
||||
MOCK "ClientContext::(read/peek fd=%i): filling buffer for %zd bytes: %s\n",
|
||||
sock, maxread, strerror(errno));
|
||||
// error
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
ccinbufsize += ret;
|
||||
return ret;
|
||||
ccinbufsize += ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t mockPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
ssize_t mockPeekBytes(int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
// usersize==0: peekAvailable()
|
||||
|
||||
if (usersize > CCBUFSIZE)
|
||||
mockverbose("CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE, usersize - CCBUFSIZE, usersize);
|
||||
if (usersize > CCBUFSIZE)
|
||||
mockverbose("CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE,
|
||||
usersize - CCBUFSIZE, usersize);
|
||||
|
||||
struct pollfd p;
|
||||
size_t retsize = 0;
|
||||
do
|
||||
{
|
||||
if (usersize && usersize <= ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// check incoming data data
|
||||
if (mockFillInBuf(sock, ccinbuf, ccinbufsize) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
struct pollfd p;
|
||||
size_t retsize = 0;
|
||||
do
|
||||
{
|
||||
if (usersize && usersize <= ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// check incoming data data
|
||||
if (mockFillInBuf(sock, ccinbuf, ccinbufsize) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (usersize == 0 && ccinbufsize)
|
||||
// peekAvailable
|
||||
return ccinbufsize;
|
||||
|
||||
if (usersize <= ccinbufsize)
|
||||
{
|
||||
// data just received
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// wait for more data until timeout
|
||||
p.fd = sock;
|
||||
p.events = POLLIN;
|
||||
} while (poll(&p, 1, timeout_ms) == 1);
|
||||
|
||||
if (usersize <= ccinbufsize)
|
||||
{
|
||||
// data just received
|
||||
retsize = usersize;
|
||||
break;
|
||||
}
|
||||
|
||||
// wait for more data until timeout
|
||||
p.fd = sock;
|
||||
p.events = POLLIN;
|
||||
} while (poll(&p, 1, timeout_ms) == 1);
|
||||
|
||||
if (dst)
|
||||
{
|
||||
memcpy(dst, ccinbuf, retsize);
|
||||
}
|
||||
|
||||
return retsize;
|
||||
return retsize;
|
||||
}
|
||||
|
||||
ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
ssize_t mockRead(int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
ssize_t copied = mockPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
if (copied < 0)
|
||||
return -1;
|
||||
// swallow (XXX use a circular buffer)
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
return copied;
|
||||
ssize_t copied = mockPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
if (copied < 0)
|
||||
return -1;
|
||||
// swallow (XXX use a circular buffer)
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
return copied;
|
||||
}
|
||||
|
||||
ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms)
|
||||
{
|
||||
size_t sent = 0;
|
||||
while (sent < size)
|
||||
{
|
||||
|
||||
struct pollfd p;
|
||||
p.fd = sock;
|
||||
p.events = POLLOUT;
|
||||
int ret = poll(&p, 1, timeout_ms);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
ssize_t mockWrite(int sock, const uint8_t* data, size_t size, int timeout_ms)
|
||||
{
|
||||
size_t sent = 0;
|
||||
while (sent < size)
|
||||
{
|
||||
struct pollfd p;
|
||||
p.fd = sock;
|
||||
p.events = POLLOUT;
|
||||
int ret = poll(&p, 1, timeout_ms);
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
#ifndef MSG_NOSIGNAL
|
||||
ret = ::write(sock, data + sent, size - sent);
|
||||
ret = ::write(sock, data + sent, size - sent);
|
||||
#else
|
||||
ret = ::send(sock, data + sent, size - sent, MSG_NOSIGNAL);
|
||||
ret = ::send(sock, data + sent, size - sent, MSG_NOSIGNAL);
|
||||
#endif
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write/send(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
sent += ret;
|
||||
if (sent < size)
|
||||
fprintf(stderr, MOCK "ClientContext::write: sent %d bytes (%zd / %zd)\n", ret, sent, size);
|
||||
}
|
||||
}
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "ClientContext::write/send(%d): %s\n", sock, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
sent += ret;
|
||||
if (sent < size)
|
||||
fprintf(stderr, MOCK "ClientContext::write: sent %d bytes (%zd / %zd)\n", ret, sent,
|
||||
size);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_ESP_WIFI
|
||||
mockverbose(MOCK "ClientContext::write: total sent %zd bytes\n", sent);
|
||||
#endif
|
||||
return sent;
|
||||
return sent;
|
||||
}
|
||||
|
@ -35,23 +35,24 @@
|
||||
#include <WiFiClient.h>
|
||||
#include <include/ClientContext.h>
|
||||
|
||||
#include <netdb.h> // gethostbyname
|
||||
#include <netdb.h> // gethostbyname
|
||||
|
||||
err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *callback_arg)
|
||||
err_t dns_gethostbyname(const char* hostname, ip_addr_t* addr, dns_found_callback found,
|
||||
void* callback_arg)
|
||||
{
|
||||
(void)callback_arg;
|
||||
(void)found;
|
||||
struct hostent* hbn = gethostbyname(hostname);
|
||||
if (!hbn)
|
||||
return ERR_TIMEOUT;
|
||||
addr->addr = *(uint32_t*)hbn->h_addr_list[0];
|
||||
return ERR_OK;
|
||||
(void)callback_arg;
|
||||
(void)found;
|
||||
struct hostent* hbn = gethostbyname(hostname);
|
||||
if (!hbn)
|
||||
return ERR_TIMEOUT;
|
||||
addr->addr = *(uint32_t*)hbn->h_addr_list[0];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static struct tcp_pcb mock_tcp_pcb;
|
||||
tcp_pcb* tcp_new (void)
|
||||
tcp_pcb* tcp_new(void)
|
||||
{
|
||||
// this is useless
|
||||
// ClientContext is setting the source port and we don't care here
|
||||
return &mock_tcp_pcb;
|
||||
// this is useless
|
||||
// ClientContext is setting the source port and we don't care here
|
||||
return &mock_tcp_pcb;
|
||||
}
|
||||
|
@ -32,46 +32,53 @@
|
||||
#ifndef EEPROM_MOCK
|
||||
#define EEPROM_MOCK
|
||||
|
||||
class EEPROMClass {
|
||||
class EEPROMClass
|
||||
{
|
||||
public:
|
||||
EEPROMClass(uint32_t sector);
|
||||
EEPROMClass(void);
|
||||
~EEPROMClass();
|
||||
EEPROMClass(uint32_t sector);
|
||||
EEPROMClass(void);
|
||||
~EEPROMClass();
|
||||
|
||||
void begin(size_t size);
|
||||
uint8_t read(int address);
|
||||
void write(int address, uint8_t val);
|
||||
bool commit();
|
||||
void end();
|
||||
void begin(size_t size);
|
||||
uint8_t read(int address);
|
||||
void write(int address, uint8_t val);
|
||||
bool commit();
|
||||
void end();
|
||||
|
||||
template<typename T>
|
||||
T& get(int const address, T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((uint8_t*)&t)[i] = read(i);
|
||||
return t;
|
||||
}
|
||||
template<typename T>
|
||||
T& get(int const address, T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
((uint8_t*)&t)[i] = read(i);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& put(int const address, const T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
write(i, ((uint8_t*)&t)[i]);
|
||||
return t;
|
||||
}
|
||||
template<typename T>
|
||||
const T& put(int const address, const T& t)
|
||||
{
|
||||
if (address < 0 || address + sizeof(T) > _size)
|
||||
return t;
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
write(i, ((uint8_t*)&t)[i]);
|
||||
return t;
|
||||
}
|
||||
|
||||
size_t length() { return _size; }
|
||||
size_t length()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
//uint8_t& operator[](int const address) { return read(address); }
|
||||
uint8_t operator[] (int address) { return read(address); }
|
||||
// uint8_t& operator[](int const address) { return read(address); }
|
||||
uint8_t operator[](int address)
|
||||
{
|
||||
return read(address);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t _size = 0;
|
||||
int _fd = -1;
|
||||
size_t _size = 0;
|
||||
int _fd = -1;
|
||||
};
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
|
@ -42,60 +42,82 @@
|
||||
static uint8_t _mode[GPIONUM];
|
||||
static uint8_t _gpio[GPIONUM];
|
||||
|
||||
void pinMode (uint8_t pin, uint8_t mode)
|
||||
void pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
#define xxx(mode) case mode: m=STRHELPER(mode); break
|
||||
const char* m;
|
||||
switch (mode)
|
||||
{
|
||||
case INPUT: m="INPUT"; break;
|
||||
case OUTPUT: m="OUTPUT"; break;
|
||||
case INPUT_PULLUP: m="INPUT_PULLUP"; break;
|
||||
case OUTPUT_OPEN_DRAIN: m="OUTPUT_OPEN_DRAIN"; break;
|
||||
case INPUT_PULLDOWN_16: m="INPUT_PULLDOWN_16"; break;
|
||||
case WAKEUP_PULLUP: m="WAKEUP_PULLUP"; break;
|
||||
case WAKEUP_PULLDOWN: m="WAKEUP_PULLDOWN"; break;
|
||||
default: m="(special)";
|
||||
}
|
||||
VERBOSE("gpio%d: mode='%s'\n", pin, m);
|
||||
#define xxx(mode) \
|
||||
case mode: \
|
||||
m = STRHELPER(mode); \
|
||||
break
|
||||
const char* m;
|
||||
switch (mode)
|
||||
{
|
||||
case INPUT:
|
||||
m = "INPUT";
|
||||
break;
|
||||
case OUTPUT:
|
||||
m = "OUTPUT";
|
||||
break;
|
||||
case INPUT_PULLUP:
|
||||
m = "INPUT_PULLUP";
|
||||
break;
|
||||
case OUTPUT_OPEN_DRAIN:
|
||||
m = "OUTPUT_OPEN_DRAIN";
|
||||
break;
|
||||
case INPUT_PULLDOWN_16:
|
||||
m = "INPUT_PULLDOWN_16";
|
||||
break;
|
||||
case WAKEUP_PULLUP:
|
||||
m = "WAKEUP_PULLUP";
|
||||
break;
|
||||
case WAKEUP_PULLDOWN:
|
||||
m = "WAKEUP_PULLDOWN";
|
||||
break;
|
||||
default:
|
||||
m = "(special)";
|
||||
}
|
||||
VERBOSE("gpio%d: mode='%s'\n", pin, m);
|
||||
|
||||
if (pin < GPIONUM)
|
||||
{
|
||||
_mode[pin] = mode;
|
||||
_mode[pin] = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val)
|
||||
{
|
||||
VERBOSE("digitalWrite(pin=%d val=%d)\n", pin, val);
|
||||
if (pin < GPIONUM) {
|
||||
VERBOSE("digitalWrite(pin=%d val=%d)\n", pin, val);
|
||||
if (pin < GPIONUM)
|
||||
{
|
||||
_gpio[pin] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void analogWrite(uint8_t pin, int val)
|
||||
{
|
||||
VERBOSE("analogWrite(pin=%d, val=%d\n", pin, val);
|
||||
VERBOSE("analogWrite(pin=%d, val=%d\n", pin, val);
|
||||
}
|
||||
|
||||
int analogRead(uint8_t pin)
|
||||
{
|
||||
(void)pin;
|
||||
return 512;
|
||||
(void)pin;
|
||||
return 512;
|
||||
}
|
||||
|
||||
void analogWriteRange(uint32_t range)
|
||||
{
|
||||
VERBOSE("analogWriteRange(range=%d)\n", range);
|
||||
VERBOSE("analogWriteRange(range=%d)\n", range);
|
||||
}
|
||||
|
||||
int digitalRead(uint8_t pin)
|
||||
{
|
||||
VERBOSE("digitalRead(%d)\n", pin);
|
||||
VERBOSE("digitalRead(%d)\n", pin);
|
||||
|
||||
if (pin < GPIONUM) {
|
||||
return _gpio[pin] != 0;
|
||||
} else {
|
||||
return 0;
|
||||
if (pin < GPIONUM)
|
||||
{
|
||||
return _gpio[pin] != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -42,52 +42,52 @@
|
||||
|
||||
#define EEPROM_FILE_NAME "eeprom"
|
||||
|
||||
EEPROMClass::EEPROMClass ()
|
||||
{
|
||||
}
|
||||
EEPROMClass::EEPROMClass() { }
|
||||
|
||||
EEPROMClass::~EEPROMClass ()
|
||||
EEPROMClass::~EEPROMClass()
|
||||
{
|
||||
if (_fd >= 0)
|
||||
close(_fd);
|
||||
if (_fd >= 0)
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
void EEPROMClass::begin(size_t size)
|
||||
{
|
||||
_size = size;
|
||||
if ( (_fd = open(EEPROM_FILE_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1
|
||||
|| ftruncate(_fd, size) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "EEPROM: cannot open/create '%s' for r/w: %s\n\r", EEPROM_FILE_NAME, strerror(errno));
|
||||
_fd = -1;
|
||||
}
|
||||
_size = size;
|
||||
if ((_fd = open(EEPROM_FILE_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))
|
||||
== -1
|
||||
|| ftruncate(_fd, size) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "EEPROM: cannot open/create '%s' for r/w: %s\n\r", EEPROM_FILE_NAME,
|
||||
strerror(errno));
|
||||
_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void EEPROMClass::end()
|
||||
{
|
||||
if (_fd != -1)
|
||||
close(_fd);
|
||||
if (_fd != -1)
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
bool EEPROMClass::commit()
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t EEPROMClass::read (int x)
|
||||
uint8_t EEPROMClass::read(int x)
|
||||
{
|
||||
char c = 0;
|
||||
if (pread(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
return c;
|
||||
char c = 0;
|
||||
if (pread(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
return c;
|
||||
}
|
||||
|
||||
void EEPROMClass::write (int x, uint8_t c)
|
||||
void EEPROMClass::write(int x, uint8_t c)
|
||||
{
|
||||
if (x > (int)_size)
|
||||
fprintf(stderr, MOCK "### eeprom beyond\r\n");
|
||||
else if (pwrite(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
if (x > (int)_size)
|
||||
fprintf(stderr, MOCK "### eeprom beyond\r\n");
|
||||
else if (pwrite(_fd, &c, 1, x) != 1)
|
||||
fprintf(stderr, MOCK "eeprom: %s\n\r", strerror(errno));
|
||||
}
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_EEPROM)
|
||||
|
@ -36,204 +36,223 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned long long operator"" _kHz(unsigned long long x) {
|
||||
unsigned long long operator"" _kHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MHz(unsigned long long x) {
|
||||
unsigned long long operator"" _MHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000 * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GHz(unsigned long long x) {
|
||||
unsigned long long operator"" _GHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000 * 1000 * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _kBit(unsigned long long x) {
|
||||
unsigned long long operator"" _kBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MBit(unsigned long long x) {
|
||||
unsigned long long operator"" _MBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GBit(unsigned long long x) {
|
||||
unsigned long long operator"" _GBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _kB(unsigned long long x) {
|
||||
unsigned long long operator"" _kB(unsigned long long x)
|
||||
{
|
||||
return x * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MB(unsigned long long x) {
|
||||
unsigned long long operator"" _MB(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GB(unsigned long long x) {
|
||||
unsigned long long operator"" _GB(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
uint32_t _SPIFFS_start;
|
||||
|
||||
void eboot_command_write (struct eboot_command* cmd)
|
||||
void eboot_command_write(struct eboot_command* cmd)
|
||||
{
|
||||
(void)cmd;
|
||||
(void)cmd;
|
||||
}
|
||||
|
||||
EspClass ESP;
|
||||
|
||||
void EspClass::restart ()
|
||||
void EspClass::restart()
|
||||
{
|
||||
mockverbose("Esp.restart(): exiting\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
mockverbose("Esp.restart(): exiting\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getChipId()
|
||||
{
|
||||
return 0xee1337;
|
||||
return 0xee1337;
|
||||
}
|
||||
|
||||
bool EspClass::checkFlashConfig(bool needsEquals)
|
||||
{
|
||||
(void) needsEquals;
|
||||
return true;
|
||||
(void)needsEquals;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getSketchSize()
|
||||
{
|
||||
return 400000;
|
||||
return 400000;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeHeap()
|
||||
{
|
||||
return 30000;
|
||||
return 30000;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getMaxFreeBlockSize()
|
||||
{
|
||||
return 20000;
|
||||
return 20000;
|
||||
}
|
||||
|
||||
String EspClass::getResetReason()
|
||||
{
|
||||
return "Power on";
|
||||
return "Power on";
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeSketchSpace()
|
||||
{
|
||||
return 4 * 1024 * 1024;
|
||||
return 4 * 1024 * 1024;
|
||||
}
|
||||
|
||||
const char *EspClass::getSdkVersion()
|
||||
const char* EspClass::getSdkVersion()
|
||||
{
|
||||
return "2.5.0";
|
||||
return "2.5.0";
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipSpeed()
|
||||
{
|
||||
return 40;
|
||||
return 40;
|
||||
}
|
||||
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag) {
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag)
|
||||
{
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
|
||||
if (hfree) *hfree = hf;
|
||||
if (hmax) *hmax = hm;
|
||||
if (hfrag) *hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
if (hfree)
|
||||
*hfree = hf;
|
||||
if (hmax)
|
||||
*hmax = hm;
|
||||
if (hfrag)
|
||||
*hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
}
|
||||
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint32_t* hmax, uint8_t* hfrag) {
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
void EspClass::getHeapStats(uint32_t* hfree, uint32_t* hmax, uint8_t* hfrag)
|
||||
{
|
||||
uint32_t hf = 10 * 1024;
|
||||
float hm = 1 * 1024;
|
||||
|
||||
if (hfree) *hfree = hf;
|
||||
if (hmax) *hmax = hm;
|
||||
if (hfrag) *hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
if (hfree)
|
||||
*hfree = hf;
|
||||
if (hmax)
|
||||
*hmax = hm;
|
||||
if (hfrag)
|
||||
*hfrag = 100 - (sqrt(hm) * 100) / hf;
|
||||
}
|
||||
|
||||
bool EspClass::flashEraseSector(uint32_t sector)
|
||||
{
|
||||
(void) sector;
|
||||
return true;
|
||||
(void)sector;
|
||||
return true;
|
||||
}
|
||||
|
||||
FlashMode_t EspClass::getFlashChipMode()
|
||||
{
|
||||
return FM_DOUT;
|
||||
return FM_DOUT;
|
||||
}
|
||||
|
||||
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
|
||||
{
|
||||
(void) byte;
|
||||
return FM_DOUT;
|
||||
(void)byte;
|
||||
return FM_DOUT;
|
||||
}
|
||||
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint32_t *data, size_t size)
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint32_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint8_t *data, size_t size)
|
||||
bool EspClass::flashWrite(uint32_t offset, const uint8_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
bool EspClass::flashRead(uint32_t offset, uint32_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EspClass::flashRead(uint32_t offset, uint8_t *data, size_t size)
|
||||
bool EspClass::flashRead(uint32_t offset, uint8_t* data, size_t size)
|
||||
{
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
(void)offset;
|
||||
(void)data;
|
||||
(void)size;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t EspClass::magicFlashChipSize(uint8_t byte) {
|
||||
switch(byte & 0x0F) {
|
||||
case 0x0: // 4 Mbit (512KB)
|
||||
return (512_kB);
|
||||
case 0x1: // 2 MBit (256KB)
|
||||
return (256_kB);
|
||||
case 0x2: // 8 MBit (1MB)
|
||||
return (1_MB);
|
||||
case 0x3: // 16 MBit (2MB)
|
||||
return (2_MB);
|
||||
case 0x4: // 32 MBit (4MB)
|
||||
return (4_MB);
|
||||
case 0x8: // 64 MBit (8MB)
|
||||
return (8_MB);
|
||||
case 0x9: // 128 MBit (16MB)
|
||||
return (16_MB);
|
||||
default: // fail?
|
||||
return 0;
|
||||
uint32_t EspClass::magicFlashChipSize(uint8_t byte)
|
||||
{
|
||||
switch (byte & 0x0F)
|
||||
{
|
||||
case 0x0: // 4 Mbit (512KB)
|
||||
return (512_kB);
|
||||
case 0x1: // 2 MBit (256KB)
|
||||
return (256_kB);
|
||||
case 0x2: // 8 MBit (1MB)
|
||||
return (1_MB);
|
||||
case 0x3: // 16 MBit (2MB)
|
||||
return (2_MB);
|
||||
case 0x4: // 32 MBit (4MB)
|
||||
return (4_MB);
|
||||
case 0x8: // 64 MBit (8MB)
|
||||
return (8_MB);
|
||||
case 0x9: // 128 MBit (16MB)
|
||||
return (16_MB);
|
||||
default: // fail?
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipRealSize(void)
|
||||
{
|
||||
return magicFlashChipSize(4);
|
||||
return magicFlashChipSize(4);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipSize(void)
|
||||
{
|
||||
return magicFlashChipSize(4);
|
||||
return magicFlashChipSize(4);
|
||||
}
|
||||
|
||||
String EspClass::getFullVersion ()
|
||||
String EspClass::getFullVersion()
|
||||
{
|
||||
return "emulation-on-host";
|
||||
return "emulation-on-host";
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeContStack()
|
||||
@ -241,9 +260,7 @@ uint32_t EspClass::getFreeContStack()
|
||||
return 4000;
|
||||
}
|
||||
|
||||
void EspClass::resetFreeContStack()
|
||||
{
|
||||
}
|
||||
void EspClass::resetFreeContStack() { }
|
||||
|
||||
uint32_t EspClass::getCycleCount()
|
||||
{
|
||||
@ -257,23 +274,15 @@ uint32_t esp_get_cycle_count()
|
||||
return (((uint64_t)t.tv_sec) * 1000000 + t.tv_usec) * (F_CPU / 1000000);
|
||||
}
|
||||
|
||||
void EspClass::setDramHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::setDramHeap() { }
|
||||
|
||||
void EspClass::setIramHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::setIramHeap() { }
|
||||
|
||||
void EspClass::setExternalHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::setExternalHeap() { }
|
||||
|
||||
void EspClass::resetHeap()
|
||||
{
|
||||
}
|
||||
void EspClass::resetHeap() { }
|
||||
|
||||
void EspClass::reset ()
|
||||
void EspClass::reset()
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
@ -35,29 +35,23 @@
|
||||
SPIClass SPI;
|
||||
#endif
|
||||
|
||||
SPIClass::SPIClass ()
|
||||
{
|
||||
}
|
||||
SPIClass::SPIClass() { }
|
||||
|
||||
uint8_t SPIClass::transfer(uint8_t data)
|
||||
{
|
||||
return data;
|
||||
return data;
|
||||
}
|
||||
|
||||
void SPIClass::begin()
|
||||
{
|
||||
}
|
||||
void SPIClass::begin() { }
|
||||
|
||||
void SPIClass::end()
|
||||
{
|
||||
}
|
||||
void SPIClass::end() { }
|
||||
|
||||
void SPIClass::setFrequency(uint32_t freq)
|
||||
{
|
||||
(void)freq;
|
||||
(void)freq;
|
||||
}
|
||||
|
||||
void SPIClass::setHwCs(bool use)
|
||||
{
|
||||
(void)use;
|
||||
(void)use;
|
||||
}
|
||||
|
@ -34,56 +34,91 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint32_t lwip_htonl(uint32_t hostlong)
|
||||
{
|
||||
return htonl(hostlong);
|
||||
}
|
||||
uint16_t lwip_htons(uint16_t hostshort)
|
||||
{
|
||||
return htons(hostshort);
|
||||
}
|
||||
uint32_t lwip_ntohl(uint32_t netlong)
|
||||
{
|
||||
return ntohl(netlong);
|
||||
}
|
||||
uint16_t lwip_ntohs(uint16_t netshort)
|
||||
{
|
||||
return ntohs(netshort);
|
||||
}
|
||||
|
||||
uint32_t lwip_htonl (uint32_t hostlong) { return htonl(hostlong); }
|
||||
uint16_t lwip_htons (uint16_t hostshort) { return htons(hostshort); }
|
||||
uint32_t lwip_ntohl (uint32_t netlong) { return ntohl(netlong); }
|
||||
uint16_t lwip_ntohs (uint16_t netshort) { return ntohs(netshort); }
|
||||
char* ets_strcpy(char* d, const char* s)
|
||||
{
|
||||
return strcpy(d, s);
|
||||
}
|
||||
char* ets_strncpy(char* d, const char* s, size_t n)
|
||||
{
|
||||
return strncpy(d, s, n);
|
||||
}
|
||||
size_t ets_strlen(const char* s)
|
||||
{
|
||||
return strlen(s);
|
||||
}
|
||||
|
||||
char* ets_strcpy (char* d, const char* s) { return strcpy(d, s); }
|
||||
char* ets_strncpy (char* d, const char* s, size_t n) { return strncpy(d, s, n); }
|
||||
size_t ets_strlen (const char* s) { return strlen(s); }
|
||||
|
||||
int ets_printf (const char* fmt, ...)
|
||||
{
|
||||
int ets_printf(const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int len = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
int len = vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
void stack_thunk_add_ref() { }
|
||||
void stack_thunk_del_ref() { }
|
||||
void stack_thunk_repaint() { }
|
||||
void stack_thunk_add_ref() { }
|
||||
void stack_thunk_del_ref() { }
|
||||
void stack_thunk_repaint() { }
|
||||
|
||||
uint32_t stack_thunk_get_refcnt() { return 0; }
|
||||
uint32_t stack_thunk_get_stack_top() { return 0; }
|
||||
uint32_t stack_thunk_get_stack_bot() { return 0; }
|
||||
uint32_t stack_thunk_get_cont_sp() { return 0; }
|
||||
uint32_t stack_thunk_get_max_usage() { return 0; }
|
||||
void stack_thunk_dump_stack() { }
|
||||
uint32_t stack_thunk_get_refcnt()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_stack_top()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_stack_bot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_cont_sp()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
uint32_t stack_thunk_get_max_usage()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void stack_thunk_dump_stack() { }
|
||||
|
||||
// Thunking macro
|
||||
#define make_stack_thunk(fcnToThunk)
|
||||
|
||||
};
|
||||
|
||||
void configTime(int timezone, int daylightOffset_sec,
|
||||
const char* server1, const char* server2, const char* server3)
|
||||
void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2,
|
||||
const char* server3)
|
||||
{
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
|
||||
mockverbose("configTime: TODO (tz=%dH offset=%dS) (time will be host's)\n", timezone, daylightOffset_sec);
|
||||
mockverbose("configTime: TODO (tz=%dH offset=%dS) (time will be host's)\n", timezone,
|
||||
daylightOffset_sec);
|
||||
}
|
||||
|
||||
void configTime(const char* tz, const char* server1, const char* server2, const char* server3)
|
||||
{
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
(void)server1;
|
||||
(void)server2;
|
||||
(void)server3;
|
||||
|
||||
mockverbose("configTime: TODO (tz='%s') (time will be host's)\n", tz);
|
||||
mockverbose("configTime: TODO (tz='%s') (time will be host's)\n", tz);
|
||||
}
|
||||
|
@ -28,475 +28,455 @@
|
||||
is responsible for feeding the RX FIFO new data by calling uart_new_data().
|
||||
*/
|
||||
|
||||
#include <unistd.h> // write
|
||||
#include <sys/time.h> // gettimeofday
|
||||
#include <time.h> // localtime
|
||||
#include <unistd.h> // write
|
||||
#include <sys/time.h> // gettimeofday
|
||||
#include <time.h> // localtime
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "uart.h"
|
||||
|
||||
//#define UART_DISCARD_NEWEST
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool blocking_uart = true; // system default
|
||||
|
||||
static int s_uart_debug_nr = UART1;
|
||||
|
||||
static uart_t *UART[2] = { NULL, NULL };
|
||||
|
||||
struct uart_rx_buffer_
|
||||
extern "C"
|
||||
{
|
||||
size_t size;
|
||||
size_t rpos;
|
||||
size_t wpos;
|
||||
uint8_t * buffer;
|
||||
};
|
||||
bool blocking_uart = true; // system default
|
||||
|
||||
struct uart_
|
||||
{
|
||||
int uart_nr;
|
||||
int baud_rate;
|
||||
bool rx_enabled;
|
||||
bool tx_enabled;
|
||||
bool rx_overrun;
|
||||
struct uart_rx_buffer_ * rx_buffer;
|
||||
};
|
||||
static int s_uart_debug_nr = UART1;
|
||||
|
||||
bool serial_timestamp = false;
|
||||
static uart_t* UART[2] = { NULL, NULL };
|
||||
|
||||
// write one byte to the emulated UART
|
||||
static void
|
||||
uart_do_write_char(const int uart_nr, char c)
|
||||
{
|
||||
static bool w = false;
|
||||
struct uart_rx_buffer_
|
||||
{
|
||||
size_t size;
|
||||
size_t rpos;
|
||||
size_t wpos;
|
||||
uint8_t* buffer;
|
||||
};
|
||||
|
||||
if (uart_nr >= UART0 && uart_nr <= UART1)
|
||||
{
|
||||
if (serial_timestamp && (c == '\n' || c == '\r'))
|
||||
{
|
||||
if (w)
|
||||
{
|
||||
FILE* out = uart_nr == UART0? stdout: stderr;
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
const tm* tm = localtime(&tv.tv_sec);
|
||||
fprintf(out, "\r\n%d:%02d:%02d.%06d: ", tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec);
|
||||
fflush(out);
|
||||
w = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct uart_
|
||||
{
|
||||
int uart_nr;
|
||||
int baud_rate;
|
||||
bool rx_enabled;
|
||||
bool tx_enabled;
|
||||
bool rx_overrun;
|
||||
struct uart_rx_buffer_* rx_buffer;
|
||||
};
|
||||
|
||||
bool serial_timestamp = false;
|
||||
|
||||
// write one byte to the emulated UART
|
||||
static void uart_do_write_char(const int uart_nr, char c)
|
||||
{
|
||||
static bool w = false;
|
||||
|
||||
if (uart_nr >= UART0 && uart_nr <= UART1)
|
||||
{
|
||||
if (serial_timestamp && (c == '\n' || c == '\r'))
|
||||
{
|
||||
if (w)
|
||||
{
|
||||
FILE* out = uart_nr == UART0 ? stdout : stderr;
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
const tm* tm = localtime(&tv.tv_sec);
|
||||
fprintf(out, "\r\n%d:%02d:%02d.%06d: ", tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
(int)tv.tv_usec);
|
||||
fflush(out);
|
||||
w = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
||||
write(uart_nr + 1, &c, 1);
|
||||
write(uart_nr + 1, &c, 1);
|
||||
#pragma GCC diagnostic pop
|
||||
w = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write a new byte into the RX FIFO buffer
|
||||
static void
|
||||
uart_handle_data(uart_t* uart, uint8_t data)
|
||||
{
|
||||
struct uart_rx_buffer_ *rx_buffer = uart->rx_buffer;
|
||||
|
||||
size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size;
|
||||
if(nextPos == rx_buffer->rpos)
|
||||
{
|
||||
uart->rx_overrun = true;
|
||||
#ifdef UART_DISCARD_NEWEST
|
||||
return;
|
||||
#else
|
||||
if (++rx_buffer->rpos == rx_buffer->size)
|
||||
rx_buffer->rpos = 0;
|
||||
#endif
|
||||
}
|
||||
rx_buffer->buffer[rx_buffer->wpos] = data;
|
||||
rx_buffer->wpos = nextPos;
|
||||
}
|
||||
|
||||
// insert a new byte into the RX FIFO nuffer
|
||||
void
|
||||
uart_new_data(const int uart_nr, uint8_t data)
|
||||
{
|
||||
uart_t* uart = UART[uart_nr];
|
||||
|
||||
if(uart == NULL || !uart->rx_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
uart_handle_data(uart, data);
|
||||
}
|
||||
|
||||
static size_t
|
||||
uart_rx_available_unsafe(const struct uart_rx_buffer_ * rx_buffer)
|
||||
{
|
||||
size_t ret = rx_buffer->wpos - rx_buffer->rpos;
|
||||
|
||||
if(rx_buffer->wpos < rx_buffer->rpos)
|
||||
ret = (rx_buffer->wpos + rx_buffer->size) - rx_buffer->rpos;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// taking data straight from fifo, only needed in uart_resize_rx_buffer()
|
||||
static int
|
||||
uart_read_char_unsafe(uart_t* uart)
|
||||
{
|
||||
if (uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// take oldest sw data
|
||||
int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size;
|
||||
return ret;
|
||||
}
|
||||
// unavailable
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
/************ UART API FUNCTIONS **************************/
|
||||
/**********************************************************/
|
||||
|
||||
size_t
|
||||
uart_rx_available(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
return uart_rx_available_unsafe(uart->rx_buffer);
|
||||
}
|
||||
|
||||
int
|
||||
uart_peek_char(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return -1;
|
||||
|
||||
if (!uart_rx_available_unsafe(uart->rx_buffer))
|
||||
return -1;
|
||||
|
||||
return uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
}
|
||||
|
||||
int
|
||||
uart_read_char(uart_t* uart)
|
||||
{
|
||||
uint8_t ret;
|
||||
return uart_read(uart, (char*)&ret, 1) ? ret : -1;
|
||||
}
|
||||
|
||||
size_t
|
||||
uart_read(uart_t* uart, char* userbuffer, size_t usersize)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
if (!blocking_uart)
|
||||
{
|
||||
char c;
|
||||
if (read(0, &c, 1) == 1)
|
||||
uart_new_data(0, c);
|
||||
w = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t ret = 0;
|
||||
while (ret < usersize && uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// pour sw buffer to user's buffer
|
||||
// get largest linear length from sw buffer
|
||||
size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos ?
|
||||
uart->rx_buffer->wpos - uart->rx_buffer->rpos :
|
||||
uart->rx_buffer->size - uart->rx_buffer->rpos;
|
||||
if (ret + chunk > usersize)
|
||||
chunk = usersize - ret;
|
||||
memcpy(userbuffer + ret, uart->rx_buffer->buffer + uart->rx_buffer->rpos, chunk);
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size;
|
||||
ret += chunk;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// write a new byte into the RX FIFO buffer
|
||||
static void uart_handle_data(uart_t* uart, uint8_t data)
|
||||
{
|
||||
struct uart_rx_buffer_* rx_buffer = uart->rx_buffer;
|
||||
|
||||
size_t
|
||||
uart_resize_rx_buffer(uart_t* uart, size_t new_size)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
size_t nextPos = (rx_buffer->wpos + 1) % rx_buffer->size;
|
||||
if (nextPos == rx_buffer->rpos)
|
||||
{
|
||||
uart->rx_overrun = true;
|
||||
#ifdef UART_DISCARD_NEWEST
|
||||
return;
|
||||
#else
|
||||
if (++rx_buffer->rpos == rx_buffer->size)
|
||||
rx_buffer->rpos = 0;
|
||||
#endif
|
||||
}
|
||||
rx_buffer->buffer[rx_buffer->wpos] = data;
|
||||
rx_buffer->wpos = nextPos;
|
||||
}
|
||||
|
||||
if(uart->rx_buffer->size == new_size)
|
||||
return uart->rx_buffer->size;
|
||||
// insert a new byte into the RX FIFO nuffer
|
||||
void uart_new_data(const int uart_nr, uint8_t data)
|
||||
{
|
||||
uart_t* uart = UART[uart_nr];
|
||||
|
||||
uint8_t * new_buf = (uint8_t*)malloc(new_size);
|
||||
if(!new_buf)
|
||||
return uart->rx_buffer->size;
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t new_wpos = 0;
|
||||
// if uart_rx_available_unsafe() returns non-0, uart_read_char_unsafe() can't return -1
|
||||
while(uart_rx_available_unsafe(uart->rx_buffer) && new_wpos < new_size)
|
||||
new_buf[new_wpos++] = uart_read_char_unsafe(uart);
|
||||
if (new_wpos == new_size)
|
||||
new_wpos = 0;
|
||||
uart_handle_data(uart, data);
|
||||
}
|
||||
|
||||
uint8_t * old_buf = uart->rx_buffer->buffer;
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = new_wpos;
|
||||
uart->rx_buffer->size = new_size;
|
||||
uart->rx_buffer->buffer = new_buf;
|
||||
free(old_buf);
|
||||
return uart->rx_buffer->size;
|
||||
}
|
||||
static size_t uart_rx_available_unsafe(const struct uart_rx_buffer_* rx_buffer)
|
||||
{
|
||||
size_t ret = rx_buffer->wpos - rx_buffer->rpos;
|
||||
|
||||
size_t
|
||||
uart_get_rx_buffer_size(uart_t* uart)
|
||||
{
|
||||
return uart && uart->rx_enabled ? uart->rx_buffer->size : 0;
|
||||
}
|
||||
if (rx_buffer->wpos < rx_buffer->rpos)
|
||||
ret = (rx_buffer->wpos + rx_buffer->size) - rx_buffer->rpos;
|
||||
|
||||
size_t
|
||||
uart_write_char(uart_t* uart, char c)
|
||||
{
|
||||
if(uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uart_do_write_char(uart->uart_nr, c);
|
||||
// taking data straight from fifo, only needed in uart_resize_rx_buffer()
|
||||
static int uart_read_char_unsafe(uart_t* uart)
|
||||
{
|
||||
if (uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// take oldest sw data
|
||||
int ret = uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + 1) % uart->rx_buffer->size;
|
||||
return ret;
|
||||
}
|
||||
// unavailable
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/**********************************************************/
|
||||
/************ UART API FUNCTIONS **************************/
|
||||
/**********************************************************/
|
||||
|
||||
size_t
|
||||
uart_write(uart_t* uart, const char* buf, size_t size)
|
||||
{
|
||||
if(uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
size_t uart_rx_available(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
size_t ret = size;
|
||||
const int uart_nr = uart->uart_nr;
|
||||
while (size--)
|
||||
uart_do_write_char(uart_nr, *buf++);
|
||||
return uart_rx_available_unsafe(uart->rx_buffer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int uart_peek_char(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return -1;
|
||||
|
||||
size_t
|
||||
uart_tx_free(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
if (!uart_rx_available_unsafe(uart->rx_buffer))
|
||||
return -1;
|
||||
|
||||
return UART_TX_FIFO_SIZE;
|
||||
}
|
||||
return uart->rx_buffer->buffer[uart->rx_buffer->rpos];
|
||||
}
|
||||
|
||||
void
|
||||
uart_wait_tx_empty(uart_t* uart)
|
||||
{
|
||||
(void) uart;
|
||||
}
|
||||
int uart_read_char(uart_t* uart)
|
||||
{
|
||||
uint8_t ret;
|
||||
return uart_read(uart, (char*)&ret, 1) ? ret : -1;
|
||||
}
|
||||
|
||||
void
|
||||
uart_flush(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return;
|
||||
size_t uart_read(uart_t* uart, char* userbuffer, size_t usersize)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
if(uart->rx_enabled)
|
||||
{
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = 0;
|
||||
}
|
||||
}
|
||||
if (!blocking_uart)
|
||||
{
|
||||
char c;
|
||||
if (read(0, &c, 1) == 1)
|
||||
uart_new_data(0, c);
|
||||
}
|
||||
|
||||
void
|
||||
uart_set_baudrate(uart_t* uart, int baud_rate)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return;
|
||||
size_t ret = 0;
|
||||
while (ret < usersize && uart_rx_available_unsafe(uart->rx_buffer))
|
||||
{
|
||||
// pour sw buffer to user's buffer
|
||||
// get largest linear length from sw buffer
|
||||
size_t chunk = uart->rx_buffer->rpos < uart->rx_buffer->wpos
|
||||
? uart->rx_buffer->wpos - uart->rx_buffer->rpos
|
||||
: uart->rx_buffer->size - uart->rx_buffer->rpos;
|
||||
if (ret + chunk > usersize)
|
||||
chunk = usersize - ret;
|
||||
memcpy(userbuffer + ret, uart->rx_buffer->buffer + uart->rx_buffer->rpos, chunk);
|
||||
uart->rx_buffer->rpos = (uart->rx_buffer->rpos + chunk) % uart->rx_buffer->size;
|
||||
ret += chunk;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uart->baud_rate = baud_rate;
|
||||
}
|
||||
size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_enabled)
|
||||
return 0;
|
||||
|
||||
int
|
||||
uart_get_baudrate(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return 0;
|
||||
if (uart->rx_buffer->size == new_size)
|
||||
return uart->rx_buffer->size;
|
||||
|
||||
return uart->baud_rate;
|
||||
}
|
||||
uint8_t* new_buf = (uint8_t*)malloc(new_size);
|
||||
if (!new_buf)
|
||||
return uart->rx_buffer->size;
|
||||
|
||||
uint8_t
|
||||
uart_get_bit_length(const int uart_nr)
|
||||
{
|
||||
uint8_t width = ((uart_nr % 16) >> 2) + 5;
|
||||
uint8_t parity = (uart_nr >> 5) + 1;
|
||||
uint8_t stop = uart_nr % 4;
|
||||
return (width + parity + stop + 1);
|
||||
}
|
||||
size_t new_wpos = 0;
|
||||
// if uart_rx_available_unsafe() returns non-0, uart_read_char_unsafe() can't return -1
|
||||
while (uart_rx_available_unsafe(uart->rx_buffer) && new_wpos < new_size)
|
||||
new_buf[new_wpos++] = uart_read_char_unsafe(uart);
|
||||
if (new_wpos == new_size)
|
||||
new_wpos = 0;
|
||||
|
||||
uart_t*
|
||||
uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size, bool invert)
|
||||
{
|
||||
(void) config;
|
||||
(void) tx_pin;
|
||||
(void) invert;
|
||||
uart_t* uart = (uart_t*) malloc(sizeof(uart_t));
|
||||
if(uart == NULL)
|
||||
return NULL;
|
||||
uint8_t* old_buf = uart->rx_buffer->buffer;
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = new_wpos;
|
||||
uart->rx_buffer->size = new_size;
|
||||
uart->rx_buffer->buffer = new_buf;
|
||||
free(old_buf);
|
||||
return uart->rx_buffer->size;
|
||||
}
|
||||
|
||||
uart->uart_nr = uart_nr;
|
||||
uart->rx_overrun = false;
|
||||
size_t uart_get_rx_buffer_size(uart_t* uart)
|
||||
{
|
||||
return uart && uart->rx_enabled ? uart->rx_buffer->size : 0;
|
||||
}
|
||||
|
||||
switch(uart->uart_nr)
|
||||
{
|
||||
case UART0:
|
||||
uart->rx_enabled = (mode != UART_TX_ONLY);
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
if(uart->rx_enabled)
|
||||
{
|
||||
struct uart_rx_buffer_ * rx_buffer = (struct uart_rx_buffer_ *)malloc(sizeof(struct uart_rx_buffer_));
|
||||
if(rx_buffer == NULL)
|
||||
{
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
rx_buffer->size = rx_size;//var this
|
||||
rx_buffer->rpos = 0;
|
||||
rx_buffer->wpos = 0;
|
||||
rx_buffer->buffer = (uint8_t *)malloc(rx_buffer->size);
|
||||
if(rx_buffer->buffer == NULL)
|
||||
{
|
||||
free(rx_buffer);
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
uart->rx_buffer = rx_buffer;
|
||||
}
|
||||
break;
|
||||
size_t uart_write_char(uart_t* uart, char c)
|
||||
{
|
||||
if (uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
|
||||
case UART1:
|
||||
// Note: uart_interrupt_handler does not support RX on UART 1.
|
||||
uart->rx_enabled = false;
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
break;
|
||||
uart_do_write_char(uart->uart_nr, c);
|
||||
|
||||
case UART_NO:
|
||||
default:
|
||||
// big fail!
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uart_set_baudrate(uart, baudrate);
|
||||
size_t uart_write(uart_t* uart, const char* buf, size_t size)
|
||||
{
|
||||
if (uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
|
||||
UART[uart_nr] = uart;
|
||||
size_t ret = size;
|
||||
const int uart_nr = uart->uart_nr;
|
||||
while (size--)
|
||||
uart_do_write_char(uart_nr, *buf++);
|
||||
|
||||
return uart;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
uart_uninit(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return;
|
||||
size_t uart_tx_free(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->tx_enabled)
|
||||
return 0;
|
||||
|
||||
if(uart->rx_enabled) {
|
||||
free(uart->rx_buffer->buffer);
|
||||
free(uart->rx_buffer);
|
||||
}
|
||||
free(uart);
|
||||
}
|
||||
return UART_TX_FIFO_SIZE;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_swap(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void) uart;
|
||||
(void) tx_pin;
|
||||
return true;
|
||||
}
|
||||
void uart_wait_tx_empty(uart_t* uart)
|
||||
{
|
||||
(void)uart;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_set_tx(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void) uart;
|
||||
(void) tx_pin;
|
||||
return true;
|
||||
}
|
||||
void uart_flush(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return;
|
||||
|
||||
bool
|
||||
uart_set_pins(uart_t* uart, int tx, int rx)
|
||||
{
|
||||
(void) uart;
|
||||
(void) tx;
|
||||
(void) rx;
|
||||
return true;
|
||||
}
|
||||
if (uart->rx_enabled)
|
||||
{
|
||||
uart->rx_buffer->rpos = 0;
|
||||
uart->rx_buffer->wpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
uart_tx_enabled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return false;
|
||||
void uart_set_baudrate(uart_t* uart, int baud_rate)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return;
|
||||
|
||||
return uart->tx_enabled;
|
||||
}
|
||||
uart->baud_rate = baud_rate;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_rx_enabled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL)
|
||||
return false;
|
||||
int uart_get_baudrate(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return 0;
|
||||
|
||||
return uart->rx_enabled;
|
||||
}
|
||||
return uart->baud_rate;
|
||||
}
|
||||
|
||||
bool
|
||||
uart_has_overrun(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || !uart->rx_overrun)
|
||||
return false;
|
||||
uint8_t uart_get_bit_length(const int uart_nr)
|
||||
{
|
||||
uint8_t width = ((uart_nr % 16) >> 2) + 5;
|
||||
uint8_t parity = (uart_nr >> 5) + 1;
|
||||
uint8_t stop = uart_nr % 4;
|
||||
return (width + parity + stop + 1);
|
||||
}
|
||||
|
||||
// clear flag
|
||||
uart->rx_overrun = false;
|
||||
return true;
|
||||
}
|
||||
uart_t* uart_init(int uart_nr, int baudrate, int config, int mode, int tx_pin, size_t rx_size,
|
||||
bool invert)
|
||||
{
|
||||
(void)config;
|
||||
(void)tx_pin;
|
||||
(void)invert;
|
||||
uart_t* uart = (uart_t*)malloc(sizeof(uart_t));
|
||||
if (uart == NULL)
|
||||
return NULL;
|
||||
|
||||
bool
|
||||
uart_has_rx_error(uart_t* uart)
|
||||
{
|
||||
(void) uart;
|
||||
return false;
|
||||
}
|
||||
uart->uart_nr = uart_nr;
|
||||
uart->rx_overrun = false;
|
||||
|
||||
void
|
||||
uart_set_debug(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
}
|
||||
switch (uart->uart_nr)
|
||||
{
|
||||
case UART0:
|
||||
uart->rx_enabled = (mode != UART_TX_ONLY);
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
if (uart->rx_enabled)
|
||||
{
|
||||
struct uart_rx_buffer_* rx_buffer
|
||||
= (struct uart_rx_buffer_*)malloc(sizeof(struct uart_rx_buffer_));
|
||||
if (rx_buffer == NULL)
|
||||
{
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
rx_buffer->size = rx_size; // var this
|
||||
rx_buffer->rpos = 0;
|
||||
rx_buffer->wpos = 0;
|
||||
rx_buffer->buffer = (uint8_t*)malloc(rx_buffer->size);
|
||||
if (rx_buffer->buffer == NULL)
|
||||
{
|
||||
free(rx_buffer);
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
uart->rx_buffer = rx_buffer;
|
||||
}
|
||||
break;
|
||||
|
||||
int
|
||||
uart_get_debug()
|
||||
{
|
||||
return s_uart_debug_nr;
|
||||
}
|
||||
case UART1:
|
||||
// Note: uart_interrupt_handler does not support RX on UART 1.
|
||||
uart->rx_enabled = false;
|
||||
uart->tx_enabled = (mode != UART_RX_ONLY);
|
||||
break;
|
||||
|
||||
void
|
||||
uart_start_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void) uart_nr;
|
||||
}
|
||||
case UART_NO:
|
||||
default:
|
||||
// big fail!
|
||||
free(uart);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
uart_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void) uart_nr;
|
||||
return 115200;
|
||||
}
|
||||
uart_set_baudrate(uart, baudrate);
|
||||
|
||||
UART[uart_nr] = uart;
|
||||
|
||||
return uart;
|
||||
}
|
||||
|
||||
void uart_uninit(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return;
|
||||
|
||||
if (uart->rx_enabled)
|
||||
{
|
||||
free(uart->rx_buffer->buffer);
|
||||
free(uart->rx_buffer);
|
||||
}
|
||||
free(uart);
|
||||
}
|
||||
|
||||
bool uart_swap(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void)uart;
|
||||
(void)tx_pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_set_tx(uart_t* uart, int tx_pin)
|
||||
{
|
||||
(void)uart;
|
||||
(void)tx_pin;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_set_pins(uart_t* uart, int tx, int rx)
|
||||
{
|
||||
(void)uart;
|
||||
(void)tx;
|
||||
(void)rx;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_tx_enabled(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return false;
|
||||
|
||||
return uart->tx_enabled;
|
||||
}
|
||||
|
||||
bool uart_rx_enabled(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL)
|
||||
return false;
|
||||
|
||||
return uart->rx_enabled;
|
||||
}
|
||||
|
||||
bool uart_has_overrun(uart_t* uart)
|
||||
{
|
||||
if (uart == NULL || !uart->rx_overrun)
|
||||
return false;
|
||||
|
||||
// clear flag
|
||||
uart->rx_overrun = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_has_rx_error(uart_t* uart)
|
||||
{
|
||||
(void)uart;
|
||||
return false;
|
||||
}
|
||||
|
||||
void uart_set_debug(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
}
|
||||
|
||||
int uart_get_debug()
|
||||
{
|
||||
return s_uart_debug_nr;
|
||||
}
|
||||
|
||||
void uart_start_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
}
|
||||
|
||||
int uart_detect_baudrate(int uart_nr)
|
||||
{
|
||||
(void)uart_nr;
|
||||
return 115200;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
size_t uart_peek_available (uart_t* uart) { return 0; }
|
||||
const char* uart_peek_buffer (uart_t* uart) { return nullptr; }
|
||||
void uart_peek_consume (uart_t* uart, size_t consume) { (void)uart; (void)consume; }
|
||||
|
||||
size_t uart_peek_available(uart_t* uart)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const char* uart_peek_buffer(uart_t* uart)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void uart_peek_consume(uart_t* uart, size_t consume)
|
||||
{
|
||||
(void)uart;
|
||||
(void)consume;
|
||||
}
|
||||
|
@ -44,32 +44,31 @@ extern "C" const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
|
||||
|
||||
// lwIP API side of WiFiServer
|
||||
|
||||
WiFiServer::WiFiServer (const IPAddress& addr, uint16_t port)
|
||||
WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port)
|
||||
{
|
||||
(void)addr;
|
||||
_port = port;
|
||||
(void)addr;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
WiFiServer::WiFiServer (uint16_t port)
|
||||
WiFiServer::WiFiServer(uint16_t port)
|
||||
{
|
||||
_port = port;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
WiFiClient WiFiServer::available (uint8_t* status)
|
||||
WiFiClient WiFiServer::available(uint8_t* status)
|
||||
{
|
||||
(void)status;
|
||||
return accept();
|
||||
(void)status;
|
||||
return accept();
|
||||
}
|
||||
|
||||
WiFiClient WiFiServer::accept ()
|
||||
WiFiClient WiFiServer::accept()
|
||||
{
|
||||
if (hasClient())
|
||||
return WiFiClient(new ClientContext(serverAccept(pcb2int(_listen_pcb))));
|
||||
return WiFiClient();
|
||||
if (hasClient())
|
||||
return WiFiClient(new ClientContext(serverAccept(pcb2int(_listen_pcb))));
|
||||
return WiFiClient();
|
||||
}
|
||||
|
||||
// static declaration
|
||||
|
||||
#include <include/UdpContext.h>
|
||||
uint32_t UdpContext::staticMCastAddr = 0;
|
||||
|
||||
|
@ -44,26 +44,26 @@
|
||||
|
||||
// host socket internal side of WiFiServer
|
||||
|
||||
int serverAccept (int srvsock)
|
||||
int serverAccept(int srvsock)
|
||||
{
|
||||
int clisock;
|
||||
socklen_t n;
|
||||
struct sockaddr_in client;
|
||||
n = sizeof(client);
|
||||
if ((clisock = accept(srvsock, (struct sockaddr*)&client, &n)) == -1)
|
||||
{
|
||||
perror(MOCK "accept()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return mockSockSetup(clisock);
|
||||
int clisock;
|
||||
socklen_t n;
|
||||
struct sockaddr_in client;
|
||||
n = sizeof(client);
|
||||
if ((clisock = accept(srvsock, (struct sockaddr*)&client, &n)) == -1)
|
||||
{
|
||||
perror(MOCK "accept()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return mockSockSetup(clisock);
|
||||
}
|
||||
|
||||
void WiFiServer::begin (uint16_t port)
|
||||
void WiFiServer::begin(uint16_t port)
|
||||
{
|
||||
return begin(port, !0);
|
||||
}
|
||||
|
||||
void WiFiServer::begin (uint16_t port, uint8_t backlog)
|
||||
void WiFiServer::begin(uint16_t port, uint8_t backlog)
|
||||
{
|
||||
if (!backlog)
|
||||
return;
|
||||
@ -71,85 +71,86 @@ void WiFiServer::begin (uint16_t port, uint8_t backlog)
|
||||
return begin();
|
||||
}
|
||||
|
||||
void WiFiServer::begin ()
|
||||
void WiFiServer::begin()
|
||||
{
|
||||
int sock;
|
||||
int mockport;
|
||||
struct sockaddr_in server;
|
||||
int sock;
|
||||
int mockport;
|
||||
struct sockaddr_in server;
|
||||
|
||||
mockport = _port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d shifted to %d (use option -s) <=====\n", _port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d <=====\n", mockport);
|
||||
mockport = _port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d shifted to %d (use option -s) <=====\n",
|
||||
_port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> WiFiServer port: %d <=====\n", mockport);
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
perror(MOCK "socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
{
|
||||
perror(MOCK "reuseport");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
{
|
||||
perror(MOCK "reuseport");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(mockport);
|
||||
server.sin_addr.s_addr = htonl(global_source_address);
|
||||
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "bind()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(mockport);
|
||||
server.sin_addr.s_addr = htonl(global_source_address);
|
||||
if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1)
|
||||
{
|
||||
perror(MOCK "bind()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (listen(sock, 1) == -1)
|
||||
{
|
||||
perror(MOCK "listen()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (listen(sock, 1) == -1)
|
||||
{
|
||||
perror(MOCK "listen()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
// store int into pointer
|
||||
_listen_pcb = int2pcb(sock);
|
||||
// store int into pointer
|
||||
_listen_pcb = int2pcb(sock);
|
||||
}
|
||||
|
||||
bool WiFiServer::hasClient ()
|
||||
bool WiFiServer::hasClient()
|
||||
{
|
||||
struct pollfd p;
|
||||
p.fd = pcb2int(_listen_pcb);
|
||||
p.events = POLLIN;
|
||||
return poll(&p, 1, 0) && p.revents == POLLIN;
|
||||
struct pollfd p;
|
||||
p.fd = pcb2int(_listen_pcb);
|
||||
p.events = POLLIN;
|
||||
return poll(&p, 1, 0) && p.revents == POLLIN;
|
||||
}
|
||||
|
||||
void WiFiServer::close ()
|
||||
void WiFiServer::close()
|
||||
{
|
||||
if (pcb2int(_listen_pcb) >= 0)
|
||||
::close(pcb2int(_listen_pcb));
|
||||
_listen_pcb = int2pcb(-1);
|
||||
if (pcb2int(_listen_pcb) >= 0)
|
||||
::close(pcb2int(_listen_pcb));
|
||||
_listen_pcb = int2pcb(-1);
|
||||
}
|
||||
|
||||
void WiFiServer::stop ()
|
||||
void WiFiServer::stop()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
size_t WiFiServer::hasClientData ()
|
||||
size_t WiFiServer::hasClientData()
|
||||
{
|
||||
// Trivial Mocking:
|
||||
// There is no waiting list of clients in this trivial mocking code,
|
||||
// so the code has to act as if the tcp backlog list is full,
|
||||
// and nothing is known about potential further clients.
|
||||
// It could be implemented by accepting new clients and store their data until the current one is closed.
|
||||
// It could be implemented by accepting new clients and store their data until the current one
|
||||
// is closed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WiFiServer::hasMaxPendingClients ()
|
||||
bool WiFiServer::hasMaxPendingClients()
|
||||
{
|
||||
// Mocking code does not consider the waiting client list,
|
||||
// so it will return ::hasClient() here meaning:
|
||||
|
@ -7,58 +7,54 @@ esp8266::AddressListImplementation::AddressList addrList;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern netif netif0;
|
||||
|
||||
extern netif netif0;
|
||||
netif* netif_list = &netif0;
|
||||
|
||||
netif* netif_list = &netif0;
|
||||
err_t dhcp_renew(struct netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t dhcp_renew(struct netif *netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
void sntp_setserver(u8_t, const ip_addr_t) { }
|
||||
|
||||
void sntp_setserver(u8_t, const ip_addr_t)
|
||||
{
|
||||
}
|
||||
const ip_addr_t* sntp_getserver(u8_t)
|
||||
{
|
||||
return IP_ADDR_ANY;
|
||||
}
|
||||
|
||||
const ip_addr_t* sntp_getserver(u8_t)
|
||||
{
|
||||
return IP_ADDR_ANY;
|
||||
}
|
||||
err_t etharp_request(struct netif* netif, const ip4_addr_t* ipaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)ipaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)ipaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
err_t igmp_start(struct netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_start(struct netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
err_t igmp_joingroup_netif(struct netif* netif, const ip4_addr_t* groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
err_t igmp_leavegroup_netif(struct netif* netif, const ip4_addr_t* groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
|
||||
{
|
||||
(void)netif;
|
||||
(void)groupaddr;
|
||||
return ERR_OK;
|
||||
}
|
||||
struct netif* netif_get_by_index(u8_t idx)
|
||||
{
|
||||
(void)idx;
|
||||
return &netif0;
|
||||
}
|
||||
|
||||
struct netif* netif_get_by_index(u8_t idx)
|
||||
{
|
||||
(void)idx;
|
||||
return &netif0;
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
extern netif netif0;
|
||||
extern netif netif0;
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
||||
#endif // __MOCKLWIP_H
|
||||
#endif // __MOCKLWIP_H
|
||||
|
@ -39,176 +39,189 @@
|
||||
#include <assert.h>
|
||||
#include <net/if.h>
|
||||
|
||||
int mockUDPSocket ()
|
||||
int mockUDPSocket()
|
||||
{
|
||||
int s;
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 || fcntl(s, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP socket: %s", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return s;
|
||||
int s;
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 || fcntl(s, F_SETFL, O_NONBLOCK) == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP socket: %s", strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
||||
bool mockUDPListen(int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast)
|
||||
{
|
||||
int optval;
|
||||
int mockport;
|
||||
int optval;
|
||||
int mockport;
|
||||
|
||||
mockport = port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d shifted to %d (use option -s) <=====\n", port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d <=====\n", mockport);
|
||||
mockport = port;
|
||||
if (mockport < 1024 && mock_port_shifter)
|
||||
{
|
||||
mockport += mock_port_shifter;
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d shifted to %d (use option -s) <=====\n",
|
||||
port, mockport);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, MOCK "=====> UdpServer port: %d <=====\n", mockport);
|
||||
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEPORT failed\n");
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEADDR failed\n");
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEPORT failed\n");
|
||||
optval = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1)
|
||||
fprintf(stderr, MOCK "SO_REUSEADDR failed\n");
|
||||
|
||||
struct sockaddr_in servaddr;
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
struct sockaddr_in servaddr;
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
|
||||
// Filling server information
|
||||
servaddr.sin_family = AF_INET;
|
||||
(void) dstaddr;
|
||||
//servaddr.sin_addr.s_addr = htonl(global_source_address);
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(mockport);
|
||||
// Filling server information
|
||||
servaddr.sin_family = AF_INET;
|
||||
(void)dstaddr;
|
||||
// servaddr.sin_addr.s_addr = htonl(global_source_address);
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servaddr.sin_port = htons(mockport);
|
||||
|
||||
// Bind the socket with the server address
|
||||
if (bind(sock, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP bind on port %d failed: %s\n", mockport, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("UDP server on port %d (sock=%d)\n", mockport, sock);
|
||||
// Bind the socket with the server address
|
||||
if (bind(sock, (const struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDP bind on port %d failed: %s\n", mockport, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("UDP server on port %d (sock=%d)\n", mockport, sock);
|
||||
|
||||
if (!mcast)
|
||||
mcast = inet_addr("224.0.0.1"); // all hosts group
|
||||
if (mcast)
|
||||
{
|
||||
// https://web.cs.wpi.edu/~claypool/courses/4514-B99/samples/multicast.c
|
||||
// https://stackoverflow.com/questions/12681097/c-choose-interface-for-udp-multicast-socket
|
||||
if (!mcast)
|
||||
mcast = inet_addr("224.0.0.1"); // all hosts group
|
||||
if (mcast)
|
||||
{
|
||||
// https://web.cs.wpi.edu/~claypool/courses/4514-B99/samples/multicast.c
|
||||
// https://stackoverflow.com/questions/12681097/c-choose-interface-for-udp-multicast-socket
|
||||
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = mcast;
|
||||
//mreq.imr_interface.s_addr = htonl(global_source_address);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
struct ip_mreq mreq;
|
||||
mreq.imr_multiaddr.s_addr = mcast;
|
||||
// mreq.imr_interface.s_addr = htonl(global_source_address);
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (host_interface)
|
||||
{
|
||||
if (host_interface)
|
||||
{
|
||||
#if __APPLE__
|
||||
int idx = if_nametoindex(host_interface);
|
||||
if (setsockopt(sock, IPPROTO_TCP, IP_BOUND_IF, &idx, sizeof(idx)) == -1)
|
||||
int idx = if_nametoindex(host_interface);
|
||||
if (setsockopt(sock, IPPROTO_TCP, IP_BOUND_IF, &idx, sizeof(idx)) == -1)
|
||||
#else
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, host_interface, strlen(host_interface)) == -1)
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, host_interface,
|
||||
strlen(host_interface))
|
||||
== -1)
|
||||
#endif
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/output on interface %s: %s\n", host_interface, strerror(errno));
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &mreq.imr_interface, sizeof(struct in_addr)) == -1)
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/input on interface %s: %s\n", host_interface, strerror(errno));
|
||||
}
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/output on interface %s: %s\n",
|
||||
host_interface, strerror(errno));
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, &mreq.imr_interface,
|
||||
sizeof(struct in_addr))
|
||||
== -1)
|
||||
fprintf(stderr, MOCK "UDP multicast: can't setup bind/input on interface %s: %s\n",
|
||||
host_interface, strerror(errno));
|
||||
}
|
||||
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "can't join multicast group addr %08x\n", (int)mcast);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("joined multicast group addr %08lx\n", (long)ntohl(mcast));
|
||||
}
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
|
||||
{
|
||||
fprintf(stderr, MOCK "can't join multicast group addr %08x\n", (int)mcast);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
mockverbose("joined multicast group addr %08lx\n", (long)ntohl(mcast));
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
size_t mockUDPFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize, uint8_t addr[16], uint16_t& port)
|
||||
size_t mockUDPFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize,
|
||||
uint8_t addr[16], uint16_t& port)
|
||||
{
|
||||
struct sockaddr_storage addrbuf;
|
||||
socklen_t addrbufsize = std::min((socklen_t)sizeof(addrbuf), (socklen_t)16);
|
||||
struct sockaddr_storage addrbuf;
|
||||
socklen_t addrbufsize = std::min((socklen_t)sizeof(addrbuf), (socklen_t)16);
|
||||
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::recvfrom(sock, ccinbuf + ccinbufsize, maxread, 0/*flags*/, (sockaddr*)&addrbuf, &addrbufsize);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, MOCK "UDPContext::(read/peek): filling buffer for %zd bytes: %s\n", maxread, strerror(errno));
|
||||
ret = 0;
|
||||
}
|
||||
size_t maxread = CCBUFSIZE - ccinbufsize;
|
||||
ssize_t ret = ::recvfrom(sock, ccinbuf + ccinbufsize, maxread, 0 /*flags*/, (sockaddr*)&addrbuf,
|
||||
&addrbufsize);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, MOCK "UDPContext::(read/peek): filling buffer for %zd bytes: %s\n",
|
||||
maxread, strerror(errno));
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
port = ntohs(((sockaddr_in*)&addrbuf)->sin_port);
|
||||
if (addrbuf.ss_family == AF_INET)
|
||||
memcpy(&addr[0], &(((sockaddr_in*)&addrbuf)->sin_addr.s_addr), addrsize = 4);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, MOCK "TODO UDP+IPv6\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (ret > 0)
|
||||
{
|
||||
port = ntohs(((sockaddr_in*)&addrbuf)->sin_port);
|
||||
if (addrbuf.ss_family == AF_INET)
|
||||
memcpy(&addr[0], &(((sockaddr_in*)&addrbuf)->sin_addr.s_addr), addrsize = 4);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, MOCK "TODO UDP+IPv6\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return ccinbufsize += ret;
|
||||
return ccinbufsize += ret;
|
||||
}
|
||||
|
||||
size_t mockUDPPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
size_t mockUDPPeekBytes(int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
(void) sock;
|
||||
(void) timeout_ms;
|
||||
if (usersize > CCBUFSIZE)
|
||||
fprintf(stderr, MOCK "CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE, usersize - CCBUFSIZE, usersize);
|
||||
(void)sock;
|
||||
(void)timeout_ms;
|
||||
if (usersize > CCBUFSIZE)
|
||||
fprintf(stderr, MOCK "CCBUFSIZE(%d) should be increased by %zd bytes (-> %zd)\n", CCBUFSIZE,
|
||||
usersize - CCBUFSIZE, usersize);
|
||||
|
||||
size_t retsize = 0;
|
||||
if (ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
if (retsize > ccinbufsize)
|
||||
retsize = ccinbufsize;
|
||||
}
|
||||
memcpy(dst, ccinbuf, retsize);
|
||||
return retsize;
|
||||
size_t retsize = 0;
|
||||
if (ccinbufsize)
|
||||
{
|
||||
// data already buffered
|
||||
retsize = usersize;
|
||||
if (retsize > ccinbufsize)
|
||||
retsize = ccinbufsize;
|
||||
}
|
||||
memcpy(dst, ccinbuf, retsize);
|
||||
return retsize;
|
||||
}
|
||||
|
||||
void mockUDPSwallow (size_t copied, char* ccinbuf, size_t& ccinbufsize)
|
||||
void mockUDPSwallow(size_t copied, char* ccinbuf, size_t& ccinbufsize)
|
||||
{
|
||||
// poor man buffer
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
// poor man buffer
|
||||
memmove(ccinbuf, ccinbuf + copied, ccinbufsize - copied);
|
||||
ccinbufsize -= copied;
|
||||
}
|
||||
|
||||
size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize)
|
||||
size_t mockUDPRead(int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize)
|
||||
{
|
||||
size_t copied = mockUDPPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
mockUDPSwallow(copied, ccinbuf, ccinbufsize);
|
||||
return copied;
|
||||
size_t copied = mockUDPPeekBytes(sock, dst, size, timeout_ms, ccinbuf, ccinbufsize);
|
||||
mockUDPSwallow(copied, ccinbuf, ccinbufsize);
|
||||
return copied;
|
||||
}
|
||||
|
||||
size_t mockUDPWrite (int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4, uint16_t port)
|
||||
size_t mockUDPWrite(int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4,
|
||||
uint16_t port)
|
||||
{
|
||||
(void) timeout_ms;
|
||||
// Filling server information
|
||||
struct sockaddr_in peer;
|
||||
peer.sin_family = AF_INET;
|
||||
peer.sin_addr.s_addr = ipv4; //XXFIXME should use lwip_htonl?
|
||||
peer.sin_port = htons(port);
|
||||
int ret = ::sendto(sock, data, size, 0/*flags*/, (const sockaddr*)&peer, sizeof(peer));
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: write(%d): %s\n", sock, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (ret != (int)size)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: short write (%d < %zd) (TODO)\n", ret, size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
(void)timeout_ms;
|
||||
// Filling server information
|
||||
struct sockaddr_in peer;
|
||||
peer.sin_family = AF_INET;
|
||||
peer.sin_addr.s_addr = ipv4; // XXFIXME should use lwip_htonl?
|
||||
peer.sin_port = htons(port);
|
||||
int ret = ::sendto(sock, data, size, 0 /*flags*/, (const sockaddr*)&peer, sizeof(peer));
|
||||
if (ret == -1)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: write(%d): %s\n", sock, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (ret != (int)size)
|
||||
{
|
||||
fprintf(stderr, MOCK "UDPContext::write: short write (%d < %zd) (TODO)\n", ret, size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,59 +4,69 @@
|
||||
Part of the Wiring project - http://wiring.org.co
|
||||
Copyright (c) 2004-06 Hernando Barragan
|
||||
Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
void randomSeed(unsigned long seed) {
|
||||
if(seed != 0) {
|
||||
void randomSeed(unsigned long seed)
|
||||
{
|
||||
if (seed != 0)
|
||||
{
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
||||
long random(long howbig) {
|
||||
if(howbig == 0) {
|
||||
long random(long howbig)
|
||||
{
|
||||
if (howbig == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (rand()) % howbig;
|
||||
}
|
||||
|
||||
long random(long howsmall, long howbig) {
|
||||
if(howsmall >= howbig) {
|
||||
long random(long howsmall, long howbig)
|
||||
{
|
||||
if (howsmall >= howbig)
|
||||
{
|
||||
return howsmall;
|
||||
}
|
||||
long diff = howbig - howsmall;
|
||||
return random(diff) + howsmall;
|
||||
}
|
||||
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
uint16_t makeWord(unsigned int w) {
|
||||
uint16_t makeWord(unsigned int w)
|
||||
{
|
||||
return w;
|
||||
}
|
||||
|
||||
uint16_t makeWord(unsigned char h, unsigned char l) {
|
||||
uint16_t makeWord(unsigned char h, unsigned char l)
|
||||
{
|
||||
return (h << 8) | l;
|
||||
}
|
||||
|
@ -36,45 +36,46 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
typedef signed char sint8_t;
|
||||
typedef signed short sint16_t;
|
||||
typedef signed long sint32_t;
|
||||
typedef signed long long sint64_t;
|
||||
typedef signed char sint8_t;
|
||||
typedef signed short sint16_t;
|
||||
typedef signed long sint32_t;
|
||||
typedef signed long long sint64_t;
|
||||
// CONFLICT typedef unsigned long long u_int64_t;
|
||||
typedef float real32_t;
|
||||
typedef double real64_t;
|
||||
typedef float real32_t;
|
||||
typedef double real64_t;
|
||||
|
||||
// CONFLICT typedef unsigned char uint8;
|
||||
typedef unsigned char u8;
|
||||
typedef signed char sint8;
|
||||
typedef signed char int8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short sint16;
|
||||
typedef signed short s16;
|
||||
typedef unsigned char u8;
|
||||
typedef signed char sint8;
|
||||
typedef signed char int8;
|
||||
typedef signed char s8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned short u16;
|
||||
typedef signed short sint16;
|
||||
typedef signed short s16;
|
||||
// CONFLICT typedef unsigned int uint32;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int sint32;
|
||||
typedef signed int s32;
|
||||
typedef int int32;
|
||||
typedef signed long long sint64;
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned long long u64;
|
||||
typedef float real32;
|
||||
typedef double real64;
|
||||
typedef unsigned int u_int;
|
||||
typedef unsigned int u32;
|
||||
typedef signed int sint32;
|
||||
typedef signed int s32;
|
||||
typedef int int32;
|
||||
typedef signed long long sint64;
|
||||
typedef unsigned long long uint64;
|
||||
typedef unsigned long long u64;
|
||||
typedef float real32;
|
||||
typedef double real64;
|
||||
|
||||
#define __le16 u16
|
||||
#define __le16 u16
|
||||
|
||||
#define LOCAL static
|
||||
#define LOCAL static
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (void *)0
|
||||
#define NULL (void*)0
|
||||
#endif /* NULL */
|
||||
|
||||
/* probably should not put STATUS here */
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
OK = 0,
|
||||
FAIL,
|
||||
PENDING,
|
||||
@ -82,10 +83,10 @@ typedef enum {
|
||||
CANCEL,
|
||||
} STATUS;
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
|
||||
#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b))
|
||||
#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b))
|
||||
#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b))
|
||||
#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b))
|
||||
|
||||
#define DMEM_ATTR __attribute__((section(".bss")))
|
||||
#define SHMEM_ATTR
|
||||
@ -93,9 +94,15 @@ typedef enum {
|
||||
#ifdef ICACHE_FLASH
|
||||
#define __ICACHE_STRINGIZE_NX(A) #A
|
||||
#define __ICACHE_STRINGIZE(A) __ICACHE_STRINGIZE_NX(A)
|
||||
#define ICACHE_FLASH_ATTR __attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define IRAM_ATTR __attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define ICACHE_RODATA_ATTR __attribute__((section("\".irom.text." __FILE__ "." __ICACHE_STRINGIZE(__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define ICACHE_FLASH_ATTR \
|
||||
__attribute__((section("\".irom0.text." __FILE__ "." __ICACHE_STRINGIZE( \
|
||||
__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define IRAM_ATTR \
|
||||
__attribute__((section("\".iram.text." __FILE__ "." __ICACHE_STRINGIZE( \
|
||||
__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#define ICACHE_RODATA_ATTR \
|
||||
__attribute__((section("\".irom.text." __FILE__ "." __ICACHE_STRINGIZE( \
|
||||
__LINE__) "." __ICACHE_STRINGIZE(__COUNTER__) "\"")))
|
||||
#else
|
||||
#define ICACHE_FLASH_ATTR
|
||||
#define IRAM_ATTR
|
||||
@ -108,10 +115,9 @@ typedef enum {
|
||||
#define STORE_ATTR __attribute__((aligned(4)))
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define BOOL bool
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
#define BOOL bool
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
#ifndef FAKE_ESP8266_PERI_H
|
||||
#define FAKE_ESP8266_PERI_H
|
||||
|
||||
const int GPI = 0;
|
||||
const int GPO = 0;
|
||||
const int GPI = 0;
|
||||
const int GPO = 0;
|
||||
const int GP16I = 0;
|
||||
|
||||
#endif
|
||||
|
@ -11,17 +11,15 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern uint32_t s_phys_addr;
|
||||
extern uint32_t s_phys_size;
|
||||
extern uint32_t s_phys_page;
|
||||
extern uint32_t s_phys_block;
|
||||
extern uint8_t* s_phys_data;
|
||||
|
||||
extern uint32_t s_phys_addr;
|
||||
extern uint32_t s_phys_size;
|
||||
extern uint32_t s_phys_page;
|
||||
extern uint32_t s_phys_block;
|
||||
extern uint8_t* s_phys_data;
|
||||
|
||||
extern int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst);
|
||||
extern int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src);
|
||||
extern int32_t flash_hal_erase(uint32_t addr, uint32_t size);
|
||||
|
||||
extern int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t* dst);
|
||||
extern int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t* src);
|
||||
extern int32_t flash_hal_erase(uint32_t addr, uint32_t size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -7,31 +7,35 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
uint32_t s_phys_addr = 0;
|
||||
uint32_t s_phys_size = 0;
|
||||
uint32_t s_phys_page = 0;
|
||||
uint32_t s_phys_addr = 0;
|
||||
uint32_t s_phys_size = 0;
|
||||
uint32_t s_phys_page = 0;
|
||||
uint32_t s_phys_block = 0;
|
||||
uint8_t* s_phys_data = nullptr;
|
||||
uint8_t* s_phys_data = nullptr;
|
||||
}
|
||||
|
||||
int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
|
||||
int32_t flash_hal_read(uint32_t addr, uint32_t size, uint8_t* dst)
|
||||
{
|
||||
memcpy(dst, s_phys_data + addr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t *src) {
|
||||
int32_t flash_hal_write(uint32_t addr, uint32_t size, const uint8_t* src)
|
||||
{
|
||||
memcpy(s_phys_data + addr, src, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t flash_hal_erase(uint32_t addr, uint32_t size) {
|
||||
if ((size & (FLASH_SECTOR_SIZE - 1)) != 0 ||
|
||||
(addr & (FLASH_SECTOR_SIZE - 1)) != 0) {
|
||||
int32_t flash_hal_erase(uint32_t addr, uint32_t size)
|
||||
{
|
||||
if ((size & (FLASH_SECTOR_SIZE - 1)) != 0 || (addr & (FLASH_SECTOR_SIZE - 1)) != 0)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
const uint32_t sector = addr / FLASH_SECTOR_SIZE;
|
||||
const uint32_t sector = addr / FLASH_SECTOR_SIZE;
|
||||
const uint32_t sectorCount = size / FLASH_SECTOR_SIZE;
|
||||
for (uint32_t i = 0; i < sectorCount; ++i) {
|
||||
for (uint32_t i = 0; i < sectorCount; ++i)
|
||||
{
|
||||
memset(s_phys_data + (sector + i) * FLASH_SECTOR_SIZE, 0xff, FLASH_SECTOR_SIZE);
|
||||
}
|
||||
return 0;
|
||||
|
@ -26,7 +26,7 @@ class WiFiClient;
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
bool getDefaultPrivateGlobalSyncValue ();
|
||||
bool getDefaultPrivateGlobalSyncValue();
|
||||
|
||||
typedef void (*discard_cb_t)(void*, ClientContext*);
|
||||
|
||||
@ -39,19 +39,19 @@ public:
|
||||
{
|
||||
(void)pcb;
|
||||
}
|
||||
|
||||
ClientContext (int sock) :
|
||||
|
||||
ClientContext(int sock) :
|
||||
_discard_cb(nullptr), _discard_cb_arg(nullptr), _refcnt(0), _next(nullptr),
|
||||
_sync(::getDefaultPrivateGlobalSyncValue()), _sock(sock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
err_t abort()
|
||||
{
|
||||
if (_sock >= 0)
|
||||
{
|
||||
::close(_sock);
|
||||
mockverbose("socket %d closed\n", _sock);
|
||||
mockverbose("socket %d closed\n", _sock);
|
||||
}
|
||||
_sock = -1;
|
||||
return ERR_ABRT;
|
||||
@ -88,11 +88,12 @@ public:
|
||||
void unref()
|
||||
{
|
||||
DEBUGV(":ur %d\r\n", _refcnt);
|
||||
if(--_refcnt == 0) {
|
||||
if (--_refcnt == 0)
|
||||
{
|
||||
discard_received();
|
||||
close();
|
||||
if (_discard_cb)
|
||||
_discard_cb(_discard_cb_arg, this);
|
||||
_discard_cb(_discard_cb_arg, this);
|
||||
DEBUGV(":del\r\n");
|
||||
delete this;
|
||||
}
|
||||
@ -172,10 +173,10 @@ public:
|
||||
int read()
|
||||
{
|
||||
char c;
|
||||
return read(&c, 1)? (unsigned char)c: -1;
|
||||
return read(&c, 1) ? (unsigned char)c : -1;
|
||||
}
|
||||
|
||||
size_t read (char* dst, size_t size)
|
||||
size_t read(char* dst, size_t size)
|
||||
{
|
||||
ssize_t ret = mockRead(_sock, dst, size, 0, _inbuf, _inbufsize);
|
||||
if (ret < 0)
|
||||
@ -189,10 +190,10 @@ public:
|
||||
int peek()
|
||||
{
|
||||
char c;
|
||||
return peekBytes(&c, 1)? c: -1;
|
||||
return peekBytes(&c, 1) ? c : -1;
|
||||
}
|
||||
|
||||
size_t peekBytes(char *dst, size_t size)
|
||||
size_t peekBytes(char* dst, size_t size)
|
||||
{
|
||||
ssize_t ret = mockPeekBytes(_sock, dst, size, _timeout_ms, _inbuf, _inbufsize);
|
||||
if (ret < 0)
|
||||
@ -216,60 +217,62 @@ public:
|
||||
|
||||
uint8_t state()
|
||||
{
|
||||
(void)getSize(); // read on socket to force detect closed peer
|
||||
return _sock >= 0? ESTABLISHED: CLOSED;
|
||||
(void)getSize(); // read on socket to force detect closed peer
|
||||
return _sock >= 0 ? ESTABLISHED : CLOSED;
|
||||
}
|
||||
|
||||
size_t write(const char* data, size_t size)
|
||||
{
|
||||
ssize_t ret = mockWrite(_sock, (const uint8_t*)data, size, _timeout_ms);
|
||||
if (ret < 0)
|
||||
{
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
ssize_t ret = mockWrite(_sock, (const uint8_t*)data, size, _timeout_ms);
|
||||
if (ret < 0)
|
||||
{
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
|
||||
void keepAlive(uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC,
|
||||
uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC,
|
||||
uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT)
|
||||
{
|
||||
(void) idle_sec;
|
||||
(void) intv_sec;
|
||||
(void) count;
|
||||
(void)idle_sec;
|
||||
(void)intv_sec;
|
||||
(void)count;
|
||||
mockverbose("TODO ClientContext::keepAlive()\n");
|
||||
}
|
||||
|
||||
bool isKeepAliveEnabled () const
|
||||
bool isKeepAliveEnabled() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::isKeepAliveEnabled()\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t getKeepAliveIdle () const
|
||||
uint16_t getKeepAliveIdle() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getKeepAliveIdle()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t getKeepAliveInterval () const
|
||||
uint16_t getKeepAliveInterval() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getKeepAliveInternal()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t getKeepAliveCount () const
|
||||
uint8_t getKeepAliveCount() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getKeepAliveCount()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool getSync () const
|
||||
bool getSync() const
|
||||
{
|
||||
mockverbose("TODO ClientContext::getSync()\n");
|
||||
return _sync;
|
||||
}
|
||||
|
||||
void setSync (bool sync)
|
||||
void setSync(bool sync)
|
||||
{
|
||||
mockverbose("TODO ClientContext::setSync()\n");
|
||||
_sync = sync;
|
||||
@ -277,13 +280,13 @@ public:
|
||||
|
||||
// return a pointer to available data buffer (size = peekAvailable())
|
||||
// semantic forbids any kind of read() before calling peekConsume()
|
||||
const char* peekBuffer ()
|
||||
const char* peekBuffer()
|
||||
{
|
||||
return _inbuf;
|
||||
}
|
||||
|
||||
// return number of byte accessible by peekBuffer()
|
||||
size_t peekAvailable ()
|
||||
size_t peekAvailable()
|
||||
{
|
||||
ssize_t ret = mockPeekBytes(_sock, nullptr, 0, 0, _inbuf, _inbufsize);
|
||||
if (ret < 0)
|
||||
@ -295,7 +298,7 @@ public:
|
||||
}
|
||||
|
||||
// consume bytes after use (see peekBuffer)
|
||||
void peekConsume (size_t consume)
|
||||
void peekConsume(size_t consume)
|
||||
{
|
||||
assert(consume <= _inbufsize);
|
||||
memmove(_inbuf, _inbuf + consume, _inbufsize - consume);
|
||||
@ -303,22 +306,21 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
discard_cb_t _discard_cb = nullptr;
|
||||
void* _discard_cb_arg = nullptr;
|
||||
|
||||
discard_cb_t _discard_cb = nullptr;
|
||||
void* _discard_cb_arg = nullptr;
|
||||
|
||||
int8_t _refcnt;
|
||||
int8_t _refcnt;
|
||||
ClientContext* _next;
|
||||
|
||||
|
||||
bool _sync;
|
||||
|
||||
|
||||
// MOCK
|
||||
|
||||
int _sock = -1;
|
||||
|
||||
int _sock = -1;
|
||||
int _timeout_ms = 5000;
|
||||
|
||||
char _inbuf [CCBUFSIZE];
|
||||
char _inbuf[CCBUFSIZE];
|
||||
size_t _inbufsize = 0;
|
||||
};
|
||||
|
||||
#endif //CLIENTCONTEXT_H
|
||||
#endif // CLIENTCONTEXT_H
|
||||
|
@ -37,17 +37,14 @@ extern netif netif0;
|
||||
class UdpContext
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::function<void(void)> rxhandler_t;
|
||||
|
||||
UdpContext(): _on_rx(nullptr), _refcnt(0)
|
||||
UdpContext() : _on_rx(nullptr), _refcnt(0)
|
||||
{
|
||||
_sock = mockUDPSocket();
|
||||
}
|
||||
|
||||
~UdpContext()
|
||||
{
|
||||
}
|
||||
~UdpContext() { }
|
||||
|
||||
void ref()
|
||||
{
|
||||
@ -64,7 +61,7 @@ public:
|
||||
|
||||
bool connect(const ip_addr_t* addr, uint16_t port)
|
||||
{
|
||||
_dst = *addr;
|
||||
_dst = *addr;
|
||||
_dstport = port;
|
||||
return true;
|
||||
}
|
||||
@ -103,7 +100,7 @@ public:
|
||||
void setMulticastTTL(int ttl)
|
||||
{
|
||||
(void)ttl;
|
||||
//mockverbose("TODO: UdpContext::setMulticastTTL\n");
|
||||
// mockverbose("TODO: UdpContext::setMulticastTTL\n");
|
||||
}
|
||||
|
||||
netif* getInputNetif() const
|
||||
@ -156,13 +153,13 @@ public:
|
||||
IPAddress getDestAddress()
|
||||
{
|
||||
mockverbose("TODO: implement UDP getDestAddress\n");
|
||||
return 0; //ip_hdr* iphdr = GET_IP_HDR(_rx_buf);
|
||||
return 0; // ip_hdr* iphdr = GET_IP_HDR(_rx_buf);
|
||||
}
|
||||
|
||||
uint16_t getLocalPort()
|
||||
{
|
||||
mockverbose("TODO: implement UDP getLocalPort\n");
|
||||
return 0; //
|
||||
return 0; //
|
||||
}
|
||||
|
||||
bool next()
|
||||
@ -191,14 +188,14 @@ public:
|
||||
int peek()
|
||||
{
|
||||
char c;
|
||||
return mockUDPPeekBytes(_sock, &c, 1, _timeout_ms, _inbuf, _inbufsize) ? : -1;
|
||||
return mockUDPPeekBytes(_sock, &c, 1, _timeout_ms, _inbuf, _inbufsize) ?: -1;
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
//mockverbose("UdpContext::flush() does not follow arduino's flush concept\n");
|
||||
//exit(EXIT_FAILURE);
|
||||
// would be:
|
||||
// mockverbose("UdpContext::flush() does not follow arduino's flush concept\n");
|
||||
// exit(EXIT_FAILURE);
|
||||
// would be:
|
||||
_inbufsize = 0;
|
||||
}
|
||||
|
||||
@ -206,7 +203,8 @@ public:
|
||||
{
|
||||
if (size + _outbufsize > sizeof _outbuf)
|
||||
{
|
||||
mockverbose("UdpContext::append: increase CCBUFSIZE (%d -> %zd)\n", CCBUFSIZE, (size + _outbufsize));
|
||||
mockverbose("UdpContext::append: increase CCBUFSIZE (%d -> %zd)\n", CCBUFSIZE,
|
||||
(size + _outbufsize));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -217,9 +215,10 @@ public:
|
||||
|
||||
err_t trySend(ip_addr_t* addr = 0, uint16_t port = 0, bool keepBuffer = true)
|
||||
{
|
||||
uint32_t dst = addr ? addr->addr : _dst.addr;
|
||||
uint16_t dstport = port ? : _dstport;
|
||||
size_t wrt = mockUDPWrite(_sock, (const uint8_t*)_outbuf, _outbufsize, _timeout_ms, dst, dstport);
|
||||
uint32_t dst = addr ? addr->addr : _dst.addr;
|
||||
uint16_t dstport = port ?: _dstport;
|
||||
size_t wrt
|
||||
= mockUDPWrite(_sock, (const uint8_t*)_outbuf, _outbufsize, _timeout_ms, dst, dstport);
|
||||
err_t ret = _outbufsize ? ERR_OK : ERR_ABRT;
|
||||
if (!keepBuffer || wrt == _outbufsize)
|
||||
cancelBuffer();
|
||||
@ -239,7 +238,7 @@ public:
|
||||
bool sendTimeout(ip_addr_t* addr, uint16_t port,
|
||||
esp8266::polledTimeout::oneShotFastMs::timeType timeoutMs)
|
||||
{
|
||||
err_t err;
|
||||
err_t err;
|
||||
esp8266::polledTimeout::oneShotFastMs timeout(timeoutMs);
|
||||
while (((err = trySend(addr, port)) != ERR_OK) && !timeout)
|
||||
delay(0);
|
||||
@ -250,15 +249,14 @@ public:
|
||||
|
||||
void mock_cb(void)
|
||||
{
|
||||
if (_on_rx) _on_rx();
|
||||
if (_on_rx)
|
||||
_on_rx();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static uint32_t staticMCastAddr;
|
||||
|
||||
private:
|
||||
|
||||
void translate_addr()
|
||||
{
|
||||
if (addrsize == 4)
|
||||
@ -267,22 +265,22 @@ private:
|
||||
memcpy(&ipv4, addr, 4);
|
||||
ip4_addr_set_u32(&ip_2_ip4(_dst), ipv4);
|
||||
// ^ this is a workaround for "type-punned pointer" with "*(uint32*)addr"
|
||||
//ip4_addr_set_u32(&ip_2_ip4(_dst), *(uint32_t*)addr);
|
||||
// ip4_addr_set_u32(&ip_2_ip4(_dst), *(uint32_t*)addr);
|
||||
}
|
||||
else
|
||||
mockverbose("TODO unhandled udp address of size %d\n", (int)addrsize);
|
||||
}
|
||||
|
||||
int _sock = -1;
|
||||
int _sock = -1;
|
||||
rxhandler_t _on_rx;
|
||||
int _refcnt = 0;
|
||||
int _refcnt = 0;
|
||||
|
||||
ip_addr_t _dst;
|
||||
uint16_t _dstport;
|
||||
uint16_t _dstport;
|
||||
|
||||
char _inbuf [CCBUFSIZE];
|
||||
char _inbuf[CCBUFSIZE];
|
||||
size_t _inbufsize = 0;
|
||||
char _outbuf [CCBUFSIZE];
|
||||
char _outbuf[CCBUFSIZE];
|
||||
size_t _outbufsize = 0;
|
||||
|
||||
int _timeout_ms = 0;
|
||||
@ -291,11 +289,11 @@ private:
|
||||
uint8_t addr[16];
|
||||
};
|
||||
|
||||
extern "C" inline err_t igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
|
||||
extern "C" inline err_t igmp_joingroup(const ip4_addr_t* ifaddr, const ip4_addr_t* groupaddr)
|
||||
{
|
||||
(void)ifaddr;
|
||||
UdpContext::staticMCastAddr = groupaddr->addr;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#endif//UDPCONTEXT_H
|
||||
#endif // UDPCONTEXT_H
|
||||
|
@ -16,7 +16,6 @@
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include "littlefs_mock.h"
|
||||
#include "spiffs_mock.h"
|
||||
#include "spiffs/spiffs.h"
|
||||
@ -56,7 +55,8 @@ LittleFSMock::LittleFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, con
|
||||
|
||||
void LittleFSMock::reset()
|
||||
{
|
||||
LittleFS = FS(FSImplPtr(new littlefs_impl::LittleFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
LittleFS = FS(
|
||||
FSImplPtr(new littlefs_impl::LittleFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
load();
|
||||
}
|
||||
|
||||
@ -72,47 +72,52 @@ LittleFSMock::~LittleFSMock()
|
||||
LittleFS = FS(FSImplPtr(nullptr));
|
||||
}
|
||||
|
||||
void LittleFSMock::load ()
|
||||
void LittleFSMock::load()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
|
||||
|
||||
int fs = ::open(m_storage.c_str(), O_RDONLY);
|
||||
if (fs == -1)
|
||||
{
|
||||
fprintf(stderr, "LittleFS: loading '%s': %s\n", m_storage.c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
off_t flen = lseek(fs, 0, SEEK_END);
|
||||
if (flen == (off_t)-1)
|
||||
{
|
||||
fprintf(stderr, "LittleFS: checking size of '%s': %s\n", m_storage.c_str(), strerror(errno));
|
||||
fprintf(stderr, "LittleFS: checking size of '%s': %s\n", m_storage.c_str(),
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
lseek(fs, 0, SEEK_SET);
|
||||
|
||||
|
||||
if (flen != (off_t)m_fs.size())
|
||||
{
|
||||
fprintf(stderr, "LittleFS: size of '%s': %d does not match requested size %zd\n", m_storage.c_str(), (int)flen, m_fs.size());
|
||||
fprintf(stderr, "LittleFS: size of '%s': %d does not match requested size %zd\n",
|
||||
m_storage.c_str(), (int)flen, m_fs.size());
|
||||
if (!m_overwrite && flen > 0)
|
||||
{
|
||||
fprintf(stderr, "LittleFS: aborting at user request\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "LittleFS: continuing without loading at user request, '%s' will be overwritten\n", m_storage.c_str());
|
||||
fprintf(stderr,
|
||||
"LittleFS: continuing without loading at user request, '%s' will be overwritten\n",
|
||||
m_storage.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "LittleFS: loading %zi bytes from '%s'\n", m_fs.size(), m_storage.c_str());
|
||||
ssize_t r = ::read(fs, m_fs.data(), m_fs.size());
|
||||
if (r != (ssize_t)m_fs.size())
|
||||
fprintf(stderr, "LittleFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r, strerror(errno));
|
||||
fprintf(stderr, "LittleFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r,
|
||||
strerror(errno));
|
||||
}
|
||||
::close(fs);
|
||||
}
|
||||
|
||||
void LittleFSMock::save ()
|
||||
void LittleFSMock::save()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
Based on spiffs_mock:
|
||||
Copyright © 2016 Ivan Grokhotkov
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
@ -27,22 +27,25 @@
|
||||
|
||||
#define DEFAULT_LITTLEFS_FILE_NAME "littlefs.bin"
|
||||
|
||||
class LittleFSMock {
|
||||
class LittleFSMock
|
||||
{
|
||||
public:
|
||||
LittleFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString);
|
||||
LittleFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page,
|
||||
const String& storage = emptyString);
|
||||
void reset();
|
||||
~LittleFSMock();
|
||||
|
||||
|
||||
protected:
|
||||
void load ();
|
||||
void save ();
|
||||
void load();
|
||||
void save();
|
||||
|
||||
std::vector<uint8_t> m_fs;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
};
|
||||
|
||||
#define LITTLEFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) LittleFSMock littlefs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define LITTLEFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
LittleFSMock littlefs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define LITTLEFS_MOCK_RESET() littlefs_mock.reset()
|
||||
|
||||
#endif /* littlefs_mock_hpp */
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
@ -39,16 +39,15 @@
|
||||
#define EXP_FUNC extern
|
||||
#define STDCALL
|
||||
|
||||
#define MD5_SIZE 16
|
||||
#define MD5_SIZE 16
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint32_t state[4]; /* state (ABCD) */
|
||||
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
uint32_t state[4]; /* state (ABCD) */
|
||||
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
|
||||
/* Constants for MD5Transform routine.
|
||||
*/
|
||||
#define S11 7
|
||||
@ -70,15 +69,13 @@ typedef struct
|
||||
|
||||
/* ----- static functions ----- */
|
||||
static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
|
||||
static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
|
||||
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
|
||||
static void Encode(uint8_t* output, uint32_t* input, uint32_t len);
|
||||
static void Decode(uint32_t* output, const uint8_t* input, uint32_t len);
|
||||
|
||||
static const uint8_t PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static const uint8_t PADDING[64]
|
||||
= { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
@ -88,35 +85,39 @@ static const uint8_t PADDING[64] =
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation. */
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += F((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += G((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += H((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{ \
|
||||
(a) += I((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = ROTATE_LEFT((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5 initialization - begins an MD5 operation, writing a new ctx.
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
|
||||
EXP_FUNC void STDCALL MD5Init(MD5_CTX* ctx)
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
|
||||
@ -131,10 +132,10 @@ EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
|
||||
/**
|
||||
* Accepts an array of octets as the next portion of the message.
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
EXP_FUNC void STDCALL MD5Update(MD5_CTX* ctx, const uint8_t* msg, int len)
|
||||
{
|
||||
uint32_t x;
|
||||
int i, partLen;
|
||||
int i, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3F);
|
||||
@ -147,7 +148,7 @@ EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
partLen = 64 - x;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (len >= partLen)
|
||||
if (len >= partLen)
|
||||
{
|
||||
memcpy(&ctx->buffer[x], msg, partLen);
|
||||
MD5Transform(ctx->state, ctx->buffer);
|
||||
@ -161,15 +162,15 @@ EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
memcpy(&ctx->buffer[x], &msg[i], len-i);
|
||||
memcpy(&ctx->buffer[x], &msg[i], len - i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 128-bit message digest into the user's array
|
||||
*/
|
||||
EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
|
||||
EXP_FUNC void STDCALL MD5Final(uint8_t* digest, MD5_CTX* ctx)
|
||||
{
|
||||
uint8_t bits[8];
|
||||
uint8_t bits[8];
|
||||
uint32_t x, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
@ -177,7 +178,7 @@ EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
|
||||
|
||||
/* Pad out to 56 mod 64.
|
||||
*/
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
|
||||
x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
|
||||
padLen = (x < 56) ? (56 - x) : (120 - x);
|
||||
MD5Update(ctx, PADDING, padLen);
|
||||
|
||||
@ -193,82 +194,81 @@ EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
|
||||
*/
|
||||
static void MD5Transform(uint32_t state[4], const uint8_t block[64])
|
||||
{
|
||||
uint32_t a = state[0], b = state[1], c = state[2],
|
||||
d = state[3], x[MD5_SIZE];
|
||||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[MD5_SIZE];
|
||||
|
||||
Decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
@ -280,16 +280,16 @@ static void MD5Transform(uint32_t state[4], const uint8_t block[64])
|
||||
* Encodes input (uint32_t) into output (uint8_t). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
|
||||
static void Encode(uint8_t* output, uint32_t* input, uint32_t len)
|
||||
{
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[j] = (uint8_t)(input[i] & 0xff);
|
||||
output[j+1] = (uint8_t)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (uint8_t)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (uint8_t)((input[i] >> 24) & 0xff);
|
||||
output[j] = (uint8_t)(input[i] & 0xff);
|
||||
output[j + 1] = (uint8_t)((input[i] >> 8) & 0xff);
|
||||
output[j + 2] = (uint8_t)((input[i] >> 16) & 0xff);
|
||||
output[j + 3] = (uint8_t)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,11 +297,11 @@ static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
|
||||
* Decodes input (uint8_t) into output (uint32_t). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len)
|
||||
static void Decode(uint32_t* output, const uint8_t* input, uint32_t len)
|
||||
{
|
||||
uint32_t i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
|
||||
(((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
|
||||
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j + 1]) << 8)
|
||||
| (((uint32_t)input[j + 2]) << 16) | (((uint32_t)input[j + 3]) << 24);
|
||||
}
|
||||
|
@ -30,7 +30,8 @@
|
||||
*/
|
||||
|
||||
#define CORE_MOCK 1
|
||||
#define MOCK "(mock) " // TODO: provide common logging API instead of adding this string everywhere?
|
||||
#define MOCK \
|
||||
"(mock) " // TODO: provide common logging API instead of adding this string everywhere?
|
||||
|
||||
//
|
||||
|
||||
@ -57,15 +58,15 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
// TODO: #include <stdlib_noniso.h> ?
|
||||
char* itoa (int val, char *s, int radix);
|
||||
char* ltoa (long val, char *s, int radix);
|
||||
// TODO: #include <stdlib_noniso.h> ?
|
||||
char* itoa(int val, char* s, int radix);
|
||||
char* ltoa(long val, char* s, int radix);
|
||||
|
||||
|
||||
size_t strlcat(char *dst, const char *src, size_t size);
|
||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
size_t strlcat(char* dst, const char* src, size_t size);
|
||||
size_t strlcpy(char* dst, const char* src, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -74,7 +75,7 @@ size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
// exotic typedefs used in the sdk
|
||||
|
||||
#include <stdint.h>
|
||||
typedef uint8_t uint8;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint32_t uint32;
|
||||
|
||||
//
|
||||
@ -97,26 +98,30 @@ uint32_t esp_get_cycle_count();
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <osapi.h>
|
||||
int ets_printf (const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int ets_printf(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
#define os_printf_plus printf
|
||||
#define ets_vsnprintf vsnprintf
|
||||
inline void ets_putc (char c) { putchar(c); }
|
||||
inline void ets_putc(char c)
|
||||
{
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
int mockverbose (const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
int mockverbose(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
extern const char* host_interface; // cmdline parameter
|
||||
extern bool serial_timestamp;
|
||||
extern int mock_port_shifter;
|
||||
extern bool blocking_uart;
|
||||
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
|
||||
extern const char* host_interface; // cmdline parameter
|
||||
extern bool serial_timestamp;
|
||||
extern int mock_port_shifter;
|
||||
extern bool blocking_uart;
|
||||
extern uint32_t global_source_address; // 0 = INADDR_ANY by default
|
||||
|
||||
#define NO_GLOBAL_BINDING 0xffffffff
|
||||
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to
|
||||
extern uint32_t global_ipv4_netfmt; // selected interface addresse to bind to
|
||||
|
||||
void loop_end();
|
||||
void loop_end();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -132,41 +137,48 @@ void loop_end();
|
||||
|
||||
// uart
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void uart_new_data(const int uart_nr, uint8_t data);
|
||||
void uart_new_data(const int uart_nr, uint8_t data);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// tcp
|
||||
int mockSockSetup (int sock);
|
||||
int mockConnect (uint32_t addr, int& sock, int port);
|
||||
ssize_t mockFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize);
|
||||
ssize_t mockPeekBytes (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockRead (int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockWrite (int sock, const uint8_t* data, size_t size, int timeout_ms);
|
||||
int serverAccept (int sock);
|
||||
int mockSockSetup(int sock);
|
||||
int mockConnect(uint32_t addr, int& sock, int port);
|
||||
ssize_t mockFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize);
|
||||
ssize_t mockPeekBytes(int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockRead(int sock, char* dst, size_t size, int timeout_ms, char* buf, size_t& bufsize);
|
||||
ssize_t mockWrite(int sock, const uint8_t* data, size_t size, int timeout_ms);
|
||||
int serverAccept(int sock);
|
||||
|
||||
// udp
|
||||
void check_incoming_udp ();
|
||||
int mockUDPSocket ();
|
||||
bool mockUDPListen (int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast = 0);
|
||||
size_t mockUDPFillInBuf (int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize, uint8_t addr[16], uint16_t& port);
|
||||
size_t mockUDPPeekBytes (int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf, size_t& ccinbufsize);
|
||||
size_t mockUDPRead (int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf, size_t& ccinbufsize);
|
||||
size_t mockUDPWrite (int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4, uint16_t port);
|
||||
void mockUDPSwallow (size_t copied, char* ccinbuf, size_t& ccinbufsize);
|
||||
void check_incoming_udp();
|
||||
int mockUDPSocket();
|
||||
bool mockUDPListen(int sock, uint32_t dstaddr, uint16_t port, uint32_t mcast = 0);
|
||||
size_t mockUDPFillInBuf(int sock, char* ccinbuf, size_t& ccinbufsize, uint8_t& addrsize,
|
||||
uint8_t addr[16], uint16_t& port);
|
||||
size_t mockUDPPeekBytes(int sock, char* dst, size_t usersize, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize);
|
||||
size_t mockUDPRead(int sock, char* dst, size_t size, int timeout_ms, char* ccinbuf,
|
||||
size_t& ccinbufsize);
|
||||
size_t mockUDPWrite(int sock, const uint8_t* data, size_t size, int timeout_ms, uint32_t ipv4,
|
||||
uint16_t port);
|
||||
void mockUDPSwallow(size_t copied, char* ccinbuf, size_t& ccinbufsize);
|
||||
|
||||
class UdpContext;
|
||||
void register_udp (int sock, UdpContext* udp = nullptr);
|
||||
void register_udp(int sock, UdpContext* udp = nullptr);
|
||||
|
||||
//
|
||||
|
||||
void mock_start_spiffs (const String& fname, size_t size_kb, size_t block_kb = 8, size_t page_b = 512);
|
||||
void mock_stop_spiffs ();
|
||||
void mock_start_littlefs (const String& fname, size_t size_kb, size_t block_kb = 8, size_t page_b = 512);
|
||||
void mock_stop_littlefs ();
|
||||
void mock_start_spiffs(const String& fname, size_t size_kb, size_t block_kb = 8,
|
||||
size_t page_b = 512);
|
||||
void mock_stop_spiffs();
|
||||
void mock_start_littlefs(const String& fname, size_t size_kb, size_t block_kb = 8,
|
||||
size_t page_b = 512);
|
||||
void mock_stop_littlefs();
|
||||
|
||||
//
|
||||
|
||||
@ -174,4 +186,4 @@ void mock_stop_littlefs ();
|
||||
|
||||
//
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // __cplusplus
|
||||
|
@ -1,19 +1,18 @@
|
||||
/*
|
||||
noniso.cpp - replacements for non-ISO functions used by Arduino core
|
||||
Copyright © 2016 Ivan Grokhotkov
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
@ -21,61 +20,69 @@
|
||||
#include <math.h>
|
||||
#include "stdlib_noniso.h"
|
||||
|
||||
|
||||
void reverse(char* begin, char* end) {
|
||||
char *is = begin;
|
||||
char *ie = end - 1;
|
||||
while(is < ie) {
|
||||
void reverse(char* begin, char* end)
|
||||
{
|
||||
char* is = begin;
|
||||
char* ie = end - 1;
|
||||
while (is < ie)
|
||||
{
|
||||
char tmp = *ie;
|
||||
*ie = *is;
|
||||
*is = tmp;
|
||||
*ie = *is;
|
||||
*is = tmp;
|
||||
++is;
|
||||
--ie;
|
||||
}
|
||||
}
|
||||
|
||||
char* utoa(unsigned value, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
char* utoa(unsigned value, char* result, int base)
|
||||
{
|
||||
if (base < 2 || base > 16)
|
||||
{
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* out = result;
|
||||
char* out = result;
|
||||
unsigned quotient = value;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
const unsigned tmp = quotient / base;
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
++out;
|
||||
quotient = tmp;
|
||||
} while(quotient);
|
||||
} while (quotient);
|
||||
|
||||
reverse(result, out);
|
||||
*out = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
char* itoa(int value, char* result, int base) {
|
||||
if(base < 2 || base > 16) {
|
||||
char* itoa(int value, char* result, int base)
|
||||
{
|
||||
if (base < 2 || base > 16)
|
||||
{
|
||||
*result = 0;
|
||||
return result;
|
||||
}
|
||||
if (base != 10) {
|
||||
return utoa((unsigned)value, result, base);
|
||||
}
|
||||
if (base != 10)
|
||||
{
|
||||
return utoa((unsigned)value, result, base);
|
||||
}
|
||||
|
||||
char* out = result;
|
||||
int quotient = abs(value);
|
||||
char* out = result;
|
||||
int quotient = abs(value);
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
const int tmp = quotient / base;
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
*out = "0123456789abcdef"[quotient - (tmp * base)];
|
||||
++out;
|
||||
quotient = tmp;
|
||||
} while(quotient);
|
||||
} while (quotient);
|
||||
|
||||
// Apply negative sign
|
||||
if(value < 0)
|
||||
if (value < 0)
|
||||
*out++ = '-';
|
||||
|
||||
reverse(result, out);
|
||||
@ -83,17 +90,19 @@ char* itoa(int value, char* result, int base) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int atoi(const char* s) {
|
||||
return (int) atol(s);
|
||||
int atoi(const char* s)
|
||||
{
|
||||
return (int)atol(s);
|
||||
}
|
||||
|
||||
long atol(const char* s) {
|
||||
char * tmp;
|
||||
long atol(const char* s)
|
||||
{
|
||||
char* tmp;
|
||||
return strtol(s, &tmp, 10);
|
||||
}
|
||||
|
||||
double atof(const char* s) {
|
||||
char * tmp;
|
||||
double atof(const char* s)
|
||||
{
|
||||
char* tmp;
|
||||
return strtod(s, &tmp);
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
/*
|
||||
pins_arduino.h
|
||||
Copyright © 2016 Ivan Grokhotkov
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
#ifndef pins_arduino_h
|
||||
#define pins_arduino_h
|
||||
|
||||
|
||||
#endif /* pins_arduino_h */
|
||||
|
@ -35,9 +35,9 @@
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
|
||||
#include <machine/ansi.h> /* for __offsetof */
|
||||
#include <machine/ansi.h> /* for __offsetof */
|
||||
|
||||
/*
|
||||
* This file defines four types of data structures: singly-linked lists,
|
||||
@ -106,322 +106,373 @@
|
||||
/*
|
||||
* Singly-linked List declarations.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL \
|
||||
}
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for ((var) = SLIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = SLIST_NEXT((var), field))
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for ((var) = SLIST_FIRST((head)); (var); (var) = SLIST_NEXT((var), field))
|
||||
|
||||
#define SLIST_INIT(head) do { \
|
||||
SLIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
#define SLIST_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if (SLIST_FIRST((head)) == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = SLIST_FIRST((head)); \
|
||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||
curelm = SLIST_NEXT(curelm, field); \
|
||||
SLIST_NEXT(curelm, field) = \
|
||||
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SLIST_REMOVE(head, elm, type, field) \
|
||||
do \
|
||||
{ \
|
||||
if (SLIST_FIRST((head)) == (elm)) \
|
||||
{ \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
struct type* curelm = SLIST_FIRST((head)); \
|
||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||
curelm = SLIST_NEXT(curelm, field); \
|
||||
SLIST_NEXT(curelm, field) = SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||
} while (0)
|
||||
#define SLIST_REMOVE_HEAD(head, field) \
|
||||
do \
|
||||
{ \
|
||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue declarations.
|
||||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first;/* first element */ \
|
||||
struct type **stqh_last;/* addr of last next element */ \
|
||||
}
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* stqh_first; /* first element */ \
|
||||
struct type** stqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).stqh_first }
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL, &(head).stqh_first \
|
||||
}
|
||||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue functions.
|
||||
*/
|
||||
#define STAILQ_CONCAT(head1, head2) do { \
|
||||
if (!STAILQ_EMPTY((head2))) { \
|
||||
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||
(head1)->stqh_last = (head2)->stqh_last; \
|
||||
STAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define STAILQ_CONCAT(head1, head2) \
|
||||
do \
|
||||
{ \
|
||||
if (!STAILQ_EMPTY((head2))) \
|
||||
{ \
|
||||
*(head1)->stqh_last = (head2)->stqh_first; \
|
||||
(head1)->stqh_last = (head2)->stqh_last; \
|
||||
STAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for((var) = STAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = STAILQ_NEXT((var), field))
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = STAILQ_FIRST((head)); (var); (var) = STAILQ_NEXT((var), field))
|
||||
|
||||
#define STAILQ_INIT(head) do { \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define STAILQ_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||
} while (0)
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
STAILQ_NEXT((elm), field) = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
STAILQ_NEXT((elm), field) = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY((head)) ? \
|
||||
NULL : \
|
||||
((struct type *) \
|
||||
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY((head)) \
|
||||
? NULL \
|
||||
: ((struct type*)((char*)((head)->stqh_last) - __offsetof(struct type, field))))
|
||||
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
|
||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||
STAILQ_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = STAILQ_FIRST((head)); \
|
||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||
curelm = STAILQ_NEXT(curelm, field); \
|
||||
if ((STAILQ_NEXT(curelm, field) = \
|
||||
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
||||
} \
|
||||
} while (0)
|
||||
#define STAILQ_REMOVE(head, elm, type, field) \
|
||||
do \
|
||||
{ \
|
||||
if (STAILQ_FIRST((head)) == (elm)) \
|
||||
{ \
|
||||
STAILQ_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
struct type* curelm = STAILQ_FIRST((head)); \
|
||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||
curelm = STAILQ_NEXT(curelm, field); \
|
||||
if ((STAILQ_NEXT(curelm, field) = STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) \
|
||||
== NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = \
|
||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define STAILQ_REMOVE_HEAD(head, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* List declarations.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL \
|
||||
}
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
#define LIST_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* le_next; /* next element */ \
|
||||
struct type** le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = LIST_NEXT((var), field))
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); (var); (var) = LIST_NEXT((var), field))
|
||||
|
||||
#define LIST_INIT(head) do { \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
#define LIST_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||
&LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \
|
||||
LIST_NEXT((listelm), field)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
#define LIST_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define LIST_REMOVE(elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = (elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Tail queue declarations.
|
||||
*/
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name \
|
||||
{ \
|
||||
struct type* tqh_first; /* first element */ \
|
||||
struct type** tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ \
|
||||
NULL, &(head).tqh_first \
|
||||
}
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct \
|
||||
{ \
|
||||
struct type* tqe_next; /* next element */ \
|
||||
struct type** tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_CONCAT(head1, head2, field) do { \
|
||||
if (!TAILQ_EMPTY(head2)) { \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define TAILQ_CONCAT(head1, head2, field) \
|
||||
do \
|
||||
{ \
|
||||
if (!TAILQ_EMPTY(head2)) \
|
||||
{ \
|
||||
*(head1)->tqh_last = (head2)->tqh_first; \
|
||||
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
|
||||
(head1)->tqh_last = (head2)->tqh_last; \
|
||||
TAILQ_INIT((head2)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = TAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = TAILQ_NEXT((var), field))
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = TAILQ_FIRST((head)); (var); (var) = TAILQ_NEXT((var), field))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var); \
|
||||
(var) = TAILQ_PREV((var), headname, field))
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = TAILQ_LAST((head), headname); (var); (var) = TAILQ_PREV((var), headname, field))
|
||||
|
||||
#define TAILQ_INIT(head) do { \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define TAILQ_INIT(head) \
|
||||
do \
|
||||
{ \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
TAILQ_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
TAILQ_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_FIRST((head)) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||
TAILQ_FIRST((head))->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_FIRST((head)) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
TAILQ_NEXT((elm), field) = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
TAILQ_NEXT((elm), field) = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define TAILQ_LAST(head, headname) (*(((struct headname*)((head)->tqh_last))->tqh_last))
|
||||
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
#define TAILQ_PREV(elm, headname, field) (*(((struct headname*)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) \
|
||||
do \
|
||||
{ \
|
||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = (elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
@ -430,39 +481,37 @@ struct { \
|
||||
* They bogusly assumes that all queue heads look alike.
|
||||
*/
|
||||
|
||||
struct quehead {
|
||||
struct quehead *qh_link;
|
||||
struct quehead *qh_rlink;
|
||||
struct quehead
|
||||
{
|
||||
struct quehead* qh_link;
|
||||
struct quehead* qh_rlink;
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef __GNUC__
|
||||
|
||||
static __inline void
|
||||
insque(void *a, void *b)
|
||||
static __inline void insque(void* a, void* b)
|
||||
{
|
||||
struct quehead *element = (struct quehead *)a,
|
||||
*head = (struct quehead *)b;
|
||||
struct quehead *element = (struct quehead*)a, *head = (struct quehead*)b;
|
||||
|
||||
element->qh_link = head->qh_link;
|
||||
element->qh_rlink = head;
|
||||
head->qh_link = element;
|
||||
element->qh_link->qh_rlink = element;
|
||||
element->qh_link = head->qh_link;
|
||||
element->qh_rlink = head;
|
||||
head->qh_link = element;
|
||||
element->qh_link->qh_rlink = element;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
remque(void *a)
|
||||
static __inline void remque(void* a)
|
||||
{
|
||||
struct quehead *element = (struct quehead *)a;
|
||||
struct quehead* element = (struct quehead*)a;
|
||||
|
||||
element->qh_link->qh_rlink = element->qh_rlink;
|
||||
element->qh_rlink->qh_link = element->qh_link;
|
||||
element->qh_rlink = 0;
|
||||
element->qh_link->qh_rlink = element->qh_rlink;
|
||||
element->qh_rlink->qh_link = element->qh_link;
|
||||
element->qh_rlink = 0;
|
||||
}
|
||||
|
||||
#else /* !__GNUC__ */
|
||||
|
||||
void insque(void *a, void *b);
|
||||
void remque(void *a);
|
||||
void insque(void* a, void* b);
|
||||
void remque(void* a);
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
|
@ -18,4 +18,4 @@
|
||||
|
||||
#define SDSIZE 16LL
|
||||
uint64_t _sdCardSizeB = 0;
|
||||
uint8_t *_sdCard = nullptr;
|
||||
uint8_t* _sdCard = nullptr;
|
||||
|
@ -21,22 +21,32 @@
|
||||
#include <vector>
|
||||
#include <FS.h>
|
||||
|
||||
class SDFSMock {
|
||||
class SDFSMock
|
||||
{
|
||||
public:
|
||||
SDFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString) { (void)fs_size; (void)fs_block; (void)fs_page; (void)storage; }
|
||||
SDFSMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString)
|
||||
{
|
||||
(void)fs_size;
|
||||
(void)fs_block;
|
||||
(void)fs_page;
|
||||
(void)storage;
|
||||
}
|
||||
void reset() { }
|
||||
~SDFSMock() { }
|
||||
};
|
||||
|
||||
extern uint64_t _sdCardSizeB;
|
||||
extern uint8_t *_sdCard;
|
||||
extern uint8_t* _sdCard;
|
||||
|
||||
#define SDFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
SDFS.end(); \
|
||||
SDFSMock sdfs_mock(size_kb * 1024, block_kb * 1024, page_b, storage); free(_sdCard); \
|
||||
_sdCardSizeB = size_kb ? 16 * 1024 * 1024 : 0; \
|
||||
if (_sdCardSizeB) _sdCard = (uint8_t*)calloc(_sdCardSizeB, 1); \
|
||||
else _sdCard = nullptr; \
|
||||
#define SDFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
SDFS.end(); \
|
||||
SDFSMock sdfs_mock(size_kb * 1024, block_kb * 1024, page_b, storage); \
|
||||
free(_sdCard); \
|
||||
_sdCardSizeB = size_kb ? 16 * 1024 * 1024 : 0; \
|
||||
if (_sdCardSizeB) \
|
||||
_sdCard = (uint8_t*)calloc(_sdCardSizeB, 1); \
|
||||
else \
|
||||
_sdCard = nullptr; \
|
||||
SDFS.setConfig(SDFSConfig().setAutoFormat(true));
|
||||
#define SDFS_MOCK_RESET() sdfs_mock.reset()
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include "spiffs_mock.h"
|
||||
#include "spiffs/spiffs.h"
|
||||
#include "debug.h"
|
||||
@ -54,7 +53,8 @@ SpiffsMock::SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const S
|
||||
|
||||
void SpiffsMock::reset()
|
||||
{
|
||||
SPIFFS = FS(FSImplPtr(new spiffs_impl::SPIFFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
SPIFFS
|
||||
= FS(FSImplPtr(new spiffs_impl::SPIFFSImpl(0, s_phys_size, s_phys_page, s_phys_block, 5)));
|
||||
load();
|
||||
}
|
||||
|
||||
@ -70,18 +70,18 @@ SpiffsMock::~SpiffsMock()
|
||||
SPIFFS = FS(FSImplPtr(nullptr));
|
||||
}
|
||||
|
||||
void SpiffsMock::load ()
|
||||
void SpiffsMock::load()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
|
||||
|
||||
int fs = ::open(m_storage.c_str(), O_RDONLY);
|
||||
if (fs == -1)
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: loading '%s': %s\n", m_storage.c_str(), strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
off_t flen = lseek(fs, 0, SEEK_END);
|
||||
if (flen == (off_t)-1)
|
||||
{
|
||||
@ -89,28 +89,32 @@ void SpiffsMock::load ()
|
||||
return;
|
||||
}
|
||||
lseek(fs, 0, SEEK_SET);
|
||||
|
||||
|
||||
if (flen != (off_t)m_fs.size())
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n", m_storage.c_str(), (int)flen, m_fs.size());
|
||||
fprintf(stderr, "SPIFFS: size of '%s': %d does not match requested size %zd\n",
|
||||
m_storage.c_str(), (int)flen, m_fs.size());
|
||||
if (!m_overwrite && flen > 0)
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: aborting at user request\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "SPIFFS: continuing without loading at user request, '%s' will be overwritten\n", m_storage.c_str());
|
||||
fprintf(stderr,
|
||||
"SPIFFS: continuing without loading at user request, '%s' will be overwritten\n",
|
||||
m_storage.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "SPIFFS: loading %zi bytes from '%s'\n", m_fs.size(), m_storage.c_str());
|
||||
ssize_t r = ::read(fs, m_fs.data(), m_fs.size());
|
||||
if (r != (ssize_t)m_fs.size())
|
||||
fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r, strerror(errno));
|
||||
fprintf(stderr, "SPIFFS: reading %zi bytes: returned %zd: %s\n", m_fs.size(), r,
|
||||
strerror(errno));
|
||||
}
|
||||
::close(fs);
|
||||
}
|
||||
|
||||
void SpiffsMock::save ()
|
||||
void SpiffsMock::save()
|
||||
{
|
||||
if (!m_fs.size() || !m_storage.length())
|
||||
return;
|
||||
@ -130,4 +134,3 @@ void SpiffsMock::save ()
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
/*
|
||||
spiffs_mock.h - SPIFFS HAL mock for host side testing
|
||||
Copyright © 2016 Ivan Grokhotkov
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
*/
|
||||
@ -24,22 +24,25 @@
|
||||
|
||||
#define DEFAULT_SPIFFS_FILE_NAME "spiffs.bin"
|
||||
|
||||
class SpiffsMock {
|
||||
class SpiffsMock
|
||||
{
|
||||
public:
|
||||
SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page, const String& storage = emptyString);
|
||||
SpiffsMock(ssize_t fs_size, size_t fs_block, size_t fs_page,
|
||||
const String& storage = emptyString);
|
||||
void reset();
|
||||
~SpiffsMock();
|
||||
|
||||
|
||||
protected:
|
||||
void load ();
|
||||
void save ();
|
||||
void load();
|
||||
void save();
|
||||
|
||||
std::vector<uint8_t> m_fs;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
String m_storage;
|
||||
bool m_overwrite;
|
||||
};
|
||||
|
||||
#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define SPIFFS_MOCK_DECLARE(size_kb, block_kb, page_b, storage) \
|
||||
SpiffsMock spiffs_mock(size_kb * 1024, block_kb * 1024, page_b, storage)
|
||||
#define SPIFFS_MOCK_RESET() spiffs_mock.reset()
|
||||
|
||||
#endif /* spiffs_mock_hpp */
|
||||
|
@ -5,25 +5,24 @@
|
||||
'_cups_strlcat()' - Safely concatenate two strings.
|
||||
*/
|
||||
|
||||
size_t /* O - Length of string */
|
||||
strlcat(char *dst, /* O - Destination string */
|
||||
const char *src, /* I - Source string */
|
||||
size_t size) /* I - Size of destination string buffer */
|
||||
size_t /* O - Length of string */
|
||||
strlcat(char* dst, /* O - Destination string */
|
||||
const char* src, /* I - Source string */
|
||||
size_t size) /* I - Size of destination string buffer */
|
||||
{
|
||||
size_t srclen; /* Length of source string */
|
||||
size_t dstlen; /* Length of destination string */
|
||||
|
||||
size_t srclen; /* Length of source string */
|
||||
size_t dstlen; /* Length of destination string */
|
||||
|
||||
/*
|
||||
Figure out how much room is left...
|
||||
*/
|
||||
|
||||
dstlen = strlen(dst);
|
||||
size -= dstlen + 1;
|
||||
size -= dstlen + 1;
|
||||
|
||||
if (!size)
|
||||
{
|
||||
return (dstlen); /* No room, return immediately... */
|
||||
return (dstlen); /* No room, return immediately... */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -53,19 +52,18 @@ strlcat(char *dst, /* O - Destination string */
|
||||
'_cups_strlcpy()' - Safely copy two strings.
|
||||
*/
|
||||
|
||||
size_t /* O - Length of string */
|
||||
strlcpy(char *dst, /* O - Destination string */
|
||||
const char *src, /* I - Source string */
|
||||
size_t /* O - Length of string */
|
||||
strlcpy(char* dst, /* O - Destination string */
|
||||
const char* src, /* I - Source string */
|
||||
size_t size) /* I - Size of destination string buffer */
|
||||
{
|
||||
size_t srclen; /* Length of source string */
|
||||
|
||||
size_t srclen; /* Length of source string */
|
||||
|
||||
/*
|
||||
Figure out how much room is needed...
|
||||
*/
|
||||
|
||||
size --;
|
||||
size--;
|
||||
|
||||
srclen = strlen(src);
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
#include <LwipDhcpServer.h>
|
||||
|
||||
bool DhcpServer::set_dhcps_lease(struct dhcps_lease *please)
|
||||
bool DhcpServer::set_dhcps_lease(struct dhcps_lease* please)
|
||||
{
|
||||
(void)please;
|
||||
return false;
|
||||
@ -62,22 +62,20 @@ bool DhcpServer::set_dhcps_offer_option(uint8 level, void* optarg)
|
||||
return false;
|
||||
}
|
||||
|
||||
void DhcpServer::end ()
|
||||
{
|
||||
}
|
||||
void DhcpServer::end() { }
|
||||
|
||||
bool DhcpServer::begin (struct ip_info *info)
|
||||
bool DhcpServer::begin(struct ip_info* info)
|
||||
{
|
||||
(void)info;
|
||||
return false;
|
||||
}
|
||||
|
||||
DhcpServer::DhcpServer (netif* netif)
|
||||
DhcpServer::DhcpServer(netif* netif)
|
||||
{
|
||||
(void)netif;
|
||||
}
|
||||
|
||||
DhcpServer::~DhcpServer ()
|
||||
DhcpServer::~DhcpServer()
|
||||
{
|
||||
end();
|
||||
}
|
||||
@ -86,7 +84,6 @@ DhcpServer dhcpSoftAP(nullptr);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <lwip/netif.h>
|
||||
|
||||
@ -120,14 +117,14 @@ extern "C"
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool wifi_station_get_config(struct station_config *config)
|
||||
bool wifi_station_get_config(struct station_config* config)
|
||||
{
|
||||
strcpy((char*)config->ssid, "emulated-ssid");
|
||||
strcpy((char*)config->password, "emulated-ssid-password");
|
||||
config->bssid_set = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
config->bssid[i] = i;
|
||||
config->threshold.rssi = 1;
|
||||
config->threshold.rssi = 1;
|
||||
config->threshold.authmode = AUTH_WPA_PSK;
|
||||
#ifdef NONOSDK3V0
|
||||
config->open_and_wep_mode_disable = true;
|
||||
@ -135,9 +132,7 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
void wifi_fpm_close(void)
|
||||
{
|
||||
}
|
||||
void wifi_fpm_close(void) { }
|
||||
|
||||
sint8 wifi_fpm_do_sleep(uint32 sleep_time_in_us)
|
||||
{
|
||||
@ -145,34 +140,30 @@ extern "C"
|
||||
return 1;
|
||||
}
|
||||
|
||||
void wifi_fpm_do_wakeup(void)
|
||||
{
|
||||
}
|
||||
void wifi_fpm_do_wakeup(void) { }
|
||||
|
||||
void wifi_fpm_open(void)
|
||||
{
|
||||
}
|
||||
void wifi_fpm_open(void) { }
|
||||
|
||||
void wifi_fpm_set_sleep_type(sleep_type_t type)
|
||||
{
|
||||
(void)type;
|
||||
}
|
||||
|
||||
uint32_t global_ipv4_netfmt = 0; // global binding
|
||||
uint32_t global_ipv4_netfmt = 0; // global binding
|
||||
|
||||
netif netif0;
|
||||
netif netif0;
|
||||
uint32_t global_source_address = INADDR_ANY;
|
||||
|
||||
bool wifi_get_ip_info(uint8 if_index, struct ip_info *info)
|
||||
bool wifi_get_ip_info(uint8 if_index, struct ip_info* info)
|
||||
{
|
||||
// emulate wifi_get_ip_info()
|
||||
// ignore if_index
|
||||
// use global option -i (host_interface) to select bound interface/address
|
||||
|
||||
struct ifaddrs * ifAddrStruct = NULL, * ifa = NULL;
|
||||
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
||||
uint32_t mask = lwip_htonl(0xff000000);
|
||||
global_source_address = INADDR_ANY; // =0
|
||||
struct ifaddrs *ifAddrStruct = NULL, *ifa = NULL;
|
||||
uint32_t ipv4 = lwip_htonl(0x7f000001);
|
||||
uint32_t mask = lwip_htonl(0xff000000);
|
||||
global_source_address = INADDR_ANY; // =0
|
||||
|
||||
if (getifaddrs(&ifAddrStruct) != 0)
|
||||
{
|
||||
@ -186,22 +177,24 @@ extern "C"
|
||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
mockverbose("host: interface: %s", ifa->ifa_name);
|
||||
if (ifa->ifa_addr
|
||||
&& ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
|
||||
)
|
||||
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET // ip_info is IPv4 only
|
||||
)
|
||||
{
|
||||
auto test_ipv4 = lwip_ntohl(*(uint32_t*) & ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
|
||||
auto test_ipv4
|
||||
= lwip_ntohl(*(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr);
|
||||
mockverbose(" IPV4 (0x%08lx)", test_ipv4);
|
||||
if ((test_ipv4 & 0xff000000) == 0x7f000000)
|
||||
// 127./8
|
||||
mockverbose(" (local, ignored)");
|
||||
else
|
||||
{
|
||||
if (!host_interface || (host_interface && strcmp(ifa->ifa_name, host_interface) == 0))
|
||||
if (!host_interface
|
||||
|| (host_interface && strcmp(ifa->ifa_name, host_interface) == 0))
|
||||
{
|
||||
// use the first non-local interface, or, if specified, the one selected by user on cmdline
|
||||
ipv4 = *(uint32_t*) & ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||
mask = *(uint32_t*) & ((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||
// use the first non-local interface, or, if specified, the one selected by
|
||||
// user on cmdline
|
||||
ipv4 = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
|
||||
mask = *(uint32_t*)&((struct sockaddr_in*)ifa->ifa_netmask)->sin_addr;
|
||||
mockverbose(" (selected)\n");
|
||||
if (host_interface)
|
||||
global_source_address = ntohl(ipv4);
|
||||
@ -216,7 +209,7 @@ extern "C"
|
||||
freeifaddrs(ifAddrStruct);
|
||||
|
||||
(void)if_index;
|
||||
//if (if_index != STATION_IF)
|
||||
// if (if_index != STATION_IF)
|
||||
// fprintf(stderr, "we are not AP");
|
||||
|
||||
if (global_ipv4_netfmt == NO_GLOBAL_BINDING)
|
||||
@ -224,15 +217,15 @@ extern "C"
|
||||
|
||||
if (info)
|
||||
{
|
||||
info->ip.addr = ipv4;
|
||||
info->ip.addr = ipv4;
|
||||
info->netmask.addr = mask;
|
||||
info->gw.addr = ipv4;
|
||||
info->gw.addr = ipv4;
|
||||
|
||||
netif0.ip_addr.addr = ipv4;
|
||||
netif0.netmask.addr = mask;
|
||||
netif0.gw.addr = ipv4;
|
||||
netif0.flags = NETIF_FLAG_IGMP | NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
|
||||
netif0.next = nullptr;
|
||||
netif0.gw.addr = ipv4;
|
||||
netif0.flags = NETIF_FLAG_IGMP | NETIF_FLAG_UP | NETIF_FLAG_LINK_UP;
|
||||
netif0.next = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -243,7 +236,7 @@ extern "C"
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool wifi_get_macaddr(uint8 if_index, uint8 *macaddr)
|
||||
bool wifi_get_macaddr(uint8 if_index, uint8* macaddr)
|
||||
{
|
||||
(void)if_index;
|
||||
macaddr[0] = 0xde;
|
||||
@ -267,7 +260,7 @@ extern "C"
|
||||
return MIN_SLEEP_T;
|
||||
}
|
||||
|
||||
#endif // nonos-sdk-pre-3
|
||||
#endif // nonos-sdk-pre-3
|
||||
|
||||
sleep_type_t wifi_get_sleep_type(void)
|
||||
{
|
||||
@ -281,13 +274,13 @@ extern "C"
|
||||
}
|
||||
|
||||
wifi_event_handler_cb_t wifi_event_handler_cb_emu = nullptr;
|
||||
void wifi_set_event_handler_cb(wifi_event_handler_cb_t cb)
|
||||
void wifi_set_event_handler_cb(wifi_event_handler_cb_t cb)
|
||||
{
|
||||
wifi_event_handler_cb_emu = cb;
|
||||
mockverbose("TODO: wifi_set_event_handler_cb set\n");
|
||||
}
|
||||
|
||||
bool wifi_set_ip_info(uint8 if_index, struct ip_info *info)
|
||||
bool wifi_set_ip_info(uint8 if_index, struct ip_info* info)
|
||||
{
|
||||
(void)if_index;
|
||||
(void)info;
|
||||
@ -352,12 +345,12 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_get_config_default(struct station_config *config)
|
||||
bool wifi_station_get_config_default(struct station_config* config)
|
||||
{
|
||||
return wifi_station_get_config(config);
|
||||
}
|
||||
|
||||
char wifi_station_get_hostname_str [128];
|
||||
char wifi_station_get_hostname_str[128];
|
||||
const char* wifi_station_get_hostname(void)
|
||||
{
|
||||
return strcpy(wifi_station_get_hostname_str, "esposix");
|
||||
@ -378,19 +371,19 @@ extern "C"
|
||||
return set != 0;
|
||||
}
|
||||
|
||||
bool wifi_station_set_config(struct station_config *config)
|
||||
bool wifi_station_set_config(struct station_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_set_config_current(struct station_config *config)
|
||||
bool wifi_station_set_config_current(struct station_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_set_hostname(const char *name)
|
||||
bool wifi_station_set_hostname(const char* name)
|
||||
{
|
||||
(void)name;
|
||||
return true;
|
||||
@ -422,20 +415,20 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_get_config(struct softap_config *config)
|
||||
bool wifi_softap_get_config(struct softap_config* config)
|
||||
{
|
||||
strcpy((char*)config->ssid, "apssid");
|
||||
strcpy((char*)config->password, "appasswd");
|
||||
config->ssid_len = strlen("appasswd");
|
||||
config->channel = 1;
|
||||
config->authmode = AUTH_WPA2_PSK;
|
||||
config->ssid_hidden = 0;
|
||||
config->max_connection = 4;
|
||||
config->ssid_len = strlen("appasswd");
|
||||
config->channel = 1;
|
||||
config->authmode = AUTH_WPA2_PSK;
|
||||
config->ssid_hidden = 0;
|
||||
config->max_connection = 4;
|
||||
config->beacon_interval = 100;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_get_config_default(struct softap_config *config)
|
||||
bool wifi_softap_get_config_default(struct softap_config* config)
|
||||
{
|
||||
return wifi_softap_get_config(config);
|
||||
}
|
||||
@ -445,19 +438,19 @@ extern "C"
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool wifi_softap_set_config(struct softap_config *config)
|
||||
bool wifi_softap_set_config(struct softap_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_set_config_current(struct softap_config *config)
|
||||
bool wifi_softap_set_config_current(struct softap_config* config)
|
||||
{
|
||||
(void)config;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please)
|
||||
bool wifi_softap_set_dhcps_lease(struct dhcps_lease* please)
|
||||
{
|
||||
(void)please;
|
||||
return true;
|
||||
@ -476,7 +469,7 @@ extern "C"
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb)
|
||||
bool wifi_station_scan(struct scan_config* config, scan_done_cb_t cb)
|
||||
{
|
||||
(void)config;
|
||||
cb(nullptr, FAIL);
|
||||
@ -498,7 +491,7 @@ extern "C"
|
||||
(void)intr;
|
||||
}
|
||||
|
||||
void dns_setserver(u8_t numdns, ip_addr_t *dnsserver)
|
||||
void dns_setserver(u8_t numdns, ip_addr_t* dnsserver)
|
||||
{
|
||||
(void)numdns;
|
||||
(void)dnsserver;
|
||||
@ -511,11 +504,10 @@ extern "C"
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
#include <smartconfig.h>
|
||||
bool smartconfig_start(sc_callback_t cb, ...)
|
||||
{
|
||||
//XXXFIXME ... -> ptr
|
||||
// XXXFIXME ... -> ptr
|
||||
cb(SC_STATUS_LINK, NULL);
|
||||
return true;
|
||||
}
|
||||
@ -530,4 +522,4 @@ extern "C"
|
||||
return NONE_SLEEP_T;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
|
Reference in New Issue
Block a user