xvc_server: don't stop when connection close, rework read to return code for error and for disconnect
This commit is contained in:
parent
c28e955bb9
commit
2182a8ff7f
|
|
@ -6,6 +6,7 @@
|
||||||
#include "xvc_server.hpp"
|
#include "xvc_server.hpp"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
@ -43,12 +44,12 @@ XVC_server::XVC_server(int port, const cable_t & cable,
|
||||||
if (pin_conf == NULL)
|
if (pin_conf == NULL)
|
||||||
throw std::exception();
|
throw std::exception();
|
||||||
_jtag =
|
_jtag =
|
||||||
new FtdiJtagBitBang(cable.config, pin_conf, dev, serial,
|
new FtdiJtagBitBang(cable.config, pin_conf, dev, serial,
|
||||||
clkHZ, _verbose);
|
clkHZ, _verbose);
|
||||||
break;
|
break;
|
||||||
case MODE_CH552_JTAG:
|
case MODE_CH552_JTAG:
|
||||||
_jtag =
|
_jtag =
|
||||||
new CH552_jtag(cable.config, dev, serial, clkHZ, _verbose);
|
new CH552_jtag(cable.config, dev, serial, clkHZ, _verbose);
|
||||||
break;
|
break;
|
||||||
case MODE_DIRTYJTAG:
|
case MODE_DIRTYJTAG:
|
||||||
_jtag = new DirtyJtag(clkHZ, _verbose);
|
_jtag = new DirtyJtag(clkHZ, _verbose);
|
||||||
|
|
@ -58,12 +59,12 @@ XVC_server::XVC_server(int port, const cable_t & cable,
|
||||||
break;
|
break;
|
||||||
case MODE_USBBLASTER:
|
case MODE_USBBLASTER:
|
||||||
_jtag = new UsbBlaster(cable.config.vid, cable.config.pid,
|
_jtag = new UsbBlaster(cable.config.vid, cable.config.pid,
|
||||||
firmware_path, _verbose);
|
firmware_path, _verbose);
|
||||||
break;
|
break;
|
||||||
#ifdef ENABLE_CMSISDAP
|
#ifdef ENABLE_CMSISDAP
|
||||||
case MODE_CMSISDAP:
|
case MODE_CMSISDAP:
|
||||||
_jtag =
|
_jtag =
|
||||||
new CmsisDAP(cable.config.vid, cable.config.pid, _verbose);
|
new CmsisDAP(cable.config.vid, cable.config.pid, _verbose);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -139,67 +140,69 @@ bool XVC_server::close_connection()
|
||||||
|
|
||||||
void XVC_server::thread_listen()
|
void XVC_server::thread_listen()
|
||||||
{
|
{
|
||||||
fd_set conn;
|
fd_set conn;
|
||||||
int maxfd = 0;
|
int maxfd = 0;
|
||||||
|
|
||||||
FD_ZERO(&conn);
|
FD_ZERO(&conn);
|
||||||
FD_SET(_sock, &conn);
|
FD_SET(_sock, &conn);
|
||||||
|
|
||||||
maxfd = _sock;
|
maxfd = _sock;
|
||||||
|
|
||||||
while (!_must_stop) {
|
while (!_must_stop) {
|
||||||
fd_set read = conn, except = conn;
|
fd_set read = conn, except = conn;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = 1;
|
tv.tv_sec = 1;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
if (select(maxfd + 1, &read, 0, &except, &tv) < 0) {
|
if (select(maxfd + 1, &read, 0, &except, &tv) < 0) {
|
||||||
printError("select");
|
printError("select");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (fd = 0; fd <= maxfd; ++fd) {
|
for (fd = 0; fd <= maxfd; ++fd) {
|
||||||
if (FD_ISSET(fd, &read)) {
|
if (FD_ISSET(fd, &read)) {
|
||||||
if (fd == _sock) {
|
if (fd == _sock) {
|
||||||
int newfd;
|
int newfd;
|
||||||
socklen_t nsize = sizeof(_sock_addr);
|
socklen_t nsize = sizeof(_sock_addr);
|
||||||
|
|
||||||
newfd = accept(_sock, (struct sockaddr*) &_sock_addr,
|
newfd = accept(_sock, (struct sockaddr*) &_sock_addr,
|
||||||
&nsize);
|
&nsize);
|
||||||
|
|
||||||
printf("connection accepted - fd %d\n", newfd);
|
printf("connection accepted - fd %d\n", newfd);
|
||||||
if (newfd < 0) {
|
if (newfd < 0) {
|
||||||
throw std::runtime_error("accept");
|
throw std::runtime_error("accept");
|
||||||
} else {
|
} else {
|
||||||
printInfo("setting TCP_NODELAY to 1\n");
|
printInfo("setting TCP_NODELAY to 1\n");
|
||||||
int flag = 1;
|
int flag = 1;
|
||||||
int optResult = setsockopt(newfd, IPPROTO_TCP,
|
int optResult = setsockopt(newfd, IPPROTO_TCP,
|
||||||
TCP_NODELAY, (char *)&flag, sizeof(int));
|
TCP_NODELAY, (char *)&flag, sizeof(int));
|
||||||
if (optResult < 0)
|
if (optResult < 0)
|
||||||
throw std::runtime_error("TCP_NODELAY error");
|
throw std::runtime_error("TCP_NODELAY error");
|
||||||
if (newfd > maxfd) {
|
if (newfd > maxfd) {
|
||||||
maxfd = newfd;
|
maxfd = newfd;
|
||||||
}
|
}
|
||||||
FD_SET(newfd, &conn);
|
FD_SET(newfd, &conn);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int ret = handle_data(fd);
|
int ret = handle_data(fd);
|
||||||
printInfo("connection closed - fd " + std::to_string(fd));
|
if (ret != 0) {
|
||||||
close(fd);
|
printInfo("connection closed - fd " + std::to_string(fd));
|
||||||
FD_CLR(fd, &conn);
|
close(fd);
|
||||||
if (ret == 1)
|
FD_CLR(fd, &conn);
|
||||||
throw std::runtime_error("communication failure");
|
if (ret == 3)
|
||||||
|
throw std::runtime_error("communication failure");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (FD_ISSET(fd, &except)) {
|
} else if (FD_ISSET(fd, &except)) {
|
||||||
printWarn("connection aborted - fd " + std::to_string(fd));
|
printWarn("connection aborted - fd " + std::to_string(fd));
|
||||||
close(fd);
|
close(fd);
|
||||||
FD_CLR(fd, &conn);
|
FD_CLR(fd, &conn);
|
||||||
if (fd == _sock)
|
if (fd == _sock)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_is_stopped = true;
|
_is_stopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,37 +223,46 @@ bool XVC_server::listen_loop()
|
||||||
|
|
||||||
int XVC_server::sread(int fd, void *target, int len)
|
int XVC_server::sread(int fd, void *target, int len)
|
||||||
{
|
{
|
||||||
unsigned char *t = (unsigned char *)target;
|
unsigned char *t = (unsigned char *)target;
|
||||||
while (len) {
|
while (len) {
|
||||||
int r = read(fd, t, len);
|
int r = read(fd, t, len);
|
||||||
if (r <= 0)
|
if (r == 0) // connection closed
|
||||||
return r;
|
return 2;
|
||||||
t += r;
|
else if (r < 0) {
|
||||||
len -= r;
|
char err[256];
|
||||||
}
|
snprintf(err, 256, "Read error (%d) %d %s\n", r,
|
||||||
return 1;
|
errno, strerror(errno));
|
||||||
}
|
printError(err);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
t += r;
|
||||||
|
len -= r;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int XVC_server::handle_data(int fd)
|
int XVC_server::handle_data(int fd)
|
||||||
{
|
{
|
||||||
char xvcInfo[32];
|
char xvcInfo[32];
|
||||||
|
int ret;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char cmd[16];
|
char cmd[16];
|
||||||
memset(cmd, 0, 16);
|
memset(cmd, 0, 16);
|
||||||
|
|
||||||
if (sread(fd, cmd, 2) != 1)
|
if ((ret = sread(fd, cmd, 2)) != 1) {
|
||||||
return 1;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* getinfo */
|
/* getinfo */
|
||||||
if (memcmp(cmd, "ge", 2) == 0) {
|
if (memcmp(cmd, "ge", 2) == 0) {
|
||||||
if (sread(fd, cmd, 6) != 1)
|
if ((ret = sread(fd, cmd, 6)) != 1)
|
||||||
return 1;
|
return ret;
|
||||||
snprintf(xvcInfo, sizeof(xvcInfo),
|
snprintf(xvcInfo, sizeof(xvcInfo),
|
||||||
"xvcServer_v1.0:%u\n", _buffer_size);
|
"xvcServer_v1.0:%u\n", _buffer_size);
|
||||||
if (send(fd, xvcInfo, strlen(xvcInfo), 0) !=
|
if (send(fd, xvcInfo, strlen(xvcInfo), 0) !=
|
||||||
(ssize_t) strlen(xvcInfo)) {
|
(ssize_t) strlen(xvcInfo)) {
|
||||||
perror("write");
|
perror("write");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -262,8 +274,8 @@ int XVC_server::handle_data(int fd)
|
||||||
break;
|
break;
|
||||||
/* settck */
|
/* settck */
|
||||||
} else if (memcmp(cmd, "se", 2) == 0) {
|
} else if (memcmp(cmd, "se", 2) == 0) {
|
||||||
if (sread(fd, cmd, 9) != 1)
|
if ((ret = sread(fd, cmd, 9)) != 1)
|
||||||
return 1;
|
return ret;
|
||||||
memcpy(_result, cmd + 5, 4);
|
memcpy(_result, cmd + 5, 4);
|
||||||
if (write(fd, _result, 4) != 4) {
|
if (write(fd, _result, 4) != 4) {
|
||||||
printError("write");
|
printError("write");
|
||||||
|
|
@ -281,24 +293,24 @@ int XVC_server::handle_data(int fd)
|
||||||
printInfo(std::to_string((int)time(NULL)) +
|
printInfo(std::to_string((int)time(NULL)) +
|
||||||
" : Received command: 'settck'");
|
" : Received command: 'settck'");
|
||||||
printf("\t Replied with '%.*s'\n\n", 4,
|
printf("\t Replied with '%.*s'\n\n", 4,
|
||||||
cmd + 5);
|
cmd + 5);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (memcmp(cmd, "de", 2) == 0) { // DEBUG CODE
|
} else if (memcmp(cmd, "de", 2) == 0) { // DEBUG CODE
|
||||||
if (sread(fd, cmd, 3) != 1)
|
if ((ret = sread(fd, cmd, 3)) != 1)
|
||||||
return 1;
|
return ret;
|
||||||
printf("%u : Received command: 'debug'\n",
|
printf("%u : Received command: 'debug'\n",
|
||||||
(int)time(NULL));
|
(int)time(NULL));
|
||||||
break;
|
break;
|
||||||
} else if (memcmp(cmd, "of", 2) == 0) { // DEBUG CODE
|
} else if (memcmp(cmd, "of", 2) == 0) { // DEBUG CODE
|
||||||
if (sread(fd, cmd, 1) != 1)
|
if ((ret = sread(fd, cmd, 1)) != 1)
|
||||||
return 1;
|
return ret;
|
||||||
printf("%u : Received command: 'off'\n",
|
printf("%u : Received command: 'off'\n",
|
||||||
(int)time(NULL));
|
(int)time(NULL));
|
||||||
break;
|
break;
|
||||||
} else if (memcmp(cmd, "sh", 2) == 0) {
|
} else if (memcmp(cmd, "sh", 2) == 0) {
|
||||||
if (sread(fd, cmd, 4) != 1)
|
if ((ret = sread(fd, cmd, 4)) != 1)
|
||||||
return 1;
|
return ret;
|
||||||
if (_verbose) {
|
if (_verbose) {
|
||||||
printInfo(std::to_string((int)time(NULL)) +
|
printInfo(std::to_string((int)time(NULL)) +
|
||||||
" : Received command: 'shift'");
|
" : Received command: 'shift'");
|
||||||
|
|
@ -311,9 +323,9 @@ int XVC_server::handle_data(int fd)
|
||||||
/* Handling for -> "shift:<num bits><tms vector><tdi vector>" */
|
/* Handling for -> "shift:<num bits><tms vector><tdi vector>" */
|
||||||
uint32_t len, nr_bytes;
|
uint32_t len, nr_bytes;
|
||||||
/* 1. len */
|
/* 1. len */
|
||||||
if (sread(fd, &len, 4) != 1) {
|
if ((ret = sread(fd, &len, 4)) != 1) {
|
||||||
printError("reading length failed");
|
printError("reading length failed");
|
||||||
return 1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. convert len (in bits) to nr_bytes (in bytes) */
|
/* 2. convert len (in bits) to nr_bytes (in bytes) */
|
||||||
|
|
@ -326,9 +338,9 @@ int XVC_server::handle_data(int fd)
|
||||||
|
|
||||||
/* 3. receive 2 x nr_bytes (TMS + TDI) */
|
/* 3. receive 2 x nr_bytes (TMS + TDI) */
|
||||||
memset(_tmstdi, 0, _buffer_size);
|
memset(_tmstdi, 0, _buffer_size);
|
||||||
if (sread(fd, _tmstdi, nr_bytes * 2) != 1) {
|
if ((ret = sread(fd, _tmstdi, nr_bytes * 2)) != 1) {
|
||||||
printError("reading data failed");
|
printError("reading data failed");
|
||||||
return 1;
|
return ret;
|
||||||
}
|
}
|
||||||
memset(_result, 0, _buffer_size/2);
|
memset(_result, 0, _buffer_size/2);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ class XVC_server {
|
||||||
void thread_listen();
|
void thread_listen();
|
||||||
/*!
|
/*!
|
||||||
* \brief parser and dispatcher for XVC transactions
|
* \brief parser and dispatcher for XVC transactions
|
||||||
* \return 1 when transactions fails, 0 otherwise
|
* \return 2 when connection is closed, 1 when transactions fails,
|
||||||
|
* 0 otherwise
|
||||||
*/
|
*/
|
||||||
int handle_data(int fd);
|
int handle_data(int fd);
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -58,7 +59,7 @@ class XVC_server {
|
||||||
* \param fd: socket descriptor
|
* \param fd: socket descriptor
|
||||||
* \param target: buffer
|
* \param target: buffer
|
||||||
* \param len: number of bytes to read
|
* \param len: number of bytes to read
|
||||||
* \return <= 0 when failure, 1 otherwise
|
* \return 3 when failure, 2 when connection closed, 1 otherwise
|
||||||
*/
|
*/
|
||||||
int sread(int fd, void *target, int len);
|
int sread(int fd, void *target, int len);
|
||||||
int _verbose; /*!< verbose level */
|
int _verbose; /*!< verbose level */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue