⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcxsend.c

📁 RCXDownload and RCXDirectMode是leJOS的一个可视化接口。RCXDownload自动设置JDK-, leJOS-和ClassPath
💻 C
📖 第 1 页 / 共 2 页
字号:
	    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 + -