/* receive files */ public static Int32 zrec_files(ref zdef.zfile zf) { byte[] rxbuf = new byte[zdef.RX_BUFFER_SIZE * sizeof(byte)]; Int32 res = -1; zcore.zinit_parameter(); zdef.rt_kprintf("\r\nrz: ready...\r\n"); /* here ready to receive things */ if ((res = zrec_init(ref rxbuf, ref zf)) != 0) { zdef.rt_kprintf("\b\b\breceive init failed\r\n"); return(-1); } res = zrec_file(ref rxbuf, ref zf); if (res == zdef.ZFIN) { return(0); /* if finish session */ } else if (res == zdef.ZCAN) { return(zdef.ZCAN); /* cancel by sender */ } else { zdevice.zsend_can(); return(res); } }
/* send file name and related info */ public static Int32 zsend_file(ref zdef.zfile zf, byte[] buf, UInt16 len) { byte cnt; Int32 res = -1; for (cnt = 0; cnt < 5; cnt++) { zcore.tx_header[zdef.ZF0] = zcore.ZF0_CMD; /* file conversion option */ zcore.tx_header[zdef.ZF1] = zcore.ZF1_CMD; /* file management option */ zcore.tx_header[zdef.ZF2] = (byte)(zcore.ZF3_CMD | ZF2_OP); /* file transfer option */ zcore.tx_header[zdef.ZF3] = zcore.ZF3_CMD; zcore.zsend_bin_header(zdef.ZFILE, zcore.tx_header); zcore.zsend_bin_data(buf, (Int16)len, zdef.ZCRCW); loop: res = zcore.zget_header(ref zcore.rx_header); switch (res) { case zdef.ZRINIT: while ((res = zdevice.zread_line(50)) > 0) { if (res == zdef.ZPAD) { goto loop; } } break; case zdef.ZCAN: case zdef.TIMEOUT: case zdef.ZABORT: case zdef.ZFIN: break; case -1: case zdef.ZNAK: break; case zdef.ZCRC: /* no CRC request */ goto loop; case zdef.ZFERR: case zdef.ZSKIP: break; case zdef.ZRPOS: /* here we want */ zcore.zget_pos(ref zcore.Rxpos); zcore.Txpos = zcore.Rxpos; return(zsend_file_data(ref zf)); default: break; } } return(res); }
/* receive file data,continously, no ack */ public static Int32 zrec_file_data(ref byte[] buf, ref zdef.zfile zf) { Int32 res = -1; more_data: res = zcore.zget_data(ref buf, zdef.RX_BUFFER_SIZE); switch (res) { case zdef.GOTCRCW: /* zack received */ zwrite_file(buf, zcore.Rxcount, zf); zf.bytes_received += zcore.Rxcount; zcore.zput_pos(zf.bytes_received); zdevice.zsend_line(zdef.XON); zcore.zsend_hex_header(zdef.ZACK, zcore.tx_header); return(0); case zdef.GOTCRCQ: zwrite_file(buf, zcore.Rxcount, zf); zf.bytes_received += zcore.Rxcount; zcore.zput_pos(zf.bytes_received); zcore.zsend_hex_header(zdef.ZACK, zcore.tx_header); goto more_data; case zdef.GOTCRCG: zwrite_file(buf, zcore.Rxcount, zf); zf.bytes_received += zcore.Rxcount; goto more_data; case zdef.GOTCRCE: zwrite_file(buf, zcore.Rxcount, zf); zf.bytes_received += zcore.Rxcount; return(0); case zdef.GOTCAN: if (zdef.ZDEBUG) { zdef.rt_kprintf("error code : zdef.ZCAN \r\n"); } return(res); case zdef.TIMEOUT: return(res); case -1: zdevice.zsend_break(zcore.Attn); return(res); default: return(res); } }
/* send files */ public static Int32 zsend_files(zdef.zfile zf) { //char *p,*q; //char *str = "/"; //stat finfo; Int32 res = -1; FileInfo fi; if (zf.fname == null) { zdef.rt_kprintf("\r\nerror: no file to be send.\r\n"); return(res); } ; if ((zf.fs = File.Open(zf.fname, FileMode.Open)) == null) { //zdef.rt_kprintf("\r\ncan not open file:%s\r\n",zf.fname+1); return(res); } fi = new FileInfo(zf.fname); zf.file_end = 0; ++file_cnt; /* extract file name */ System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区 long timeStamp = (long)(fi.LastWriteTime - startTime).TotalSeconds; // 相差秒数 zdevice.Left_sizes += (UInt32)fi.Length; string info = Convert.ToString(fi.Length, 10) + " " + Convert.ToString(timeStamp, 8) + " " + "0 " + "3 " + Convert.ToString(file_cnt, 10) + " " + Convert.ToString(zdevice.Left_sizes, 10); zdevice.Left_sizes -= (UInt32)fi.Length; TX_BUFFER[127] = (byte)((fi.Length + 127) >> 7); TX_BUFFER[126] = (byte)((fi.Length + 127) >> 15); zsend_init(); /* start sending files */ res = zsend_file(ref zf, TX_BUFFER, (UInt16)fi.Length); zsay_bibi(); zf.fs.Close(); return(res); }
/* proccess file infomation */ public static Int32 zget_file_info(byte[] name, ref zdef.zfile zf) { Int32 res = -1; string full_path = ""; FileInfo fi; string data_str = Encoding.Default.GetString(name); string[] data_str_array = data_str.Split('\0'); string[] file_info_array = data_str_array[1].Replace(" ", " ").Split(' '); if (zf.fname == null) /* extract file path */ { full_path = data_str_array[0]; } else { full_path = zf.fname + data_str_array[0]; } zf.fname = full_path; //fi = new FileInfo(full_path); ///* check if is a directory */ //if ((fi.Attributes & FileAttributes.Directory) != 0) //{ // zdevice.zsend_can(); // //zdef.rt_kprintf("\b\b\bcan not open file:%s\r\n",zf.fname+1); // zf.fs.Close(); // return res; //} /* get fullpath && file attributes */ zf.bytes_total = Convert.ToUInt32(file_info_array[0], 10); zf.ctime = Convert.ToUInt32(file_info_array[1], 8); zf.mode = Convert.ToUInt32(file_info_array[2], 8); zf.bytes_received = 0; if ((zf.fs = File.Open(zf.fname, FileMode.Create)) == null) /* create or replace exist file */ { zdevice.zsend_can(); //zdef.rt_kprintf("\b\b\bcan not create file:%s \r\n",zf.fname); return(-1); } return(0); }
/* start zmodem receive proccess */ public static void zr_start(string path) { zdef.zfile zf = new zdef.zfile(); byte[] ch = new byte[1]; byte n; Int32 res = -1; zf.fname = path; res = zrec_files(ref zf); if (res == 0) { //zdef.rt_kprintf("\b\b\bfile: %s \r\n",p); //zdef.rt_kprintf("size: %ld bytes\r\n",zf.bytes_received); zdef.rt_kprintf("receive completed.\r\n"); zf.fs.Close(); } else { //zdef.rt_kprintf("\b\b\bfile: %s \r\n",p); zdef.rt_kprintf("size: 0 bytes\r\n"); zdef.rt_kprintf("receive failed.\r\n"); if (null != zf.fs) { zf.fs.Close(); File.Delete(zf.fname); /* remove this file */ } } /* waiting,clear console buffer */ Thread.Sleep(500); while (true) { n = (byte)zdevice.rt_device_read(0, 0, ref ch, 1); if (n == 0) { break; } } return; }
public static byte ZF2_OP; /* file transfer option */ /* start zmodem send process */ public static void zs_start(string path) { zdef.zfile zf = new zdef.zfile(); Int32 res = 1; zdef.rt_kprintf("\r\nsz: ready...\r\n"); /* here ready to send things */ zf.fname = path; res = zsend_files(zf); if (res == 0) { //zdef.rt_kprintf("\r\nfile: %s \r\nsize: %ld bytes\r\nsend completed.\r\n", // p,zf.bytes_received); } else { //zdef.rt_kprintf("\r\nfile: %s \r\nsize: 0 bytes\r\nsend failed.\r\n",p); } return; }
/* receiver init, wait for ack */ public static Int32 zrec_init(ref byte[] rxbuf, ref zdef.zfile zf) { UInt32 err_cnt = 0; Int32 res = -1; for (;;) { zcore.zput_pos(0); zcore.tx_header[zdef.ZF0] = zcore.ZF0_CMD; zcore.tx_header[zdef.ZF1] = zcore.ZF1_CMD; zcore.tx_header[zdef.ZF2] = zcore.ZF2_CMD; zcore.zsend_hex_header(zdef.ZRINIT, zcore.tx_header); again: res = zcore.zget_header(ref zcore.rx_header); switch (res) { case zdef.ZFILE: zcore.ZF0_CMD = zcore.rx_header[zdef.ZF0]; zcore.ZF1_CMD = zcore.rx_header[zdef.ZF1]; zcore.ZF2_CMD = zcore.rx_header[zdef.ZF2]; zcore.ZF3_CMD = zcore.rx_header[zdef.ZF3]; res = zcore.zget_data(ref rxbuf, zdef.RX_BUFFER_SIZE); if (res == zdef.GOTCRCW) { if ((res = zget_file_info(rxbuf, ref zf)) != 0) { zcore.zsend_hex_header(zdef.ZSKIP, zcore.tx_header); return(res); } return(0);; } zcore.zsend_hex_header(zdef.ZNAK, zcore.tx_header); goto again; case zdef.ZSINIT: if (zcore.zget_data(ref zcore.Attn, zdef.ZATTNLEN) == zdef.GOTCRCW) /* send zack */ { zcore.zsend_hex_header(zdef.ZACK, zcore.tx_header); goto again; } zcore.zsend_hex_header(zdef.ZNAK, zcore.tx_header); /* send znak */ goto again; case zdef.ZRQINIT: continue; case zdef.ZEOF: continue; case zdef.ZCOMPL: goto again; case zdef.ZFIN: /* end file session */ zrec_ack_bibi(); return(res); default: if (++err_cnt > 1000) { return(-1); } continue; } } }
/* write file */ public static Int32 zwrite_file(byte[] buf, UInt16 size, zdef.zfile zf) { zf.fs.Write(buf, 0, size); return(size); }
/* receive file */ public static Int32 zrec_file(ref byte[] rxbuf, ref zdef.zfile zf) { Int32 res = -1; UInt16 err_cnt = 0; do { zcore.zput_pos(zf.bytes_received); zcore.zsend_hex_header(zdef.ZRPOS, zcore.tx_header); again: res = zcore.zget_header(ref zcore.rx_header); switch (res) { case zdef.ZDATA: zcore.zget_pos(ref zcore.Rxpos); if (zcore.Rxpos != zf.bytes_received) { zdevice.zsend_break(zcore.Attn); continue; } err_cnt = 0; res = zrec_file_data(ref rxbuf, ref zf); if (res == -1) { zdevice.zsend_break(zcore.Attn); continue; } else if (res == zdef.GOTCAN) { return(res); } else { goto again; } case zdef.ZRPOS: zcore.zget_pos(ref zcore.Rxpos); continue; case zdef.ZEOF: err_cnt = 0; zcore.zget_pos(ref zcore.Rxpos); if (zcore.Rxpos != zf.bytes_received || zcore.Rxpos != zf.bytes_total) { continue; } return(zrec_init(ref rxbuf, ref zf)); /* resend zdef.ZRINIT packet,ready to receive next file */ case zdef.ZFIN: zrec_ack_bibi(); return(zdef.ZCOMPL); case zdef.ZCAN: if (zdef.ZDEBUG) { zdef.rt_kprintf("error code: sender cancelled \r\n"); } zf.bytes_received = 0; /* throw the received data */ return(res); case zdef.ZSKIP: return(res); case -1: zdevice.zsend_break(zcore.Attn); continue; case zdef.ZNAK: case zdef.TIMEOUT: default: continue; } } while(++err_cnt < 100); return(res); }
/* fill file data to buffer*/ public static UInt16 zfill_buffer(ref zdef.zfile zf, ref byte[] buf, UInt16 size) { return((UInt16)zf.fs.Read(buf, 0, size)); }
/* send the file data */ public static Int32 zsend_file_data(ref zdef.zfile zf) { Int16 cnt; byte cmd; Int32 res = -1; bool is_get_syn1 = false; /* send zdef.ZDATA packet, start to send data */ start_send: zcore.zput_pos(zcore.Txpos); zcore.zsend_bin_header(zdef.ZDATA, zcore.tx_header); do { cnt = (Int16)zfill_buffer(ref zf, ref TX_BUFFER, zdef.RX_BUFFER_SIZE); if (cnt < zdef.RX_BUFFER_SIZE) { cmd = zdef.ZCRCE; } else { cmd = zdef.ZCRCG; } zcore.zsend_bin_data(TX_BUFFER, cnt, cmd); zf.bytes_received = zcore.Txpos += (UInt32)cnt; if (cmd == zdef.ZCRCW) { is_get_syn1 = true; break; } } while (cnt == zdef.RX_BUFFER_SIZE); for (;;) /* get ack and check if send finish */ { if (is_get_syn1) { is_get_syn1 = false; goto get_syn1; } zcore.zput_pos(zcore.Txpos); zcore.zsend_bin_header(zdef.ZEOF, zcore.tx_header); get_syn1: res = zget_sync(); switch (res) { case zdef.ZACK: goto get_syn1; case zdef.ZNAK: continue; case zdef.ZRPOS: /* resend here */ zf.fs.Seek(zcore.Txpos, SeekOrigin.Begin); goto start_send; case zdef.ZRINIT: /* send finish,then begin to send next file */ return(0); case zdef.ZSKIP: case -1: return(res); default: return(res); } } }