📄 zmdm.c
字号:
*/ return c; } } while (FALSE); /* * ZDLE encoded sequence or session abort. * (or something illegal; then back to the top) */ do { c = rx_raw(to); if (c == 0x11 || c == 0x13 || c == 0x91 || c == 0x93 || c == ZDLE) { /* * these can be dropped. */ continue; } switch (c) { /* * these four are really nasty. * for convenience we just change them into * special characters by setting a bit outside the * first 8. that way they can be recognized and still * be processed as characters by the rest of the code. */ case ZCRCE: case ZCRCG: case ZCRCQ: case ZCRCW: return (c | ZDLEESC); break; case ZRUB0: return 0x7f; break; case ZRUB1: return 0xff; break; default: if (escape_all_control_characters && (c & 0x60) == 0) { /* * a not escaped control character; probably * something from a network. just drop it. */ continue; } /* * legitimate escape sequence. * rebuild the orignal and return it. */ if ((c & 0x60) == 0x40) { return c ^ 0x40; } break; } } while (FALSE); } /* * not reached. */ return 0;}/* * receive a data subpacket as dictated by the last received header. * return 2 with correct packet and end of frame * return 1 with correct packet frame continues * return 0 with incorrect frame. * return TIMEOUT with a timeout * if an acknowledgement is requested it is generated automatically * here. *//* * data subpacket reception */int rx_32_data(unsigned char *p, int *l){ int c; unsigned long rxd_crc; unsigned long crc; int sub_frame_type;#ifdef DEBUG fprintf(logfp, "rx_32_data\n");#endif crc = 0xffffffffl; do { c = rx(1000); if (c == TIMEOUT) { return TIMEOUT; } if (c < 0x100) { crc = UPDCRC32(c, crc); *p++ = c; (*l)++; continue; } } while (c < 0x100); sub_frame_type = c & 0xff; crc = UPDCRC32(sub_frame_type, crc); crc = ~crc; rxd_crc = rx(1000); rxd_crc |= rx(1000) << 8; rxd_crc |= rx(1000) << 16; rxd_crc |= rx(1000) << 24;#ifndef XXX_SKIP_CRC if (rxd_crc != crc) { return FALSE; }#endif ack_file_pos += *l; return sub_frame_type;}int rx_16_data(register unsigned char *p, int *l){ register int c; int sub_frame_type; register unsigned short crc; unsigned short rxd_crc;#ifdef DEBUG fprintf(logfp, "rx_16_data:\n");#endif crc = 0; do { c = rx(5000); if (c == TIMEOUT) { return TIMEOUT; } if (c < 0x100) { crc = UPDCRC16(c, crc); *p++ = c; (*l)++; } } while (c < 0x100); sub_frame_type = c & 0xff; crc = UPDCRC16(sub_frame_type, crc); crc = UPDCRC16(0, crc); crc = UPDCRC16(0, crc); rxd_crc = rx(1000) << 8; rxd_crc |= rx(1000);#ifndef XXX_SKIP_CRC if (rxd_crc != crc) {#ifdef DEBUG fprintf(logfp, "%s: bad crc - orininal crc %4.4x calculated crc %4.4x\n", __FUNCTION__, rxd_crc, crc);#endif return FALSE; }#endif ack_file_pos += *l; return sub_frame_type;}int rx_data(unsigned char *p, int *l){ int sub_frame_type; long pos; /* * fill in the file pointer in case acknowledgement is requested. * the ack file pointer will be updated in the subpacket read routine; * so we need to get it now */ pos = ack_file_pos; /* * receive the right type of frame */ *l = 0; if (receive_32_bit_data) { sub_frame_type = rx_32_data(p, l); } else { sub_frame_type = rx_16_data(p, l); } switch (sub_frame_type) { case TIMEOUT: return TIMEOUT; break; /* * frame continues non-stop */ case ZCRCG: return FRAMEOK; break; /* * frame ends */ case ZCRCE: return ENDOFFRAME; break; /* * frame continues; ZACK expected */ case ZCRCQ: tx_pos_header(ZACK, pos); return FRAMEOK; break; /* * frame ends; ZACK expected */ case ZCRCW: tx_pos_header(ZACK, pos); return ENDOFFRAME; break; } return FALSE;}int rx_nibble(int to){ int c; c = rx(to); if (c == TIMEOUT) { return c; } if (c > '9') { if (c < 'a' || c > 'f') { /* * illegal hex; different than expected. * we might as well time out. */ return TIMEOUT; } c -= 'a' - 10; } else { if (c < '0') { /* * illegal hex; different than expected. * we might as well time out. */ return TIMEOUT; } c -= '0'; } return c;}int rx_hex(int to){ int n1; int n0; n1 = rx_nibble(to); if (n1 == TIMEOUT) { return n1; } n0 = rx_nibble(to); if (n0 == TIMEOUT) { return n0; } return (n1 << 4) | n0;}/* * receive routines for each of the six different styles of header. * each of these leaves rxd_header_len set to 0 if the end result is * not a valid header. */void rx_bin16_header(int to){ int c; int n; unsigned short int crc; unsigned short int rxd_crc;#ifdef DEBUG fprintf(logfp, "rx_bin16_header: rx binary header 16 bits crc\n");#endif crc = 0; for (n = 0; n < 4; n++) { c = rx(to); if (c == TIMEOUT) {#ifdef DEBUG fprintf(logfp, "rx_bin16_header: timeout\n");#endif return; } crc = UPDCRC16(c, crc); rxd_header[n] = c; } crc = UPDCRC16(ZDLE, crc); for (; n < 6; n++) { c = rx(to); if (c == TIMEOUT) {#ifdef DEBUG fprintf(logfp, "rx_bin16_header: timeout\n");#endif return; } rxd_header[n] = c; }#ifdef DEBUG fprintf(logfp, "rxd_header[] = [%2.2x, %2.2x, %2.2x, %2.2x, %2.2x, %2.2x]\n", rxd_header[0], rxd_header[1], rxd_header[2], rxd_header[3], rxd_header[4], rxd_header[5]);#endif rxd_crc = rxd_header[4] << 8; rxd_crc |= rxd_header[5];#ifndef XXX_SKIP_CRC if (rxd_crc != crc) {#ifdef DEBUG fprintf(logfp, "rx_bin16_header: bad crc - orininal crc %4.4x calculated crc %4.4x\n", rxd_crc, crc);#endif return; }#endif rxd_header_len = 5;}void rx_hex_header(int to){ int c; int i; unsigned short int crc = 0; unsigned short int rxd_crc;#ifdef DEBUG fprintf(logfp, "rx_hex_header :...\n");#endif for (i = 0; i < 5; i++) { c = rx_hex(to); if (c == TIMEOUT) { return; } crc = UPDCRC16(c, crc); rxd_header[i] = c; } crc = UPDCRC16(0, crc); crc = UPDCRC16(0, crc); /* * receive the crc */ c = rx_hex(to); if (c == TIMEOUT) { return; } rxd_crc = c << 8; c = rx_hex(to); if (c == TIMEOUT) { return; } rxd_crc |= c; if (rxd_crc == crc) { rxd_header_len = 5; }#ifdef DEBUG else { fprintf(logfp, "bad crc.\n"); }#endif /* * drop the end of line sequence after a hex header */ c = rx(to); if (c == CR) { /* * both are expected with CR */ c = rx(to); }}void rx_bin32_header(int to){ int c; int n; unsigned long crc; unsigned long rxd_crc;#ifdef DEBUG fprintf(logfp, "rx binary header 32 bits crc\n");#endif crc = 0xffffffffL; for (n = 0; n < 5; n++) { c = rx(1000); if (c == TIMEOUT) { return; } crc = UPDCRC32(c, crc); rxd_header[n] = c; } crc = ~crc; rxd_crc = rx(1000); rxd_crc |= rx(1000) << 8; rxd_crc |= rx(1000) << 16; rxd_crc |= rx(1000) << 24;#ifndef XXX_SKIP_CRC if (rxd_crc != crc) {#ifdef DEBUG fprintf(logfp, "rx_bin32_header: bad crc - orininal crc %8.8x calculated crc %8.8x\n", rxd_crc, crc);#endif return; }#endif /* XXX_SKIP_CRC */ rxd_header_len = 5;}/* * receive any style header * if the errors flag is set than whenever an invalid header packet is * received INVHDR will be returned. otherwise we wait for a good header * also; a flag (receive_32_bit_data) will be set to indicate whether data * packets following this header will have 16 or 32 bit data attached. * variable headers are not implemented. */int rx_header_raw(int to, int errors){ int c;#ifdef DEBUG fprintf(logfp, "rx_header_raw...\n");#endif rxd_header_len = 0; do { do { c = rx_raw(to); if (c == TIMEOUT) { return c; } } while (c != ZPAD); c = rx_raw(to); if (c == TIMEOUT) { return c; } if (c == ZPAD) { c = rx_raw(to); if (c == TIMEOUT) { return c; } } /* * spurious ZPAD check */ if (c != ZDLE) {#ifdef DEBUG fprintf(logfp, "rx_read_raw: expected ZDLE; but got %c\n", c);#endif continue; } /* * now read the header style */ c = rx(to); if (c == TIMEOUT) { return c; }#ifdef DEBUG fprintf(logfp, "got header type...to verify it...\n");#endif switch (c) { case ZBIN:#ifdef DEBUG fprintf(logfp, "rx_header_raw: to call rx_bin16_header...\n");#endif rx_bin16_header(to); receive_32_bit_data = FALSE; break; case ZHEX: rx_hex_header(to);#ifdef DEBUG fprintf(logfp, "to call rx_hex_header...\n");#endif receive_32_bit_data = FALSE; break; case ZBIN32: rx_bin32_header(to);#ifdef DEBUG fprintf(logfp, "rx_header_raw: to call rx_bin32_header...\n");#endif receive_32_bit_data = TRUE; break; default: /* * unrecognized header style */#ifdef DEBUG fprintf(logfp, "rx_header_raw: unrecognized header style %c\n", c);#endif if (errors) { return INVHDR; } continue; break; } if (errors && rxd_header_len == 0) { return INVHDR; } } while (rxd_header_len == 0); /* * this appears to have been a valid header. * return its type. */ if (rxd_header[0] == ZDATA) {#ifdef DEBUG fprintf(logfp, "rx_header_raw: got ZDATA header\n");#endif ack_file_pos = rxd_header[ZP0] | (rxd_header[ZP1] << 8) | (rxd_header[ZP2] << 16) | (rxd_header[ZP3] << 24); } if (rxd_header[0] == ZFILE) {#ifdef DEBUG fprintf(logfp, "rx_header_raw: got ZFILE header\n");#endif ack_file_pos = 0l; }#ifdef DEBUG fprintf(logfp, "rx_header_raw: got header type %d\n", rxd_header[0]);#endif return rxd_header[0];}int rx_header(int timeout){ return rx_header_raw(timeout, FALSE);}int rx_header_and_check(int timeout){ int type; while (TRUE) { type = rx_header_raw(timeout, TRUE); if (type != INVHDR) { break; } tx_znak(); } return type;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -