deserialize dc11-configuration

This commit is contained in:
folkert van heusden 2024-05-20 20:14:39 +02:00
parent 6f20af4b2c
commit a9d0f89c00
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
8 changed files with 69 additions and 40 deletions

View file

@ -71,7 +71,7 @@ comm *comm::deserialize(const JsonVariantConst j, bus *const b)
if (!d->begin()) { if (!d->begin()) {
delete d; delete d;
DOLOG(warning, false, "comm::deserialize: begin() failed"); DOLOG(warning, false, "comm::deserialize: begin() \"%s\" failed", type.c_str());
return nullptr; return nullptr;
} }

View file

@ -201,7 +201,6 @@ JsonDocument comm_tcp_socket_client::serialize() const
comm_tcp_socket_client *comm_tcp_socket_client::deserialize(const JsonVariantConst j) comm_tcp_socket_client *comm_tcp_socket_client::deserialize(const JsonVariantConst j)
{ {
comm_tcp_socket_client *r = new comm_tcp_socket_client(j["host"].as<std::string>(), j["port"].as<int>()); comm_tcp_socket_client *r = new comm_tcp_socket_client(j["host"].as<std::string>(), j["port"].as<int>());
r->begin(); // TODO error-checking
return r; return r;
} }

View file

@ -80,6 +80,13 @@ comm_tcp_socket_server::~comm_tcp_socket_server()
th->join(); th->join();
delete th; delete th;
} }
if (fd != INVALID_SOCKET)
close(fd);
if (cfd != INVALID_SOCKET)
close(cfd);
DOLOG(debug, false, "comm_tcp_socket_server: destructor for port %d finished", port);
} }
bool comm_tcp_socket_server::begin() bool comm_tcp_socket_server::begin()
@ -159,7 +166,7 @@ void comm_tcp_socket_server::operator()()
fd = socket(AF_INET, SOCK_STREAM, 0); fd = socket(AF_INET, SOCK_STREAM, 0);
int reuse_addr = 1; int reuse_addr = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr)) == -1) { if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&reuse_addr), sizeof(reuse_addr)) == -1) {
close(fd); close(fd);
fd = INVALID_SOCKET; fd = INVALID_SOCKET;
@ -176,10 +183,10 @@ void comm_tcp_socket_server::operator()()
listen_addr.sin_port = htons(port); listen_addr.sin_port = htons(port);
if (bind(fd, reinterpret_cast<struct sockaddr *>(&listen_addr), sizeof(listen_addr)) == -1) { if (bind(fd, reinterpret_cast<struct sockaddr *>(&listen_addr), sizeof(listen_addr)) == -1) {
DOLOG(warning, true, "Cannot bind to port %d (send_datacomm_tcp_socket_server): %s", port, strerror(errno));
close(fd); close(fd);
fd = INVALID_SOCKET; fd = INVALID_SOCKET;
DOLOG(warning, true, "Cannot bind to port %d (send_datacomm_tcp_socket_server)", port);
return; return;
} }
@ -227,9 +234,6 @@ void comm_tcp_socket_server::operator()()
} }
DOLOG(info, true, "comm_tcp_socket_server thread terminating"); DOLOG(info, true, "comm_tcp_socket_server thread terminating");
close(cfd);
close(fd);
} }
JsonDocument comm_tcp_socket_server::serialize() const JsonDocument comm_tcp_socket_server::serialize() const
@ -246,7 +250,6 @@ JsonDocument comm_tcp_socket_server::serialize() const
comm_tcp_socket_server *comm_tcp_socket_server::deserialize(const JsonVariantConst j) comm_tcp_socket_server *comm_tcp_socket_server::deserialize(const JsonVariantConst j)
{ {
comm_tcp_socket_server *r = new comm_tcp_socket_server(j["port"].as<int>()); comm_tcp_socket_server *r = new comm_tcp_socket_server(j["port"].as<int>());
r->begin(); // TODO error-checking
return r; return r;
} }

View file

@ -47,6 +47,11 @@ dc11::~dc11()
th->join(); th->join();
delete th; delete th;
} }
for(auto & c : comm_interfaces) {
DOLOG(debug, false, "Stopping %s", c->get_identifier().c_str());
delete c;
}
} }
void dc11::show_state(console *const cnsl) const void dc11::show_state(console *const cnsl) const

View file

@ -56,7 +56,7 @@ void start_network(console *const cnsl);
extern SdFs SD; extern SdFs SD;
#endif #endif
#define SERIAL_CFG_FILE "/dc11.json" #define SERIAL_CFG_FILE "dc11.json"
#if !defined(BUILD_FOR_RP2040) #if !defined(BUILD_FOR_RP2040)
std::optional<disk_backend *> select_nbd_server(console *const cnsl) std::optional<disk_backend *> select_nbd_server(console *const cnsl)
@ -657,7 +657,7 @@ void tm11_unload_tape(bus *const b)
b->getTM11()->unload(); b->getTM11()->unload();
} }
void serdc11(console *const cnsl, bus *const b, const std::string & filename) void serdc11(console *const cnsl, bus *const b)
{ {
dc11 *d = b->getDC11(); dc11 *d = b->getDC11();
if (!d) { if (!d) {
@ -670,7 +670,7 @@ void serdc11(console *const cnsl, bus *const b, const std::string & filename)
bool ok = false; bool ok = false;
#if IS_POSIX #if IS_POSIX
FILE *fh = fopen(filename.c_str(), "w"); FILE *fh = fopen(SERIAL_CFG_FILE, "w");
if (fh) { if (fh) {
state_writer ws { fh }; state_writer ws { fh };
serializeJsonPretty(j, ws); serializeJsonPretty(j, ws);
@ -679,16 +679,31 @@ void serdc11(console *const cnsl, bus *const b, const std::string & filename)
ok = true; ok = true;
} }
#elif defined(ESP32) #elif defined(ESP32)
File dataFile = LittleFS.open(SERIAL_CFG_FILE, "w"); File data_file = LittleFS.open("/" SERIAL_CFG_FILE, "w");
if (dataFile) { if (data_file) {
serializeJsonPretty(j, dataFile); serializeJsonPretty(j, data_file);
dataFile.close(); data_file.close();
ok = true; ok = true;
} }
#endif #endif
cnsl->put_string_lf(format("Serialize to %s: %s", filename.c_str(), ok ? "OK" : "failed")); cnsl->put_string_lf(format("Serialize to " SERIAL_CFG_FILE ": %s", ok ? "OK" : "failed"));
}
void deserdc11(console *const cnsl, bus *const b)
{
auto rc = deserialize_file(SERIAL_CFG_FILE);
if (rc.has_value() == false) {
cnsl->put_string_lf("Failed to deserialize " SERIAL_CFG_FILE);
return;
}
b->del_DC11();
b->add_DC11(dc11::deserialize(rc.value(), b));
cnsl->put_string_lf(format("Deserialized " SERIAL_CFG_FILE));
} }
void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event) void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event)
@ -1107,13 +1122,13 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
continue; continue;
} }
else if (parts[0] == "serdc11" && parts.size() == 2) { else if (cmd == "serdc11") {
serdc11(cnsl, b, parts[1]); serdc11(cnsl, b);
continue; continue;
} }
else if (parts[0] == "dserdc11" && parts.size() == 2) { else if (cmd == "dserdc11") {
// TODO deserdc11(cnsl, b);
continue; continue;
} }
@ -1173,8 +1188,8 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto
"ramsize x - set ram size (page count (8 kB), decimal)", "ramsize x - set ram size (page count (8 kB), decimal)",
"bl - set bootloader (rl02 or rk05)", "bl - set bootloader (rl02 or rk05)",
"cdc11 - configure DC11 device", "cdc11 - configure DC11 device",
"serdc11 x - store DC11 device settings", "serdc11 - store DC11 device settings",
"dserdc11 x - load DC11 device settings", "dserdc11 - load DC11 device settings",
#if IS_POSIX #if IS_POSIX
"ser x - serialize state to a file", "ser x - serialize state to a file",
// "dser - deserialize state from a file", // "dser - deserialize state from a file",

View file

@ -1,6 +1,7 @@
// (C) 2018-2024 by Folkert van Heusden // (C) 2018-2024 by Folkert van Heusden
// Released under MIT license // Released under MIT license
#include "gen.h"
#include <fcntl.h> #include <fcntl.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -11,6 +12,9 @@
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <winsock2.h> #include <winsock2.h>
#else #else
#if defined(ESP32)
#include <Arduino.h>
#endif
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/socket.h> #include <sys/socket.h>

View file

@ -693,13 +693,8 @@ int main(int argc, char *argv[])
cnsl->stop_thread(); cnsl->stop_thread();
auto dc11_devices = *b->getDC11()->get_comm_interfaces(); // TODO fix RAII
delete b; delete b;
for(auto & c: dc11_devices)
delete c;
delete cnsl; delete cnsl;
return 0; return 0;

View file

@ -5,6 +5,7 @@
#if defined(ESP32) || defined(BUILD_FOR_RP2040) #if defined(ESP32) || defined(BUILD_FOR_RP2040)
#include <Arduino.h> #include <Arduino.h>
#include <LittleFS.h>
#include "rp2040.h" #include "rp2040.h"
#include <sys/socket.h> #include <sys/socket.h>
#elif defined(_WIN32) #elif defined(_WIN32)
@ -34,8 +35,6 @@
#include "win32.h" #include "win32.h"
#endif #endif
#include "log.h"
void setBit(uint16_t & v, const int bit, const bool vb) void setBit(uint16_t & v, const int bit, const bool vb)
{ {
@ -250,15 +249,18 @@ void update_word(uint16_t *const w, const bool msb, const uint8_t v)
} }
} }
void set_nodelay(const int fd) bool set_nodelay(const int fd)
{ {
int flags = 1; int flags = 1;
#if defined(__FreeBSD__) || defined(ESP32) || defined(_WIN32) #if defined(__FreeBSD__) || defined(ESP32) || defined(_WIN32)
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&flags), sizeof(flags)) == -1) if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&flags), sizeof(flags)) == -1)
return false;
#else #else
if (setsockopt(fd, SOL_TCP, TCP_NODELAY, reinterpret_cast<void *>(&flags), sizeof(flags)) == -1) if (setsockopt(fd, SOL_TCP, TCP_NODELAY, reinterpret_cast<void *>(&flags), sizeof(flags)) == -1)
return false;
#endif #endif
DOLOG(warning, true, "Cannot disable nagle algorithm");
return true;
} }
std::string get_endpoint_name(const int fd) std::string get_endpoint_name(const int fd)
@ -274,11 +276,19 @@ std::string get_endpoint_name(const int fd)
std::optional<JsonDocument> deserialize_file(const std::string & filename) std::optional<JsonDocument> deserialize_file(const std::string & filename)
{ {
FILE *fh = fopen(filename.c_str(), "r"); JsonDocument j;
if (!fh) {
DOLOG(warning, false, "Failed to open %s", filename.c_str()); #if defined(ESP32)
File data_file = LittleFS.open(filename.c_str(), "r");
if (!data_file)
return { };
deserializeJson(j, data_file);
data_file.close();
#else
FILE *fh = fopen(filename.c_str(), "r");
if (!fh)
return { }; return { };
}
std::string j_in; std::string j_in;
char buffer[4096]; char buffer[4096];
@ -292,12 +302,10 @@ std::optional<JsonDocument> deserialize_file(const std::string & filename)
fclose(fh); fclose(fh);
JsonDocument j;
DeserializationError error = deserializeJson(j, j_in); DeserializationError error = deserializeJson(j, j_in);
if (error) { if (error)
DOLOG(warning, false, "Failed to de-serialize %s", filename.c_str());
return { }; return { };
} #endif
return j; return j;
} }