📄 zmtx-new.c
字号:
tx_32_data(sub_frame_type,p,l); } else { tx_16_data(sub_frame_type,p,l); } if (sub_frame_type == ZCRCW) { tx_raw(XON); } tx_flush();}voidtx_pos_header(int type,long pos) { char header[5]; header[0] = type; header[ZP0] = pos & 0xff; header[ZP1] = (pos >> 8) & 0xff; header[ZP2] = (pos >> 16) & 0xff; header[ZP3] = (pos >> 24) & 0xff; tx_hex_header(header);}voidtx_znak(){ fprintf(stderr,"tx_znak\n"); tx_pos_header(ZNAK,ack_file_pos);}voidtx_zskip(){ tx_pos_header(ZSKIP,0L);}/* * receive any style header within timeout milliseconds */voidalrm(int a){ signal(SIGALRM,SIG_IGN);}intrx_poll(){ struct timeval t; fd_set f; unsigned char c; t.tv_sec = 0; t.tv_usec = 0; FD_ZERO(&f); FD_SET(0,&f); if (select(1,&f,NULL,NULL,&t)) { return 1; } return 0;}unsigned char inputbuffer[1024];int n_in_inputbuffer = 0;int inputbuffer_index;/* * rx_raw ; receive a single byte from the line. * reads as many are available and then processes them one at a time * check the data stream for 5 consecutive CAN characters; * and if you see them abort. this saves a lot of clutter in * the rest of the code; even though it is a very strange place * for an exit. (but that was wat session abort was all about.) */inlineintrx_raw(int to){ int n; unsigned char c; static int n_cans = 0; if (n_in_inputbuffer == 0) { /* * change the timeout into seconds; minimum is 1 */ to /= 1000; if (to == 0) { to++; } /* * setup an alarm in case io takes too long */ signal(SIGALRM,alrm); to /= 1000; if (to == 0) { to = 2; } alarm(to); n_in_inputbuffer = read(0,inputbuffer,1024); if (n_in_inputbuffer <= 0) { n_in_inputbuffer = 0; } /* * cancel the alarm in case it did not go off yet */ signal(SIGALRM,SIG_IGN); if (n_in_inputbuffer < 0 && (errno != 0 && errno != EINTR)) { fprintf(stderr,"zmdm : fatal error reading device\n"); exit(1); } if (n_in_inputbuffer == 0) { return TIMEOUT; } inputbuffer_index = 0; } c = inputbuffer[inputbuffer_index++]; n_in_inputbuffer--; if (c == CAN) { n_cans++; if (n_cans == 5) { /* * the other side is serious about this. just shut up; * clean up and exit. */ cleanup(); exit(CAN); } } else { n_cans = 0; } return c;}/* * rx; receive a single byte undoing any escaping at the * sending site. this bit looks like a mess. sorry for that * but there seems to be no other way without incurring a lot * of overhead. at least like this the path for a normal character * is relatively short. */inlineintrx(int to){ int c; /* * outer loop for ever so for sure something valid * will come in; a timeout will occur or a session abort * will be received. */ while (TRUE) { /* * fake do loop so we may continue * in case a character should be dropped. */ do { c = rx_raw(to); if (c == TIMEOUT) { return c; } switch (c) { case ZDLE: break; case 0x11: case 0x91: case 0x13: case 0x93: continue; break; default: /* * if all control characters should be escaped and * this one wasnt then its spurious and should be dropped. */ if (escape_all_control_characters && (c & 0x60) == 0) { continue; } /* * normal character; return it. */ 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 */intrx_32_data(unsigned char * p,int * l){ int c; unsigned long rxd_crc; unsigned long crc; int sub_frame_type;#ifdef DEBUG fprintf(stderr,"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; if (rxd_crc != crc) { return FALSE; } ack_file_pos += *l; return sub_frame_type;}intrx_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(stderr,"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); if (rxd_crc != crc) { return FALSE; } ack_file_pos += *l; return sub_frame_type;}intrx_data(unsigned char * p, int * l){ unsigned char zack_header[] = { ZACK, 0, 0, 0, 0 }; 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;}inlineintrx_nibble(int to) { int c; c = rx(to); if (c == TIMEOUT) { return c;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -