402 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			402 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * File      : rz.c
							 | 
						||
| 
								 | 
							
								 * the implemention of receiving files from the remote computers  
							 | 
						||
| 
								 | 
							
								 * through the zmodem protocol.
							 | 
						||
| 
								 | 
							
								 * Change Logs:
							 | 
						||
| 
								 | 
							
								 * Date           Author       Notes
							 | 
						||
| 
								 | 
							
								 * 2011-03-29     itspy       
							 | 
						||
| 
								 | 
							
								 * 2011-12-12     aozima       fixed syntax error.       
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <rtthread.h>
							 | 
						||
| 
								 | 
							
								#include <finsh.h>
							 | 
						||
| 
								 | 
							
								#include <shell.h>
							 | 
						||
| 
								 | 
							
								#include <rtdef.h>
							 | 
						||
| 
								 | 
							
								#include <dfs.h>
							 | 
						||
| 
								 | 
							
								#include <dfs_file.h>
							 | 
						||
| 
								 | 
							
								#include <dfs_posix.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include "zdef.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void zr_start(char *path);
							 | 
						||
| 
								 | 
							
								static rt_err_t zrec_init(rt_uint8_t *rxbuf, struct zfile *zf);
							 | 
						||
| 
								 | 
							
								static rt_err_t zrec_files(struct zfile *zf);
							 | 
						||
| 
								 | 
							
								static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
							 | 
						||
| 
								 | 
							
								static rt_err_t zrec_file_data(rt_uint8_t *buf, struct zfile *zf);;
							 | 
						||
| 
								 | 
							
								static rt_err_t zrec_file(rt_uint8_t *rxbuf, struct zfile *zf);
							 | 
						||
| 
								 | 
							
								static rt_err_t zget_file_info(char *name, struct zfile *zf);
							 | 
						||
| 
								 | 
							
								static rt_err_t zwrite_file(rt_uint8_t *buf, rt_uint16_t size, struct zfile *zf);
							 | 
						||
| 
								 | 
							
								static void zrec_ack_bibi(void);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* start zmodem receive proccess */
							 | 
						||
| 
								 | 
							
								void zr_start(char *path)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct zfile *zf;
							 | 
						||
| 
								 | 
							
								    rt_uint8_t n;
							 | 
						||
| 
								 | 
							
									char ch,*p,*q;
							 | 
						||
| 
								 | 
							
									rt_err_t res = -RT_ERROR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									zf = rt_malloc(sizeof(struct zfile));
							 | 
						||
| 
								 | 
							
									if (zf == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									    rt_kprintf("zf: out of memory\r\n");
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									memset(zf, 0, sizeof(struct zfile));
							 | 
						||
| 
								 | 
							
								    zf->fname = path;
							 | 
						||
| 
								 | 
							
									zf->fd = -1;
							 | 
						||
| 
								 | 
							
									res = zrec_files(zf);   
							 | 
						||
| 
								 | 
							
									p = zf->fname;
							 | 
						||
| 
								 | 
							
									for (;;)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										q = strstr(p,"/");
							 | 
						||
| 
								 | 
							
										if (q == RT_NULL)  break;
							 | 
						||
| 
								 | 
							
										p = q+1;
							 | 
						||
| 
								 | 
							
									}	   
							 | 
						||
| 
								 | 
							
								    if (res == RT_EOK)
							 | 
						||
| 
								 | 
							
								    {		  
							 | 
						||
| 
								 | 
							
								        rt_kprintf("\b\b\bfile: %s                           \r\n",p);
							 | 
						||
| 
								 | 
							
										rt_kprintf("size: %ld bytes\r\n",zf->bytes_received);
							 | 
						||
| 
								 | 
							
										rt_kprintf("receive completed.\r\n");
							 | 
						||
| 
								 | 
							
										close(zf->fd);
							 | 
						||
| 
								 | 
							
										rt_free(zf->fname);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        rt_kprintf("\b\b\bfile: %s                           \r\n",p);
							 | 
						||
| 
								 | 
							
										rt_kprintf("size: 0 bytes\r\n");
							 | 
						||
| 
								 | 
							
										rt_kprintf("receive failed.\r\n");
							 | 
						||
| 
								 | 
							
										if (zf->fd >= 0)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
									        close(zf->fd);
							 | 
						||
| 
								 | 
							
									        unlink(zf->fname);    /* remove this file */ 
							 | 
						||
| 
								 | 
							
											rt_free(zf->fname);
							 | 
						||
| 
								 | 
							
										}	
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
									rt_free(zf);
							 | 
						||
| 
								 | 
							
									/* waiting,clear console buffer */
							 | 
						||
| 
								 | 
							
									rt_thread_delay(RT_TICK_PER_SECOND/2);
							 | 
						||
| 
								 | 
							
									while(1)                     
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									   n=rt_device_read(shell->device, 0, &ch, 1);
							 | 
						||
| 
								 | 
							
									   if (n == 0) break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return ;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* 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;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* receive files */
							 | 
						||
| 
								 | 
							
								static rt_err_t zrec_files(struct zfile *zf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									rt_uint8_t *rxbuf;
							 | 
						||
| 
								 | 
							
									rt_err_t res = -RT_ERROR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									zinit_parameter();
							 | 
						||
| 
								 | 
							
									rxbuf = rt_malloc(RX_BUFFER_SIZE*sizeof(rt_uint8_t));
							 | 
						||
| 
								 | 
							
									if (rxbuf == RT_NULL)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										 rt_kprintf("rxbuf: out of memory\r\n");
							 | 
						||
| 
								 | 
							
										 return -RT_ERROR;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									rt_kprintf("\r\nrz: ready...\r\n");	   /* here ready to receive things */
							 | 
						||
| 
								 | 
							
									if ((res = zrec_init(rxbuf,zf))!= RT_EOK)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									     rt_kprintf("\b\b\breceive init failed\r\n");
							 | 
						||
| 
								 | 
							
										 rt_free(rxbuf);
							 | 
						||
| 
								 | 
							
										 return -RT_ERROR;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									res = zrec_file(rxbuf,zf);
							 | 
						||
| 
								 | 
							
									if (res == ZFIN)
							 | 
						||
| 
								 | 
							
									{	
							 | 
						||
| 
								 | 
							
									    rt_free(rxbuf); 
							 | 
						||
| 
								 | 
							
									    return RT_EOK;	     /* if finish session */
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if (res == ZCAN)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
								        rt_free(rxbuf);
							 | 
						||
| 
								 | 
							
										return ZCAN;        /* cancel by sender */
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									   zsend_can();
							 | 
						||
| 
								 | 
							
									   rt_free(rxbuf);
							 | 
						||
| 
								 | 
							
									   return res;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/* 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:
							 | 
						||
| 
								 | 
							
								#ifdef 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;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* proccess file infomation */
							 | 
						||
| 
								 | 
							
								static rt_err_t zget_file_info(char *name, struct zfile *zf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									char *p;
							 | 
						||
| 
								 | 
							
									char *full_path,*ptr;
							 | 
						||
| 
								 | 
							
									rt_uint16_t i,len;
							 | 
						||
| 
								 | 
							
									rt_err_t res  = -RT_ERROR;
							 | 
						||
| 
								 | 
							
									struct statfs buf;
							 | 
						||
| 
								 | 
							
									struct stat finfo;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (zf->fname == RT_NULL) 		       /* extract file path  */
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
									    len = strlen(name)+2; 
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
									    len = strlen(zf->fname)+strlen(name)+2; 
							 | 
						||
| 
								 | 
							
								    full_path = rt_malloc(len);
							 | 
						||
| 
								 | 
							
								    if (full_path == RT_NULL)		 
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									    zsend_can();
							 | 
						||
| 
								 | 
							
										rt_kprintf("\b\b\bfull_path: out of memory\n");
							 | 
						||
| 
								 | 
							
										rt_free(full_path);
							 | 
						||
| 
								 | 
							
										return -RT_ERROR;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									memset(full_path,0,len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i=0,ptr=zf->fname;i<len-strlen(name)-2;i++)
							 | 
						||
| 
								 | 
							
										 full_path[i] = *ptr++;
							 | 
						||
| 
								 | 
							
								    full_path[len-strlen(name)-2] = '/';
							 | 
						||
| 
								 | 
							
									/* check if is a directory */
							 | 
						||
| 
								 | 
							
									if ((zf->fd=open(full_path, DFS_O_DIRECTORY,0)) < 0)	 
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									    zsend_can();
							 | 
						||
| 
								 | 
							
									    rt_kprintf("\b\b\bcan not open file:%s\r\n",zf->fname+1);
							 | 
						||
| 
								 | 
							
										close(zf->fd);
							 | 
						||
| 
								 | 
							
										zf->fd = -1;
							 | 
						||
| 
								 | 
							
										rt_free(full_path);
							 | 
						||
| 
								 | 
							
									    return res;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									fstat(zf->fd, &finfo);
							 | 
						||
| 
								 | 
							
									if ((finfo.st_mode&S_IFDIR) != S_IFDIR)           
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										close(zf->fd);
							 | 
						||
| 
								 | 
							
										zf->fd = -1;
							 | 
						||
| 
								 | 
							
										return res;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									close(zf->fd);	   
							 | 
						||
| 
								 | 
							
									/* get fullpath && file attributes */
							 | 
						||
| 
								 | 
							
								    strcat(full_path,name);
							 | 
						||
| 
								 | 
							
								    zf->fname = full_path;
							 | 
						||
| 
								 | 
							
									p = strlen(name)+name+1;	   
							 | 
						||
| 
								 | 
							
									sscanf((const char *)p, "%ld%lo%o", &zf->bytes_total,&zf->ctime,&zf->mode);
							 | 
						||
| 
								 | 
							
								#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
							 | 
						||
| 
								 | 
							
									dfs_statfs(working_directory,&buf);
							 | 
						||
| 
								 | 
							
									if (zf->bytes_total > (buf.f_blocks * buf.f_bfree))
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									    zsend_can();
							 | 
						||
| 
								 | 
							
									    rt_kprintf("\b\b\bnot enough disk space\r\n");
							 | 
						||
| 
								 | 
							
										zf->fd = -1;
							 | 
						||
| 
								 | 
							
										rt_free(full_path);
							 | 
						||
| 
								 | 
							
										return -RT_ERROR;  
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    buf = buf;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									zf->bytes_received   = 0L;
							 | 
						||
| 
								 | 
							
									if ((zf->fd = open(zf->fname,DFS_O_CREAT|DFS_O_WRONLY,0)) < 0)	 /* create or replace exist file */
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									    zsend_can();
							 | 
						||
| 
								 | 
							
									    rt_kprintf("\b\b\bcan not create file:%s \r\n",zf->fname);	
							 | 
						||
| 
								 | 
							
										return -RT_ERROR;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return RT_EOK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* 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;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* write file */
							 | 
						||
| 
								 | 
							
								static rt_err_t zwrite_file(rt_uint8_t *buf,rt_uint16_t size, struct zfile *zf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return (write(zf->fd,buf,size));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ack bibi */
							 | 
						||
| 
								 | 
							
								static void zrec_ack_bibi(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									rt_uint8_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									zput_pos(0L);
							 | 
						||
| 
								 | 
							
									for (i=0;i<3;i++) 
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										zsend_hex_header(ZFIN, tx_header);
							 | 
						||
| 
								 | 
							
										switch (zread_line(100)) 
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
										case 'O':
							 | 
						||
| 
								 | 
							
											 zread_line(1);	
							 | 
						||
| 
								 | 
							
											 return;
							 | 
						||
| 
								 | 
							
										case RCDO:
							 | 
						||
| 
								 | 
							
											 return;
							 | 
						||
| 
								 | 
							
										case TIMEOUT:
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											 break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* end of rz.c */
							 |