📄 rcxsend.c
字号:
return RCX_OK; /* success */
if (__comm_debug) {
printf("recvlen = %d\n", len);
hexdump("R", buf, len);
}
rx_flush(fd);
} while (timer_read(&timer) < (float)timeout / 1000.0f);
if (!count)
return RCX_NO_TOWER; /* tower not responding */
else
return RCX_BAD_LINK; /* bad link */
}
/* Hexdump routine */
#define LINE_SIZE 16
#define GROUP_SIZE 4
#define UNPRINTABLE '.'
void hexdump(char *prefix, void *buf, int len)
{
unsigned char *b = (unsigned char *)buf;
int i, j, w;
for (i = 0; i < len; i += w) {
w = len - i;
if (w > LINE_SIZE)
w = LINE_SIZE;
if (prefix)
printf("%s ", prefix);
printf("%04x: ", i);
for (j = 0; j < w; j++, b++) {
printf("%02x ", *b);
if ((j + 1) % GROUP_SIZE == 0)
putchar(' ');
}
putchar('\n');
}
}
int rcx_send (FILEDESCR fd, void *buf, int len) // , int use_comp)
{
char *bufp = (char *)buf;
char buflen = len;
char msg[BUFFERSIZE];
char echo[BUFFERSIZE];
int msglen, echolen;
int sum;
/* Encode message */
msglen = 0;
sum = 0;
// if (use_comp) {
msg[msglen++] = 0x55;
msg[msglen++] = 0xff;
msg[msglen++] = 0x00;
while (buflen--) {
msg[msglen++] = *bufp;
msg[msglen++] = (~*bufp) & 0xff;
sum += *bufp++;
}
msg[msglen++] = sum;
msg[msglen++] = ~sum;
/*
}
else {
msg[msglen++] = 0xff;
while (buflen--) {
msg[msglen++] = *bufp;
sum += *bufp++;
}
msg[msglen++] = sum;
}
*/
/* Send message */
if (mywrite(fd, msg, msglen) != msglen) {
myperror("write");
exit(1);
}
/* Receive echo */
echolen = nbread(fd, echo, msglen, 100);
if (__comm_debug) {
printf("msglen = %d, echolen = %d\n", msglen, echolen);
hexdump("C", echo, echolen);
}
/* Check echo */
/* Ignore data, since rcx might send ack even if echo data is wrong */
if (echolen != msglen /* || memcmp(echo, msg, msglen) */ ) {
/* Flush connection if echo is bad */
rx_flush(fd);
return RCX_BAD_ECHO;
}
return len;
}
int rcx_recv (FILEDESCR fd, void *buf, int maxlen, int timeout) // , int use_comp)
{
char *bufp = (char *)buf;
unsigned char msg[BUFFERSIZE];
int msglen;
int sum;
int pos;
int len;
/* Receive message */
msglen = nbread(fd, msg, BUFFERSIZE, timeout);
if (__comm_debug) {
printf("recvlen = %d\n", msglen);
hexdump("R", msg, msglen);
}
/* Check for message */
if (!msglen)
return RCX_NO_RESPONSE;
/* Verify message */
// if (use_comp) {
if (msglen < 5 || (msglen - 3) % 2 != 0)
return RCX_BAD_RESPONSE;
if (msg[0] != 0x55 || msg[1] != 0xff || msg[2] != 0x00)
return RCX_BAD_RESPONSE;
for (sum = 0, len = 0, pos = 3; pos < msglen - 2; pos += 2) {
if (msg[pos] != ((~msg[pos+1]) & 0xff))
return RCX_BAD_RESPONSE;
sum += msg[pos];
if (len < maxlen)
bufp[len++] = msg[pos];
}
if (msg[pos] != ((~msg[pos+1]) & 0xff))
return RCX_BAD_RESPONSE;
if (msg[pos] != (sum & 0xff))
return RCX_BAD_RESPONSE;
/* Success */
return len;
/*
}
else {
if (msglen < 4)
return RCX_BAD_RESPONSE;
if (msg[0] != 0x55 || msg[1] != 0xff || msg[2] != 0x00)
return RCX_BAD_RESPONSE;
for (sum = 0, len = 0, pos = 3; pos < msglen - 1; pos++) {
sum += msg[pos];
if (len < maxlen)
bufp[len++] = msg[pos];
}
// Return success if checksum matches
if (msg[pos] == (sum & 0xff))
return len;
// Failed. Possibly a 0xff byte queued message? (legos unlock firmware)
for (sum = 0, len = 0, pos = 3; pos < msglen - 2; pos++) {
sum += msg[pos];
if (len < maxlen)
bufp[len++] = msg[pos];
}
// Return success if checksum matches
if (msg[pos] == (sum & 0xff))
return len;
// Failed. Possibly a long message?
// Long message if opcode is complemented and checksum okay
// If long message, checksum does not include opcode complement
for (sum = 0, len = 0, pos = 3; pos < msglen - 1; pos++) {
if (pos == 4) {
if (msg[3] != ((~msg[4]) & 0xff))
return RCX_BAD_RESPONSE;
}
else {
sum += msg[pos];
if (len < maxlen)
bufp[len++] = msg[pos];
}
}
if (msg[pos] != (sum & 0xff))
return RCX_BAD_RESPONSE;
// Success
return len;
}
*/
}
int rcx_sendrecv (FILEDESCR fd, void *send, int slen, void *recv, int rlen,
int timeout, int retries) //, int use_comp)
{
int status = 0;
if (__comm_debug) printf("sendrecv %d:\n", slen);
while (retries--) {
// if ((status = rcx_send(fd, send, slen, use_comp)) < 0) {
if ((status = rcx_send(fd, send, slen)) < 0) {
if (__comm_debug) printf("status = %s\n", rcx_strerror(status));
continue;
}
// if ((status = rcx_recv(fd, recv, rlen, timeout, use_comp)) < 0) {
if ((status = rcx_recv(fd, recv, rlen, timeout)) < 0) {
if (__comm_debug) printf("status = %s\n", rcx_strerror(status));
continue;
}
break;
}
if (__comm_debug) {
if (status > 0)
printf("status = %s\n", rcx_strerror(0));
else
printf("status = %s\n", rcx_strerror(status));
}
return status;
}
int rcx_is_alive (FILEDESCR fd) // , int use_comp)
{
unsigned char send[1] = { 0x10 };
unsigned char recv[1];
// return (rcx_sendrecv(fd, send, 1, recv, 1, 50, 5, use_comp) == 1);
return (rcx_sendrecv(fd, send, 1, recv, 1, 50, 5) == 1);
}
char *rcx_strerror (int error)
{
switch (error) {
case RCX_OK: return "no error";
case RCX_NO_TOWER: return "tower not responding";
case RCX_BAD_LINK: return "bad ir link";
case RCX_BAD_ECHO: return "bad ir echo";
case RCX_NO_RESPONSE: return "no response from rcx";
case RCX_BAD_RESPONSE: return "bad response from rcx";
default: return "unknown error";
}
}
/*** rcxsend.c ***/
/* Global variables */
char *progname;
/* Defines */
/* Defines */
#define BUFFERSIZE 4096
#define RETRIES 5
#define WAKEUP_TIMEOUT 4000
/* #define WAKEUP_TIMEOUT 1000 */
/* Functions */
int main (int argc, char **argv)
{
unsigned char sendbuf[BUFFERSIZE];
unsigned char recvbuf[BUFFERSIZE];
unsigned char *sp = sendbuf;
char *tty = NULL;
// int use_fast = 0;
int usage = 0;
FILEDESCR fd;
int i;
int status;
progname = argv[0];
/* Parse command line */
argv++; argc--;
while (argc && argv[0][0] == '-') {
if (argv[0][1] == '-') {
if (!strcmp(argv[0], "--")) {
argv++; argc--;
break;
}
else if (!strcmp(argv[0], "--debug")) {
extern int __comm_debug;
__comm_debug = 1;
} /*
else if (!strcmp(argv[0], "--fast")) {
use_fast = 1;
}
else if (!strcmp(argv[0], "--slow")) {
use_fast = 0;
} */
else if (!strncmp(argv[0], "--tty", 5)) {
if (argv[0][5] == '=') {
tty = &argv[0][6];
}
else if (argc > 1) {
argv++; argc--;
tty = argv[0];
}
else
tty = "";
if (!tty[0]) {
fprintf(stderr, "%s: invalid tty: %s\n", progname, tty);
exit(1);
}
}
else if (!strcmp(argv[0], "--help")) {
usage = 1;
}
else {
fprintf(stderr, "%s: unrecognized option %s\n",
progname, argv[0]);
exit(1);
}
}
else {
char *p = &argv[0][1];
if (!*p)
break;
while (*p) {
switch (*p) {
// case 'f': use_fast = 1; break;
// case 's': use_fast = 0; break;
case 'h': usage = 1; break;
default:
fprintf(stderr, "%s: unrecognized option -- %c\n",
progname, *p);
exit(1);
}
p++;
}
}
argv++;
argc--;
}
/* Print usage if nothing on command line */
if (argc == 0) {
if (!usage) {
printf ("Use --help for options.\n");
exit(1);
}
}
if (usage) {
char *usage_string =
" --debug show debug output, mostly raw bytes\n"
// " -f, --fast use fast 4x downloading\n"
// " -s, --slow use slow 1x downloading (DEFAULT)\n"
" --tty=TTY assume tower connected to TTY\n"
" -h, --help display this help and exit\n"
;
fprintf(stderr, "usage: %s [options] byte [byte ...]\n", progname);
fprintf(stderr, usage_string);
exit(1);
}
/* Assemble the message */
while (argc > 0) {
*sp++ = strtol(argv[0], NULL, 16);
argv++; argc--;
}
/* Open the serial port */
if (!tty)
if ((tty = getenv("RCXTTY")) == NULL)
tty = DEFAULTTTY;
fd = rcx_init(tty);
if ((status = rcx_wakeup_tower(fd, WAKEUP_TIMEOUT)) < 0) {
fprintf(stderr, "%s: %s\n", progname, rcx_strerror(status));
exit(1);
}
/* Send it */
status = rcx_sendrecv(fd, sendbuf, sp - sendbuf, recvbuf, BUFFERSIZE, 50, RETRIES);
/* Close the tty */
/* fprintf(stderr, "Close the tty.\n", argv[0]); */
rcx_close(fd);
/* Print response and exit */
if (status == RCX_BAD_LINK) {
fprintf(stderr, "%s: Bad link.\n", progname);
exit(4);
}
if (status == RCX_BAD_RESPONSE) {
fprintf(stderr, "%s: Bad response.\n", progname);
exit(2);
}
if (status == RCX_NO_RESPONSE) {
fprintf(stderr, "%s: No response.\n", progname);
exit(3);
}
if (status == RCX_BAD_ECHO) {
fprintf(stderr, "%s: Response too large.\n", progname);
exit(5);
}
hexdump("C",recvbuf, status);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -