Files
Gen4_R-Car_Trace32/2_Trunk/demo/arm/etc/t32server/remote.c
2025-10-14 09:52:32 +09:00

264 lines
5.0 KiB
C

// --------------------------------------------------------------------------------
// @Title: t32server - remote
// @Description: -
// @Author: KJM
// @Copyright: (C) 1989-2022 Lauterbach GmbH, licensed for use with TRACE32(R) only
// --------------------------------------------------------------------------------
// $Id: remote.c 18850 2022-01-26 18:41:29Z bschroefel $
#include "main.h"
#include "remote.h"
#include "arm-dcc.h"
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <stdlib.h>
/* seconds to wait for connect */
#define TIMEOUT 15
#define POLL_INTERVAL 2
extern void debugout(const char *format, ...);
//! TRACE32 -> t32server <- gdbserver's
static int ReceiveBlock(char *buffer, int len, int timeout, int fd)
{
fd_set fds;
int n, tmp, m;
struct timeval tv;
time_t t0;
if ((t0 = time(0)) == -1)
{
return -4;
}
tv.tv_sec = 0;
tv.tv_usec = timeout * 1000; // 500 ms
n=0;
while (n<len)
{
/* Check readability */
FD_ZERO (&fds); FD_SET (fd, &fds);
tmp = select (fd+1, &fds, (void *)0, (void *)0, &tv);
/* Error. Return */
if (tmp < 0)
{
return -1;
}
/* Data available. Read */
else if ((tmp > 0) && FD_ISSET (fd, &fds))
{
if ((m = recv (fd, buffer+n, len - n,0)) <= 0)
{
return -2;
}
else n += m;
buffer[n] = 0;
} else
break;
/* Update time left. (0s < Error < 1s) */
if ((tv.tv_sec -= (long) (difftime (time (0), t0) - timeout/1000.0)) < 0)
tv.tv_sec = 0;
}
return n;
}
//! open a tcp socket and establish the connection
int GdbNetOpen(int port)
{
struct sockaddr_in sockaddr;
struct hostent *hostent;
int n, fd, tmp, error;
const char hostname[100] = {'1','2','7','.','0','.','0','.','1'};
hostent = gethostbyname (hostname);
if (!hostent)
{
fprintf (stderr, "%s: unknown host\n", hostname);
return -1;
}
fd = socket (PF_INET, SOCK_STREAM, 0);
if (fd < 0)
return -1;
sockaddr.sin_family = PF_INET;
sockaddr.sin_port = htons(port);
memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr, sizeof (struct in_addr));
n = connect (fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
if (n < 0 && errno != EINPROGRESS)
{
error = errno;
close(fd);
if (error == 101)
return -3;
return -2;
}
if (n)
{
/* looks like we need to wait for the connect */
struct timeval t;
fd_set rset, wset, eset;
int polls = 0;
fflush(stderr);
FD_ZERO (&rset);
do {
FD_SET (fd, &rset);
wset = rset;
eset = rset;
t.tv_sec = 0;
t.tv_usec = 1000000 / POLL_INTERVAL;
n = select (fd + 1, &rset, &wset, &eset, &t);
polls++;
} while (n == 0 && polls <= TIMEOUT * POLL_INTERVAL);
if (n < 0 || polls > TIMEOUT * POLL_INTERVAL)
{
close (fd);
fd = -1;
return -2;
}
}
/* Got something. Is it an error? */
{
int res, err;
socklen_t len;
len = sizeof (err);
res = getsockopt (fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
tmp = 1;
// disable Nagle algorithm needed in some cases
res = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &tmp, sizeof(tmp));
if (res < 0 || err)
{
close (fd);
fd = -1;
return -1;
}
}
tmp = 1;
// disable Nagle algorithm needed in some cases
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &tmp, sizeof(tmp));
return fd;
}
//! t32server -> TRACE32
int TransmitBlock(char *buf, int len, int timeout)
{
int cnt = 0;
if (len > 1)
debugout("reply to host (%i): (\"%s\")\n", len, buf);
cnt = send_dcc(buf, len, timeout, 0);
if (cnt <= 0 && len > 1)
debugout("TransmitBlock: error\n");
return cnt;
}
int GdbGetReply(char *reply, int fd, int timeout /* in ms */)
{
int cnt;
int i = 0;
memset(reply, 0, BUFSIZE);
do {
if (timeout == 0 && i > 0)
timeout = 500; /* ms */
cnt = ReceiveBlock(reply+i, 1, timeout, fd);
if (cnt > 0)
i += cnt;
} while (cnt > 0 && reply[i - 1] != '#' && i < BUFSIZE);
if (cnt > 0 && i < BUFSIZE)
ReceiveBlock(reply+i, 2, timeout, fd);
else
return -1;
reply[i+2] = 0;
send(fd, "+", 1, 0);
return i;
}
inline int GetT32CmdDCC(char *buf)
{
int data, nmax = -1, timeout = 1000, len, n, i;
char tmp[4096];
start:
n = 0;
while (1)
{
if (n == 0)
timeout = 1;
else
timeout = 10000; /* we received a part of the packet, so wait more for the rest */
data = read_dcc (tmp, timeout);
if (data <= 0)
{
if (n > 0)
return n;
else
return -1;
}
len = ((data >> 24) & 0x3) + 1;
if (n == 0)
debugout("[T32]: (\"");
for(i=0; i<len; i++)
{
buf[n] = (data >> (8*i)) & 0x7f;
debugout("%c", buf[n]);
if ((buf[n] == '$' || buf[n] == '&') && n != 0)
{
/* new packet in the middle of an old one */
buf[0] = buf[n];
n = 0;
}
if (buf[n] == '%') /* end of t32 command */
{
debugout("\")\n");
buf[n+1] = 0;
return n;
}
if (buf[n] == '#') /* end of gdb command = n+2 (checsum) */
{
nmax = n + 2;
}
n++;
if (n > nmax && nmax != -1)
{
buf[n] = '\0';
debugout("\")\n");
return n;
}
}
if (n > 1024)
{
debugout("TIMEOUT\n");
n = 0;
goto start;
}
}
return n;
}
int GetT32Cmd(char *buf)
{
buf[0] = 0;
return GetT32CmdDCC(buf);
}