/* 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; }
/* receiver init, wait for ack */ static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf) { rt_uint8_t err_cnt = 0; rt_err_t res = -RT_ERROR; for (;;) { zput_pos(0L); tx_header[ZF0] = ZF0_CMD; tx_header[ZF1] = ZF1_CMD; tx_header[ZF2] = ZF2_CMD; zsend_hex_header(ZRINIT, tx_header); again: res = zget_header(rx_header); switch(res) { case ZFILE: ZF0_CMD = rx_header[ZF0]; ZF1_CMD = rx_header[ZF1]; ZF2_CMD = rx_header[ZF2]; ZF3_CMD = rx_header[ZF3]; res = zget_data(rxbuf, RX_BUFFER_SIZE); if (res == GOTCRCW) { if ((res =zget_file_info((char*)rxbuf,zf))!= RT_EOK) { zsend_hex_header(ZSKIP, tx_header); return (res); } return RT_EOK;; } zsend_hex_header(ZNAK, tx_header); goto again; case ZSINIT: if (zget_data((rt_uint8_t*)Attn, ZATTNLEN) == GOTCRCW) /* send zack */ { zsend_hex_header(ZACK, tx_header); goto again; } zsend_hex_header(ZNAK, tx_header); /* send znak */ goto again; case ZRQINIT: continue; case ZEOF: continue; case ZCOMPL: goto again; case ZFIN: /* end file session */ zrec_ack_bibi(); return res; default: if (++err_cnt >1000) return -RT_ERROR; continue; } } }