/* receive file */ static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf) { rt_err_t res = - RT_ERROR; rt_uint16_t err_cnt = 0; do { zput_pos(zf->bytes_received); zsend_hex_header(ZRPOS, tx_header); again: res = zget_header(rx_header); switch (res) { case ZDATA: zget_pos(Rxpos); if (Rxpos != zf->bytes_received) { zsend_break(Attn); continue; } err_cnt = 0; res = zrec_file_data(rxbuf,zf); if (res == -RT_ERROR) { zsend_break(Attn); continue; } else if (res == GOTCAN) return res; else goto again; case ZRPOS: zget_pos(Rxpos); continue; case ZEOF: err_cnt = 0; zget_pos(Rxpos); if (Rxpos != zf->bytes_received || Rxpos != zf->bytes_total) { continue; } return (zrec_init(rxbuf,zf)); /* resend ZRINIT packet,ready to receive next file */ case ZFIN: zrec_ack_bibi(); return ZCOMPL; case ZCAN: #if 1==ZDEBUG rt_kprintf("error code: sender cancelled \r\n"); #endif zf->bytes_received = 0L; /* throw the received data */ return res; case ZSKIP: return res; case -RT_ERROR: zsend_break(Attn); continue; case ZNAK: case TIMEOUT: default: continue; } } while(++err_cnt < 100); return res; }
/* wait sync(ack) from the receiver */ static rt_err_t zget_sync(void) { rt_err_t res = -RT_ERROR; for (;;) { res = zget_header(rx_header); switch (res) { case ZCAN: case ZABORT: case ZFIN: case TIMEOUT: return -RT_ERROR; case ZRPOS: /* get pos, need to resend */ zget_pos(Rxpos); Txpos = Rxpos; return res; case ZACK: return res; case ZRINIT: /* get ZRINIT indicate that the prev file send completed */ return res; case ZSKIP: return res; case -RT_ERROR: default: zsend_bin_header(ZNAK, tx_header); continue; } } }
/* send file name and related info */ static rt_err_t zsend_file(struct zfile *zf, rt_uint8_t *buf, rt_uint16_t len) { rt_uint8_t cnt; rt_err_t res = -RT_ERROR; for (cnt=0;cnt<5;cnt++) { tx_header[ZF0] = ZF0_CMD; /* file conversion option */ tx_header[ZF1] = ZF1_CMD; /* file management option */ tx_header[ZF2] = (ZF3_CMD|ZF2_OP); /* file transfer option */ tx_header[ZF3] = ZF3_CMD; zsend_bin_header(ZFILE, tx_header); zsend_bin_data(buf, len, ZCRCW); loop: res = zget_header(rx_header); switch (res) { case ZRINIT: while ((res = zread_line(50)) > 0) { if (res == ZPAD) { goto loop; } } break; case ZCAN: case TIMEOUT: case ZABORT: case ZFIN: break; case -RT_ERROR: case ZNAK: break; case ZCRC: /* no CRC request */ goto loop; case ZFERR: case ZSKIP: break; case ZRPOS: /* here we want */ zget_pos(Rxpos); Txpos = Rxpos; return(zsend_file_data(zf)); default: break; } } return res; }