-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from janekbaraniewski/basic-functionality-testing
Basic functionality testing
- Loading branch information
Showing
11 changed files
with
510 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#ifndef SOCKETCLIENT_H | ||
#define SOCKETCLIENT_H | ||
|
||
#include <iostream> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
#include <arpa/inet.h> | ||
|
||
class SocketClient { | ||
struct sockaddr_in server_addr; | ||
|
||
public: | ||
int sock_fd; | ||
SocketClient() : sock_fd(-1) { | ||
memset(&server_addr, 0, sizeof(server_addr)); | ||
} | ||
|
||
~SocketClient() { | ||
close(sock_fd); | ||
} | ||
|
||
bool connectToServer(const char* server_ip, int server_port) { | ||
sock_fd = socket(AF_INET, SOCK_STREAM, 0); | ||
if (sock_fd == -1) { | ||
std::cerr << "Error creating socket: " << strerror(errno) << std::endl; | ||
return false; | ||
} | ||
|
||
server_addr.sin_family = AF_INET; | ||
server_addr.sin_port = htons(server_port); | ||
if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) { | ||
std::cerr << "Invalid address/ Address not supported" << std::endl; | ||
return false; | ||
} | ||
|
||
if (::connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { | ||
std::cerr << "Connection Failed: " << strerror(errno) << std::endl; | ||
return false; | ||
} | ||
|
||
std::cout << "Connected to server at " << server_ip << ":" << server_port << std::endl; | ||
return true; | ||
} | ||
|
||
ssize_t sendToServer(const char* buffer, size_t bufferSize) { | ||
return send(sock_fd, buffer, bufferSize, 0); | ||
} | ||
|
||
ssize_t receiveFromServer(char* buffer, size_t bufferSize) { | ||
return recv(sock_fd, buffer, bufferSize, 0); | ||
} | ||
}; | ||
|
||
#endif // CLIENT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,100 @@ | ||
#include "VirtualSerialPort.h" | ||
|
||
VirtualSerialPort::VirtualSerialPort(boost::asio::io_context& io_context, const std::string& device) | ||
: master_fd_(io_context), device_name_("/dev/" + device) { | ||
int master_fd = posix_openpt(O_RDWR | O_NOCTTY); | ||
if (master_fd == -1 || grantpt(master_fd) != 0 || unlockpt(master_fd) != 0) { | ||
: master_fd_(io_context), slave_fd_(io_context), device_name_("/dev/" + device) { | ||
std::lock_guard<std::mutex> lock(mutex_); | ||
int master_fd, slave_fd; | ||
char* slave_name; | ||
master_fd = posix_openpt(O_RDWR | O_NOCTTY); | ||
if (master_fd == -1) { | ||
BOOST_LOG_TRIVIAL(error) << "Failed to open PTY master: " << strerror(errno); | ||
throw std::runtime_error("Failed to open PTY master"); | ||
} | ||
BOOST_LOG_TRIVIAL(info) << "PTY master opened successfully"; | ||
|
||
char* slave_name = ptsname(master_fd); | ||
if (!slave_name) { | ||
throw std::runtime_error("Failed to get PTY slave name"); | ||
if (grantpt(master_fd) == -1 || unlockpt(master_fd) == -1 || (slave_name = ptsname(master_fd)) == nullptr) { | ||
BOOST_LOG_TRIVIAL(error) << "Failed to grant or unlock PTY: " << strerror(errno); | ||
throw std::runtime_error("Failed to grant or unlock PTY"); | ||
} | ||
BOOST_LOG_TRIVIAL(info) << "PTY grant and unlock successful"; | ||
BOOST_LOG_TRIVIAL(info) << "Slave PTY name: " << slave_name << std::endl; | ||
|
||
if (unlink(device_name_.c_str()) == -1 && errno != ENOENT) { | ||
throw std::runtime_error("Failed to remove existing symlink"); | ||
// Attempt to create a symbolic link from slave_name to "/dev/ttyUSB0" | ||
if (symlink(slave_name, device_name_.c_str()) == -1) { | ||
BOOST_LOG_TRIVIAL(error) << "Failed to create symlink for PTY slave: " << strerror(errno); | ||
throw std::runtime_error("Failed to create symlink for PTY slave"); | ||
} | ||
BOOST_LOG_TRIVIAL(info) << "Symlink for PTY slave created successfully"; | ||
|
||
if (symlink(slave_name, device_name_.c_str()) != 0) { | ||
throw std::runtime_error("Failed to create symlink for PTY slave"); | ||
// Open the slave pseudoterminal | ||
slave_fd = open(slave_name, O_RDWR); | ||
if (slave_fd == -1) { | ||
BOOST_LOG_TRIVIAL(error) << "Failed to create symlink for PTY slave: " << strerror(errno); | ||
throw std::runtime_error("Failed to open the slave pseudoterminal"); | ||
} | ||
|
||
|
||
|
||
chmod(device_name_.c_str(), 0660); | ||
struct group* tty_grp = getgrnam("tty"); | ||
if (tty_grp) { | ||
chown(device_name_.c_str(), -1, tty_grp->gr_gid); | ||
if (tty_grp && chown(device_name_.c_str(), -1, tty_grp->gr_gid) == -1) { | ||
BOOST_LOG_TRIVIAL(error) << "Failed to change group of device: " << strerror(errno); | ||
throw std::runtime_error("Failed to change group of device"); | ||
} | ||
BOOST_LOG_TRIVIAL(info) << "Group changed successfully for the device"; | ||
|
||
master_fd_.assign(master_fd); | ||
slave_fd_.assign(slave_fd); | ||
setup_pty(master_fd); | ||
} | ||
|
||
|
||
VirtualSerialPort::~VirtualSerialPort() { | ||
close(); | ||
setup_pty(slave_fd); | ||
} | ||
|
||
void VirtualSerialPort::setup_pty(int fd) { | ||
struct termios tty; | ||
memset(&tty, 0, sizeof tty); | ||
if (tcgetattr(fd, &tty) != 0) { | ||
BOOST_LOG_TRIVIAL(error) << "Error from tcgetattr: " << strerror(errno); | ||
return; | ||
} | ||
|
||
cfmakeraw(&tty); // Configure the terminal attributes to raw mode | ||
cfmakeraw(&tty); | ||
|
||
tty.c_cflag |= (CLOCAL | CREAD); // Ignore modem controls and enable receiver | ||
tty.c_cflag |= (CLOCAL | CREAD); | ||
tty.c_cflag &= ~CSIZE; | ||
tty.c_cflag |= CS8; // 8-bit characters | ||
tty.c_cflag &= ~PARENB; // No parity bit | ||
tty.c_cflag &= ~CSTOPB; // Only need 1 stop bit | ||
tty.c_cflag &= ~CRTSCTS; // No hardware flow control | ||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl | ||
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Disable canonical mode, echo, and signal chars | ||
tty.c_oflag &= ~OPOST; // No output processing | ||
tty.c_cflag |= CS8; | ||
tty.c_cflag &= ~PARENB; | ||
tty.c_cflag &= ~CSTOPB; | ||
tty.c_cflag &= ~CRTSCTS; | ||
|
||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); | ||
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); | ||
tty.c_oflag &= ~OPOST; | ||
|
||
if (tcsetattr(fd, TCSANOW, &tty) != 0) { | ||
BOOST_LOG_TRIVIAL(error) << "Error from tcsetattr: " << strerror(errno); | ||
} else { | ||
BOOST_LOG_TRIVIAL(info) << "PTY attributes set successfully"; | ||
} | ||
} | ||
|
||
void VirtualSerialPort::close() { | ||
master_fd_.close(); | ||
slave_fd_.close(); | ||
unlink(device_name_.c_str()); | ||
} | ||
|
||
void VirtualSerialPort::async_read(boost::asio::mutable_buffer buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) { | ||
boost::asio::async_read(master_fd_, buffer, handler); | ||
VirtualSerialPort::~VirtualSerialPort() { | ||
close(); | ||
} | ||
|
||
ssize_t VirtualSerialPort::async_read(char* buffer, unsigned int length) { | ||
BOOST_LOG_TRIVIAL(info) << "VSP::async_read"; | ||
ssize_t bytes_read = read(master_fd_.native_handle(), buffer, length); | ||
BOOST_LOG_TRIVIAL(info) << "READ FROM SERIAL!!!! -> "; | ||
return bytes_read; | ||
} | ||
|
||
void VirtualSerialPort::async_write(boost::asio::const_buffer buffer, std::function<void(const boost::system::error_code&, std::size_t)> handler) { | ||
boost::asio::async_write(master_fd_, buffer, handler); | ||
|
||
ssize_t VirtualSerialPort::async_write(const char* buffer, unsigned int length) { | ||
return write(master_fd_.native_handle(), buffer, length); | ||
} | ||
|
Oops, something went wrong.