30#include <sys/socket.h>
45using namespace std::placeholders;
93 "VT snd bytes saved prior connect");
95 "VT snd bytes dropped prior connect");
97 "VT ListenPollHandler() calls");
125 if (!
fUrl.
Set(url,
"|port=|trace|",
"tcp", emsg))
return false;
129 emsg.
Init(
"Rw11VirtTermTcp::Open",
"port= option not specified");
135 unsigned long portno;
138 protoent* pe = getprotobyname(
"tcp");
140 emsg.
Init(
"Rw11VirtTermTcp::Open",
"getprotobyname(\"tcp\") failed");
144 int fd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, pe->p_proto);
146 emsg.
InitErrno(
"Rw11VirtTermTcp::Open",
"socket() failed: ", errno);
151 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) < 0) {
152 emsg.
InitErrno(
"Rw11VirtTermTcp::Open",
"setsockop() failed: ", errno);
158 sa.sin_family = AF_INET;
159 sa.sin_port = htons(
static_cast<unsigned short>(portno));
160 sa.sin_addr.s_addr = htonl(INADDR_ANY);
163 if (::bind(fd,
reinterpret_cast<sockaddr*
>(&sa),
sizeof(sa)) < 0) {
164 emsg.
InitErrno(
"Rw11VirtTermTcp::Open",
"bind() failed: ", errno);
169 if (listen(fd, 1) <0) {
170 emsg.
InitErrno(
"Rw11VirtTermTcp::Open",
"listen() failed: ", errno);
196 const uint8_t* pdata = data;
197 const uint8_t* pdataend = data+count;
198 if (count == 0)
return true;
201 for (
size_t i=0; i<count; i++)
fSndPreConQue.push_back(data[i]);
210 const size_t c_bufsiz=1024;
211 uint8_t obuf[c_bufsiz];
212 while (pdata < pdataend) {
213 uint8_t* pobuf = obuf;
214 uint8_t* pobufend = obuf+
sizeof(obuf);
215 while (pdata < pdataend && pobuf < pobufend-1) {
220 int irc = ::write(
fFd, obuf, pobuf-obuf);
223 RerrMsg emsg(
"Rw11VirtTermTcp::Snd",
224 string(
"write() for port ") +
fChannelId +
" failed: ",
243 os << bl << (text?text:
"--") <<
"Rw11VirtTermTcp @ " <<
this << endl;
245 os << bl <<
" fFdListen: " <<
fFdListen << endl;
246 os << bl <<
" fFd: " <<
fFd << endl;
247 const char* t_state =
"";
249 case ts_Closed: t_state =
"ts_Closed";
break;
250 case ts_Listen: t_state =
"ts_Listen";
break;
251 case ts_Stream: t_state =
"ts_Stream";
break;
252 case ts_Iac: t_state =
"ts_Iac";
break;
253 case ts_Cmd: t_state =
"ts_Cmd";
break;
254 case ts_Subneg: t_state =
"ts_Subneg";
break;
255 case ts_Subiac: t_state =
"ts_Subiac";
break;
256 default: t_state =
"???";
258 os << bl <<
" fState: " << t_state << endl;
260 os << bl <<
" fSndPreConQue.size:" <<
fSndPreConQue.size() << endl;
271 if (pfd.revents & (~pfd.events))
return -1;
277 RerrMsg emsg(
"Rw11VirtTermTcp::ListenPollHandler",
278 string(
"accept() for port ") +
fChannelId +
" failed: ",
296 if (::write(
fFd, buf_1,
sizeof(buf_1)) < 0) nerr += 1;
297 if (::write(
fFd, buf_2,
sizeof(buf_2)) < 0) nerr += 1;
298 if (::write(
fFd, buf_3,
sizeof(buf_3)) < 0) nerr += 1;
299 if (::write(
fFd, buf_4,
sizeof(buf_4)) < 0) nerr += 1;
300 if (::write(
fFd, buf_5,
sizeof(buf_5)) < 0) nerr += 1;
306 <<
" for " <<
Unit().
Name() <<
"\r\n\r\n";
307 string str = msg.str();
308 if (::write(
fFd, str.c_str(), str.length()) < 0) nerr += 1;
318 string str = msg.str();
319 if (::write(
fFd, str.c_str(), str.length()) < 0) nerr += 1;
326 RerrMsg emsg(
"Rw11VirtTermTcp::ListenPollHandler",
327 string(
"initial write()s for port ") +
fChannelId +
355 if (pfd.revents & POLLIN) {
356 const size_t c_bufsiz=1024;
357 uint8_t ibuf[c_bufsiz];
358 uint8_t obuf[c_bufsiz];
359 uint8_t* pobuf = obuf;
361 irc = ::read(
fFd, ibuf,
sizeof(ibuf));
363 if (irc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
return 0;
367 for (
int i=0; i<irc; i++) {
368 uint8_t byt = ibuf[i];
410 if (pobuf > obuf)
fRcvCb(obuf, pobuf - obuf);
417 RerrMsg emsg(
"Rw11VirtTermTcp::RcvPollHandler",
418 string(
"read() for port ") +
fChannelId +
" failed: ",
void Init(const std::string &meth, const std::string &text)
FIXME_docs.
void InitErrno(const std::string &meth, const std::string &text, int errnum)
FIXME_docs.
void RemovePollHandler(int fd, short events, bool nothrow=false)
FIXME_docs.
void AddPollHandler(pollhdl_t &&pollhdl, int fd, short events=POLLIN)
FIXME_docs.
I/O appicator to generate fill characters.
bool FindOpt(const std::string &name) const
FIXME_docs.
bool Set(const std::string &url, const std::string &optlist, RerrMsg &emsg)
FIXME_docs.
void Inc(size_t ind, double val=1.)
FIXME_docs.
void Define(size_t ind, const std::string &name, const std::string &text)
FIXME_docs.
std::string Name() const
FIXME_docs.
static const uint8_t kCode_WILL
static const uint8_t kCode_DONT
Rw11VirtTermTcp(Rw11Unit *punit)
Default constructor.
~Rw11VirtTermTcp()
Destructor.
static const uint8_t kCode_IP
static const size_t kPreConQue_limit
std::deque< uint8_t > fSndPreConQue
static const uint8_t kOpt_TTYP
static const uint8_t kCode_SB
static const uint8_t kOpt_LINE
bool Connected() const
FIXME_docs.
virtual bool Open(const std::string &url, RerrMsg &emsg)
FIXME_docs.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
static const uint8_t kOpt_ECHO
static const uint8_t kCode_WONT
int RcvPollHandler(const pollfd &pfd)
FIXME_docs.
static const uint8_t kCode_NOP
static const uint8_t kCode_GA
static const uint8_t kCode_ESC
static const uint8_t kCode_NULL
static const uint8_t kCode_IAC
static const uint8_t kOpt_SGA
int ListenPollHandler(const pollfd &pfd)
FIXME_docs.
static const uint8_t kCode_DO
virtual bool Snd(const uint8_t *data, size_t count, RerrMsg &emsg)
FIXME_docs.
static const uint8_t kCode_SE
static const uint8_t kOpt_BIN
static const uint8_t kCode_LF
static const uint8_t kCode_CR
rcvcbfo_t fRcvCb
receive callback fobj
std::string fChannelId
channel id
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
RlogFile & LogFile() const
FIXME_docs.
Rw11Unit & Unit() const
FIXME_docs.
RlinkServer & Server() const
FIXME_docs.
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Declaration of class ReventLoop.