/* 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; }
/* send cancel string to get the other end to shut up */ void zsend_can(void) { static char cmd[] = {24,24,24,24,24,24,24,24,24,24,0}; zsend_break(cmd); rt_kprintf("\x0d"); Line_left=0; /* clear Line_left */ return; }
/* receive file data,continously, no ack */ static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf) { rt_err_t res = -RT_ERROR; more_data: res = zget_data(buf,RX_BUFFER_SIZE); switch(res) { case GOTCRCW: /* zack received */ zwrite_file(buf,Rxcount,zf); zf->bytes_received += Rxcount; zput_pos(zf->bytes_received); zsend_line(XON); zsend_hex_header(ZACK, tx_header); return RT_EOK; case GOTCRCQ: zwrite_file(buf,Rxcount,zf); zf->bytes_received += Rxcount; zput_pos(zf->bytes_received); zsend_hex_header(ZACK, tx_header); goto more_data; case GOTCRCG: zwrite_file(buf,Rxcount,zf); zf->bytes_received += Rxcount; goto more_data; case GOTCRCE: zwrite_file(buf,Rxcount,zf); zf->bytes_received += Rxcount; return RT_EOK; case GOTCAN: #ifdef ZDEBUG rt_kprintf("error code : ZCAN \r\n"); #endif return res; case TIMEOUT: return res; case -RT_ERROR: zsend_break(Attn); return res; default: return res; } }