Skip to content

Commit

Permalink
Attempted another refactoring. Base Port class is now subclassed into…
Browse files Browse the repository at this point in the history
… seperate Server and Client Port classes. Inbound and Outbound fifos are now not handled seperately, instead each Port has both an in and out fifo. This moves a little bit more complexity out of the main Server and Client classes and moves it into the Port classes.
  • Loading branch information
Sebastien Sikora committed Dec 3, 2021
1 parent 7d57bbe commit a37ace9
Show file tree
Hide file tree
Showing 11 changed files with 470 additions and 375 deletions.
4 changes: 2 additions & 2 deletions demos/client_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ int main(int argc, char *argv[]) {
}
usleep(1000);
}
std::cerr << "On termination error code = " << stc.GetErrorCode().err_no << " Error detail = " << stc.GetErrorCode().detail << std::endl;
std::cerr << "On termination error code = " << stc.GetErrorCode().err_no << " Error detail = " << stc.GetErrorCode().err_detail << std::endl;
sleep(5); // Delay to read the message before terminal emulator window closes.
} else {
std::cerr << "On termination error code = " << stc.GetErrorCode().err_no << " Error detail = " << stc.GetErrorCode().detail << std::endl;
std::cerr << "On termination error code = " << stc.GetErrorCode().err_no << " Error detail = " << stc.GetErrorCode().err_detail << std::endl;
sleep(5); // Delay to read the message before terminal emulator window closes.
}
return 0;
Expand Down
6 changes: 3 additions & 3 deletions demos/server_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

int main (void) {

SatTerm_Server sts("test_server", "./client_demo");
SatTerm_Server sts("test_server", "./client_demo", true, {"com_1", "com_2"});

if (sts.IsConnected()) {
size_t message_count = 10;
Expand All @@ -27,11 +27,11 @@ int main (void) {
usleep(1000);
}

std::cerr << "On termination error code = " << sts.GetErrorCode().err_no << " Error detail = " << sts.GetErrorCode().detail << std::endl;
std::cerr << "On termination error code = " << sts.GetErrorCode().err_no << " Error detail = " << sts.GetErrorCode().err_detail << std::endl;

} else {

std::cerr << "On termination error code = " << sts.GetErrorCode().err_no << " Error detail = " << sts.GetErrorCode().detail << std::endl;
std::cerr << "On termination error code = " << sts.GetErrorCode().err_no << " Error detail = " << sts.GetErrorCode().err_detail << std::endl;

}
return 0;
Expand Down
27 changes: 13 additions & 14 deletions src/satellite_terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

#include <string> // std::string.
#include <vector> // std::vector.
#include <map>
#include <memory>
#include <map> // std::map.
#include <memory> // std::unique_ptr.

#include "satterm_port.h"

Expand All @@ -36,15 +36,12 @@ class SatTerm_Agent {
void SetConnectedFlag(bool is_connected);

protected:
bool CreatePorts(bool is_server, bool is_in_port, std::string const& working_path, std::vector<std::string> port_identifiers,
bool display_messages, char end_char, std::map<std::string, std::unique_ptr<Port>>& ports);
bool OpenPorts(std::map<std::string, std::unique_ptr<Port>>& ports, unsigned long timeout_seconds = 5);

error_descriptor m_error_code = {0, ""};
bool m_display_messages = false;
std::map<std::string, std::unique_ptr<Port>> m_in_ports = {};
std::map<std::string, std::unique_ptr<Port>> m_out_ports = {};
default_port m_default_port = {"", ""};
std::map<std::string, std::unique_ptr<Port>> m_ports = {};
std::string m_default_port_identifier = "";
std::string m_stop_port_identifier = "";
std::string m_working_path = "";
std::string m_identifier = "";
Expand All @@ -56,26 +53,28 @@ class SatTerm_Agent {
class SatTerm_Server : public SatTerm_Agent {
public:
SatTerm_Server(std::string const& identifier, std::string const& path_to_client_binary, bool display_messages = true,
std::vector<std::string> port_identifiers = {"comms"}, std::string const& stop_message = "q",
std::string const& path_to_terminal_emulator_paths = "./terminal_emulator_paths.txt",
std::vector<std::string> out_port_identifiers = {"server_out"}, std::vector<std::string> in_port_identifiers = {"server_in"},
char end_char = 3, std::string const& stop_port_identifier = "", std::string const& stop_message = "q");
char end_char = 3, std::string const& stop_port_identifier = "", unsigned long timeout_seconds = 5);
~SatTerm_Server();

private:
std::string GetWorkingPath(void);
bool CreateServerPorts(std::string const& working_path, std::vector<std::string> port_identifiers,
bool display_messages, char end_char, std::map<std::string, std::unique_ptr<Port>>& ports);
std::vector<std::string> LoadTerminalEmulatorPaths(std::string const& file_path);
pid_t StartClient(std::string const& path_to_terminal_emulator_paths, std::string const& path_to_client_binary, std::string const& working_path,
char end_char, std::string const& stop_message, std::vector<std::string> in_port_identifiers,
std::vector<std::string> out_port_identifiers);

char end_char, std::string const& stop_message, std::vector<std::string> port_identifiers);
};

class SatTerm_Client : public SatTerm_Agent {
public:
SatTerm_Client(std::string const& identifier, int argc, char* argv[], bool display_messages = true);
~SatTerm_Client();

private:
size_t GetArgStartIndex(std::string const& arg_start_delimiter, int argc, char* argv[]);
std::vector<std::string> ParseFifoPaths(size_t argv_start_index, size_t argv_count, char* argv[]);
void CreateClientPorts(std::string const& working_path, std::vector<std::string> port_identifiers,
bool display_messages, char end_char, std::map<std::string, std::unique_ptr<Port>>& ports);
};
67 changes: 25 additions & 42 deletions src/satterm_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,20 @@
// For a copy, see <https://opensource.org/licenses/MIT>.
// -----------------------------------------------------------------------------------------------------

#include <iostream>
#include <iostream> // std::cout, std::cerr, std::endl.
#include <fstream> // std::ifstream.
#include <stdexcept>
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <stdexcept> // std::out_of_range.
#include <string> // std::string, std::to_string.
#include <map> // std::map.
#include <vector> // std::vector.
#include <memory> // std::unique_ptr.

#include "satellite_terminal.h"

bool SatTerm_Agent::CreatePorts(bool is_server, bool is_in_port, std::string const& working_path, std::vector<std::string> port_identifiers,
bool display_messages, char end_char, std::map<std::string, std::unique_ptr<Port>>& ports) {
bool success = true;
for (auto const& port_identifier : port_identifiers) {
ports.emplace(port_identifier, std::make_unique<Port>(is_server, is_in_port, working_path, port_identifier, display_messages, end_char));
if (is_server) {
if (!(ports.at(port_identifier)->IsCreated())) {
success = false;
m_error_code = ports.at(port_identifier)->GetErrorCode();
break;
}
}
}
return success;
}

bool SatTerm_Agent::OpenPorts(std::map<std::string, std::unique_ptr<Port>>& ports, unsigned long timeout_seconds) {
bool success = true;
for (auto const& current_port : ports) {
current_port.second->Open(timeout_seconds);
if (!(current_port.second->IsOpened())) {
if (!(current_port.second->Open(timeout_seconds))) {
success = false;
m_error_code = current_port.second->GetErrorCode();
break;
Expand All @@ -50,72 +33,72 @@ bool SatTerm_Agent::OpenPorts(std::map<std::string, std::unique_ptr<Port>>& port
}

std::string SatTerm_Agent::GetMessage(bool capture_end_char, unsigned long timeout_seconds) {
return GetMessage(m_default_port.in, capture_end_char, timeout_seconds);
return GetMessage(m_default_port_identifier, capture_end_char, timeout_seconds);
}

std::string SatTerm_Agent::GetMessage(std::string const& in_port_identifier, bool capture_end_char, unsigned long timeout_seconds) {
std::string SatTerm_Agent::GetMessage(std::string const& port_identifier, bool capture_end_char, unsigned long timeout_seconds) {
m_error_code = {0, ""};

std::string received_message = "";
try {
received_message = m_in_ports.at(in_port_identifier)->GetMessage(capture_end_char, timeout_seconds);
m_error_code = m_in_ports.at(in_port_identifier)->GetErrorCode();
received_message = m_ports.at(port_identifier)->GetMessage(capture_end_char, timeout_seconds);
m_error_code = m_ports.at(port_identifier)->GetErrorCode();
if (m_error_code.err_no != 0) {
SetConnectedFlag(m_in_ports.at(in_port_identifier)->IsOpened());
SetConnectedFlag(m_ports.at(port_identifier)->IsOpened());
}
}

catch (const std::out_of_range& oor) {
m_error_code = {-1, "GetMessage()_OOR_port_id"};
std::string error_message = "GetMessage() error - No port matches identifier " + in_port_identifier;
std::string error_message = "GetMessage() error - No port matches identifier " + port_identifier;
std::cerr << error_message << std::endl;
}
return received_message;
}

std::string SatTerm_Agent::SendMessage(std::string const& message, unsigned long timeout_seconds) {
return SendMessage(message, m_default_port.out, timeout_seconds);
return SendMessage(message, m_default_port_identifier, timeout_seconds);
}

std::string SatTerm_Agent::SendMessage(std::string const& message, std::string const& out_port_identifier, unsigned long timeout_seconds) {
std::string SatTerm_Agent::SendMessage(std::string const& message, std::string const& port_identifier, unsigned long timeout_seconds) {
m_error_code = {0, ""};

std::string remaining_message = "";
try {
remaining_message = m_out_ports.at(out_port_identifier)->SendMessage(message, timeout_seconds);
m_error_code = m_out_ports.at(out_port_identifier)->GetErrorCode();
remaining_message = m_ports.at(port_identifier)->SendMessage(message, timeout_seconds);
m_error_code = m_ports.at(port_identifier)->GetErrorCode();
if (m_error_code.err_no != 0) {
SetConnectedFlag(m_out_ports.at(out_port_identifier)->IsOpened());
SetConnectedFlag(m_ports.at(port_identifier)->IsOpened());
}
}

catch (const std::out_of_range& oor) {
m_error_code = {-1, "SendMessage()_OOR_port_id"};
std::string error_message = "SendMessage() error - No port matches identifier " + out_port_identifier;
std::string error_message = "SendMessage() error - No port matches identifier " + port_identifier;
std::cerr << error_message << std::endl;
}
return remaining_message;
}

size_t SatTerm_Agent::SendBytes(const char* bytes, size_t byte_count, unsigned long timeout_seconds) {
return SendBytes(bytes, byte_count, m_default_port.out, timeout_seconds);
return SendBytes(bytes, byte_count, m_default_port_identifier, timeout_seconds);
}

size_t SatTerm_Agent::SendBytes(const char* bytes, size_t byte_count, std::string const& out_port_identifier, unsigned long timeout_seconds) {
size_t SatTerm_Agent::SendBytes(const char* bytes, size_t byte_count, std::string const& port_identifier, unsigned long timeout_seconds) {
m_error_code = {0, ""};

size_t sent_bytes = 0;
try {
sent_bytes = m_out_ports.at(out_port_identifier)->SendBytes(bytes, byte_count, timeout_seconds);
m_error_code = m_out_ports.at(out_port_identifier)->GetErrorCode();
sent_bytes = m_ports.at(port_identifier)->SendBytes(bytes, byte_count, timeout_seconds);
m_error_code = m_ports.at(port_identifier)->GetErrorCode();
if (m_error_code.err_no != 0) {
SetConnectedFlag(m_out_ports.at(out_port_identifier)->IsOpened());
SetConnectedFlag(m_ports.at(port_identifier)->IsOpened());
}
}

catch (const std::out_of_range& oor) {
m_error_code = {-1, "SendBytes()_OOR_port_id"};
std::string error_message = "SendBytes() error - No port matches identifier " + out_port_identifier;
std::string error_message = "SendBytes() error - No port matches identifier " + port_identifier;
std::cerr << error_message << std::endl;
}
return sent_bytes;
Expand Down
52 changes: 23 additions & 29 deletions src/satterm_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,54 +10,44 @@
// For a copy, see <https://opensource.org/licenses/MIT>.
// -----------------------------------------------------------------------------------------------------

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <iostream> // std::cout, std::cerr, std::endl.
#include <string> // std::string, std::stoi.
#include <map> // std::map.
#include <vector> // std::vector.

#include "satellite_terminal.h"

SatTerm_Client::SatTerm_Client(std::string const& identifier, int argc, char* argv[], bool display_messages) {
m_identifier = identifier;
m_display_messages = display_messages;

size_t in_port_count = 0;
size_t out_port_count = 0;
std::vector<std::string> out_port_identifiers = {};
std::vector<std::string> in_port_identifiers = {};
size_t port_count = 0;
std::vector<std::string> port_identifiers = {};

size_t argv_start_index = GetArgStartIndex("client_args", argc, argv);

bool success = false;
if (argv_start_index != 0) {
success = true;
m_working_path = std::string(argv[argv_start_index]);
m_end_char = (char)(std::stoi(std::string(argv[argv_start_index + 1])));
m_stop_message = std::string(argv[argv_start_index + 2]);
out_port_count = std::stoi(std::string(argv[argv_start_index + 3]));
in_port_count = std::stoi(std::string(argv[argv_start_index + 4]));
out_port_identifiers = ParseFifoPaths(argv_start_index + 5, out_port_count, argv);
in_port_identifiers = ParseFifoPaths(argv_start_index + 5 + out_port_count, in_port_count, argv);
port_count = std::stoi(std::string(argv[argv_start_index + 3]));
port_identifiers = ParseFifoPaths(argv_start_index + 4, port_count, argv);

m_default_port.out = out_port_identifiers[0];
m_default_port.in = in_port_identifiers[0];
m_default_port_identifier = port_identifiers[0];

if (m_display_messages) {
std::string message = "Client working path is " + m_working_path;
std::cerr << message << std::endl;
}

success = CreatePorts(false, false, m_working_path, out_port_identifiers, m_display_messages, m_end_char, m_out_ports);
if (success) {
success = CreatePorts(false, true, m_working_path, in_port_identifiers, m_display_messages, m_end_char, m_in_ports);
}
CreateClientPorts(m_working_path, port_identifiers, m_display_messages, m_end_char, m_ports);

unsigned long timeout_seconds = 5;
if (success) {
success = OpenPorts(m_out_ports, timeout_seconds);
}

if (success) {
success = OpenPorts(m_in_ports, timeout_seconds);
success = OpenPorts(m_ports, timeout_seconds);
}

if (success) {
Expand All @@ -84,15 +74,12 @@ SatTerm_Client::SatTerm_Client(std::string const& identifier, int argc, char* ar
SatTerm_Client::~SatTerm_Client() {
// If shutdown is occurring, the server will poll m_default_port.in until it gets EOF, then everything will be closed and unlinked at the
// server end. To make sure that unlink() deletes the files, we close any that are open here, saving m_default_port.out at this end for last.
for (const auto& port : m_in_ports) {
port.second->Close();
}
for (const auto& port : m_out_ports) {
if (port.first != m_default_port.out) {
for (const auto& port : m_ports) {
if (port.first != m_default_port_identifier) {
port.second->Close();
}
}
m_out_ports.at(m_default_port.out)->Close();
m_ports.at(m_default_port_identifier)->Close();
// There should not be any more to do. Pointers in m_in_ports and m_out_ports are stored as unique_ptr<Port>, so when the maps
// are destroyed now the destructors for the Ports should be called automatically. In these the fifos will be unlink()ed if m_is_server is set.
}
Expand Down Expand Up @@ -122,3 +109,10 @@ std::vector<std::string> SatTerm_Client::ParseFifoPaths(size_t argv_start_index,
}
return paths_container;
}

void SatTerm_Client::CreateClientPorts(std::string const& working_path, std::vector<std::string> port_identifiers,
bool display_messages, char end_char, std::map<std::string, std::unique_ptr<Port>>& ports) {
for (auto const& port_identifier : port_identifiers) {
ports.emplace(port_identifier, std::make_unique<Port_Client>(working_path, port_identifier, display_messages, end_char));
}
}
Loading

0 comments on commit a37ace9

Please sign in to comment.