diff --git a/comm.cpp b/comm.cpp index dc1f536..10f8752 100644 --- a/comm.cpp +++ b/comm.cpp @@ -71,7 +71,7 @@ comm *comm::deserialize(const JsonVariantConst j, bus *const b) if (!d->begin()) { delete d; - DOLOG(warning, false, "comm::deserialize: begin() failed"); + DOLOG(warning, false, "comm::deserialize: begin() \"%s\" failed", type.c_str()); return nullptr; } diff --git a/comm_tcp_socket_client.cpp b/comm_tcp_socket_client.cpp index c157152..0f06cfb 100644 --- a/comm_tcp_socket_client.cpp +++ b/comm_tcp_socket_client.cpp @@ -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 *r = new comm_tcp_socket_client(j["host"].as(), j["port"].as()); - r->begin(); // TODO error-checking return r; } diff --git a/comm_tcp_socket_server.cpp b/comm_tcp_socket_server.cpp index 3296cba..57e2e73 100644 --- a/comm_tcp_socket_server.cpp +++ b/comm_tcp_socket_server.cpp @@ -80,6 +80,13 @@ comm_tcp_socket_server::~comm_tcp_socket_server() th->join(); 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() @@ -159,7 +166,7 @@ void comm_tcp_socket_server::operator()() fd = socket(AF_INET, SOCK_STREAM, 0); 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(&reuse_addr), sizeof(reuse_addr)) == -1) { close(fd); fd = INVALID_SOCKET; @@ -176,10 +183,10 @@ void comm_tcp_socket_server::operator()() listen_addr.sin_port = htons(port); if (bind(fd, reinterpret_cast(&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); fd = INVALID_SOCKET; - - DOLOG(warning, true, "Cannot bind to port %d (send_datacomm_tcp_socket_server)", port); return; } @@ -227,9 +234,6 @@ void comm_tcp_socket_server::operator()() } DOLOG(info, true, "comm_tcp_socket_server thread terminating"); - - close(cfd); - close(fd); } 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 *r = new comm_tcp_socket_server(j["port"].as()); - r->begin(); // TODO error-checking return r; } diff --git a/dc11.cpp b/dc11.cpp index 00d1b21..fee4423 100644 --- a/dc11.cpp +++ b/dc11.cpp @@ -47,6 +47,11 @@ dc11::~dc11() th->join(); 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 diff --git a/debugger.cpp b/debugger.cpp index aaf07fc..807aee2 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -56,7 +56,7 @@ void start_network(console *const cnsl); extern SdFs SD; #endif -#define SERIAL_CFG_FILE "/dc11.json" +#define SERIAL_CFG_FILE "dc11.json" #if !defined(BUILD_FOR_RP2040) std::optional select_nbd_server(console *const cnsl) @@ -657,7 +657,7 @@ void tm11_unload_tape(bus *const b) 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(); if (!d) { @@ -670,7 +670,7 @@ void serdc11(console *const cnsl, bus *const b, const std::string & filename) bool ok = false; #if IS_POSIX - FILE *fh = fopen(filename.c_str(), "w"); + FILE *fh = fopen(SERIAL_CFG_FILE, "w"); if (fh) { state_writer ws { fh }; serializeJsonPretty(j, ws); @@ -679,16 +679,31 @@ void serdc11(console *const cnsl, bus *const b, const std::string & filename) ok = true; } #elif defined(ESP32) - File dataFile = LittleFS.open(SERIAL_CFG_FILE, "w"); - if (dataFile) { - serializeJsonPretty(j, dataFile); - dataFile.close(); + File data_file = LittleFS.open("/" SERIAL_CFG_FILE, "w"); + if (data_file) { + serializeJsonPretty(j, data_file); + data_file.close(); ok = true; } #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) @@ -1107,13 +1122,13 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto continue; } - else if (parts[0] == "serdc11" && parts.size() == 2) { - serdc11(cnsl, b, parts[1]); + else if (cmd == "serdc11") { + serdc11(cnsl, b); continue; } - else if (parts[0] == "dserdc11" && parts.size() == 2) { - // TODO + else if (cmd == "dserdc11") { + deserdc11(cnsl, b); 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)", "bl - set bootloader (rl02 or rk05)", "cdc11 - configure DC11 device", - "serdc11 x - store DC11 device settings", - "dserdc11 x - load DC11 device settings", + "serdc11 - store DC11 device settings", + "dserdc11 - load DC11 device settings", #if IS_POSIX "ser x - serialize state to a file", // "dser - deserialize state from a file", diff --git a/log.cpp b/log.cpp index 8a85fbe..49200c8 100644 --- a/log.cpp +++ b/log.cpp @@ -1,6 +1,7 @@ // (C) 2018-2024 by Folkert van Heusden // Released under MIT license +#include "gen.h" #include #include #include @@ -11,6 +12,9 @@ #include #include #else +#if defined(ESP32) +#include +#endif #include #include #include diff --git a/main.cpp b/main.cpp index 1cd636c..e708dcc 100644 --- a/main.cpp +++ b/main.cpp @@ -693,13 +693,8 @@ int main(int argc, char *argv[]) cnsl->stop_thread(); - auto dc11_devices = *b->getDC11()->get_comm_interfaces(); // TODO fix RAII - delete b; - for(auto & c: dc11_devices) - delete c; - delete cnsl; return 0; diff --git a/utils.cpp b/utils.cpp index 11f7b0e..abcc548 100644 --- a/utils.cpp +++ b/utils.cpp @@ -5,6 +5,7 @@ #if defined(ESP32) || defined(BUILD_FOR_RP2040) #include +#include #include "rp2040.h" #include #elif defined(_WIN32) @@ -34,8 +35,6 @@ #include "win32.h" #endif -#include "log.h" - 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; #if defined(__FreeBSD__) || defined(ESP32) || defined(_WIN32) if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flags), sizeof(flags)) == -1) + return false; #else if (setsockopt(fd, SOL_TCP, TCP_NODELAY, reinterpret_cast(&flags), sizeof(flags)) == -1) + return false; #endif - DOLOG(warning, true, "Cannot disable nagle algorithm"); + + return true; } std::string get_endpoint_name(const int fd) @@ -274,11 +276,19 @@ std::string get_endpoint_name(const int fd) std::optional deserialize_file(const std::string & filename) { - FILE *fh = fopen(filename.c_str(), "r"); - if (!fh) { - DOLOG(warning, false, "Failed to open %s", filename.c_str()); + JsonDocument j; + +#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 { }; - } std::string j_in; char buffer[4096]; @@ -292,12 +302,10 @@ std::optional deserialize_file(const std::string & filename) fclose(fh); - JsonDocument j; DeserializationError error = deserializeJson(j, j_in); - if (error) { - DOLOG(warning, false, "Failed to de-serialize %s", filename.c_str()); + if (error) return { }; - } +#endif return j; }