listen thread
This commit is contained in:
parent
399ebec70f
commit
62db960efa
3 changed files with 147 additions and 35 deletions
|
@ -31,8 +31,114 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
|
||||||
comm_tcp_socket::comm_tcp_socket(const int port)
|
static bool setup_telnet_session(const int fd)
|
||||||
{
|
{
|
||||||
|
uint8_t dont_auth[] = { 0xff, 0xf4, 0x25 };
|
||||||
|
uint8_t suppress_goahead[] = { 0xff, 0xfb, 0x03 };
|
||||||
|
uint8_t dont_linemode[] = { 0xff, 0xfe, 0x22 };
|
||||||
|
uint8_t dont_new_env[] = { 0xff, 0xfe, 0x27 };
|
||||||
|
uint8_t will_echo[] = { 0xff, 0xfb, 0x01 };
|
||||||
|
uint8_t dont_echo[] = { 0xff, 0xfe, 0x01 };
|
||||||
|
uint8_t noecho[] = { 0xff, 0xfd, 0x2d };
|
||||||
|
// uint8_t charset[] = { 0xff, 0xfb, 0x01 };
|
||||||
|
|
||||||
|
if (write(fd, dont_auth, sizeof dont_auth) != sizeof dont_auth)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, suppress_goahead, sizeof suppress_goahead) != sizeof suppress_goahead)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, dont_linemode, sizeof dont_linemode) != sizeof dont_linemode)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, dont_new_env, sizeof dont_new_env) != sizeof dont_new_env)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, will_echo, sizeof will_echo) != sizeof will_echo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, dont_echo, sizeof dont_echo) != sizeof dont_echo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write(fd, noecho, sizeof noecho) != sizeof noecho)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
comm_tcp_socket::comm_tcp_socket(const int port) : port(port)
|
||||||
|
{
|
||||||
|
th = new std::thread(std::ref(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
comm_tcp_socket::~comm_tcp_socket()
|
||||||
|
{
|
||||||
|
stop_flag = true;
|
||||||
|
|
||||||
|
if (th) {
|
||||||
|
th->join();
|
||||||
|
delete th;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool comm_tcp_socket::is_connected()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||||
|
|
||||||
|
return cfd != INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool comm_tcp_socket::has_data()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WSAPOLLFD fds[] { { cfd, POLLIN, 0 } };
|
||||||
|
int rc = WSAPoll(fds, 1, 0);
|
||||||
|
#else
|
||||||
|
pollfd fds[] { { cfd, POLLIN, 0 } };
|
||||||
|
int rc = poll(fds, 1, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rc == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t comm_tcp_socket::get_byte()
|
||||||
|
{
|
||||||
|
int use_fd = -1;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||||
|
use_fd = cfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t c = 0;
|
||||||
|
read(use_fd, &c, 1); // TODO error checking
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void comm_tcp_socket::send_data(const uint8_t *const in, const size_t n)
|
||||||
|
{
|
||||||
|
const uint8_t *p = in;
|
||||||
|
size_t len = n;
|
||||||
|
|
||||||
|
while(len > 0) {
|
||||||
|
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||||
|
int rc = write(cfd, p, len);
|
||||||
|
if (rc <= 0) // TODO error checking
|
||||||
|
break;
|
||||||
|
|
||||||
|
p += rc;
|
||||||
|
len -= rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void comm_tcp_socket::operator()()
|
||||||
|
{
|
||||||
|
set_thread_name("kek:COMMTCP");
|
||||||
|
|
||||||
|
DOLOG(info, true, "TCP comm thread started for port %d", port);
|
||||||
|
|
||||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
int reuse_addr = 1;
|
int reuse_addr = 1;
|
||||||
|
@ -67,48 +173,44 @@ comm_tcp_socket::comm_tcp_socket(const int port)
|
||||||
DOLOG(warning, true, "Cannot listen on port %d (comm_tcp_socket)", port);
|
DOLOG(warning, true, "Cannot listen on port %d (comm_tcp_socket)", port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
comm_tcp_socket::~comm_tcp_socket()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool comm_tcp_socket::is_connected()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool comm_tcp_socket::has_data()
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
WSAPOLLFD fds[] { { fd, POLLIN, 0 } };
|
WSAPOLLFD fds[] { { fd, POLLIN, 0 } };
|
||||||
int rc = WSAPoll(fds, 1, 0);
|
|
||||||
#else
|
#else
|
||||||
pollfd fds[] { { fd, POLLIN, 0 } };
|
pollfd fds[] { { fd, POLLIN, 0 } };
|
||||||
int rc = poll(fds, 1, 0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return rc == 1;
|
while(!stop_flag) {
|
||||||
}
|
#if defined(_WIN32)
|
||||||
|
int rc = WSAPoll(fds, 1, 100);
|
||||||
|
#else
|
||||||
|
int rc = poll(fds, 1, 100);
|
||||||
|
#endif
|
||||||
|
if (rc == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
uint8_t comm_tcp_socket::get_byte()
|
std::unique_lock<std::mutex> lck(cfd_lock);
|
||||||
{
|
|
||||||
uint8_t c = 0;
|
|
||||||
read(fd, &c, 1); // TODO error checking
|
|
||||||
|
|
||||||
return c;
|
// disconnect any existing client session
|
||||||
}
|
// yes, one can 'DOS' with this
|
||||||
|
if (cfd != INVALID_SOCKET) {
|
||||||
|
close(cfd);
|
||||||
|
DOLOG(info, false, "Restarting session for port %d", port);
|
||||||
|
}
|
||||||
|
|
||||||
void comm_tcp_socket::send_data(const uint8_t *const in, const size_t n)
|
cfd = accept(fd, nullptr, nullptr);
|
||||||
{
|
|
||||||
const uint8_t *p = in;
|
|
||||||
size_t len = n;
|
|
||||||
|
|
||||||
while(len > 0) {
|
if (setup_telnet_session(cfd) == false) {
|
||||||
int rc = write(fd, p, len);
|
close(cfd);
|
||||||
if (rc <= 0) // TODO error checking
|
cfd = INVALID_SOCKET;
|
||||||
break;
|
}
|
||||||
|
|
||||||
p += rc;
|
if (cfd != INVALID_SOCKET)
|
||||||
len -= rc;
|
set_nodelay(cfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DOLOG(info, true, "DC11 thread terminating");
|
||||||
|
|
||||||
|
close(cfd);
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
// Released under MIT license
|
// Released under MIT license
|
||||||
|
|
||||||
#include "gen.h"
|
#include "gen.h"
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
#include "comm.h"
|
#include "comm.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
@ -16,7 +19,12 @@
|
||||||
class comm_tcp_socket: public comm
|
class comm_tcp_socket: public comm
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SOCKET fd { INVALID_SOCKET };
|
const int port { -1 };
|
||||||
|
std::atomic_bool stop_flag { false };
|
||||||
|
SOCKET fd { INVALID_SOCKET };
|
||||||
|
SOCKET cfd { INVALID_SOCKET };
|
||||||
|
std::mutex cfd_lock;
|
||||||
|
std::thread *th { nullptr };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
comm_tcp_socket(const int port);
|
comm_tcp_socket(const int port);
|
||||||
|
@ -28,4 +36,6 @@ public:
|
||||||
virtual uint8_t get_byte() = 0;
|
virtual uint8_t get_byte() = 0;
|
||||||
|
|
||||||
virtual void send_data(const uint8_t *const in, const size_t n) = 0;
|
virtual void send_data(const uint8_t *const in, const size_t n) = 0;
|
||||||
|
|
||||||
|
void operator()();
|
||||||
};
|
};
|
||||||
|
|
2
dc11.cpp
2
dc11.cpp
|
@ -41,7 +41,7 @@ constexpr const int serial_line = 3;
|
||||||
|
|
||||||
const char *const dc11_register_names[] { "RCSR", "RBUF", "TSCR", "TBUF" };
|
const char *const dc11_register_names[] { "RCSR", "RBUF", "TSCR", "TBUF" };
|
||||||
|
|
||||||
bool setup_telnet_session(const int fd)
|
static bool setup_telnet_session(const int fd)
|
||||||
{
|
{
|
||||||
uint8_t dont_auth[] = { 0xff, 0xf4, 0x25 };
|
uint8_t dont_auth[] = { 0xff, 0xf4, 0x25 };
|
||||||
uint8_t suppress_goahead[] = { 0xff, 0xfb, 0x03 };
|
uint8_t suppress_goahead[] = { 0xff, 0xfb, 0x03 };
|
||||||
|
|
Loading…
Add table
Reference in a new issue