///// <summary> ///// Function to get a file. Make sure you unsuscribe DataReceived events from SerialPort before calling this function! ///// </summary> ///// <param name="FileName">FileName on sender system</param> ///// <param name="timeOutS">Break transfert before after specified number of seconds.</param> ///// <returns>Return a Memory Stream. It's up to you to write it to a file or deserialize it, or whatever...</returns> public MemoryStream ZModemTransfert(string fileName, int timeOutS) { state = TransfertState.Initializing; //Init of variables to allow multiple download with a simple object. HeaderInProgress = false; FrameInProgress = false; ErrorInHeader = false; ErrorOfTransmission = false; NeedAttnSeq = false; EndOfFrame = false; ZackRequested = false; NextByteHeader = false; SessionInit = false; SessionClose = false; ErrorInData = false; StopThread = false; Console.WriteLine(""); Console.WriteLine("Start transfert of " + fileName + "..."); receivedBytes = new Queue <byte>(); lockAcces = new object(); if (!t.IsAlive) { t = new Thread(new ThreadStart(DataReceived)); } t.Start(); portserie.DataReceived += new SerialDataReceivedEventHandler(portserie_DataReceived); msZfile = new MemoryStream(); msfile = new MemoryStream(); sdata = new SessionReceiver(); hdata = new HeaderReceiver(); SendCommand("sz " + fileName); state = TransfertState.Initialized; DateTime start = DateTime.Now; while (!SessionClose) { Thread.Sleep(50); if (timeOutS > 0) { if ((DateTime.Now - start).TotalSeconds > timeOutS) { Console.WriteLine("Timeout for this operation!"); portserie.DataReceived -= new SerialDataReceivedEventHandler(portserie_DataReceived); NeedAttnSeq = true; StopThread = true; t.Join(); Thread.Sleep(1000); ThreadRequestSerialPort = true; lock (lockAcces) { portserie.DiscardInBuffer(); SendCommand(SessionAbortSeq); portserie.DiscardInBuffer(); return(msfile); } } } } StopThread = true; portserie.DataReceived -= new SerialDataReceivedEventHandler(portserie_DataReceived); GC.Collect(); state = TransfertState.Ended; return(msfile); }
void DataReceived() { Byte b; DateTime StartReceiveHeader = DateTime.Now; //Console.WriteLine("Treatment Thread Starts!"); while (!StopThread) { while (receivedBytes.Count > 0) { if (StopThread) { return; } else { lock (lockAcces) { b = receivedBytes.Dequeue(); } } //Console.Write("Buffer:" + portserie.BytesToRead + "\r"); if (FrameInProgress) { bdata.ReceivedNewByteInDataFrame(b, ref EndOfFrame, ref ZackRequested, ref ErrorOfTransmission, ref NeedAttnSeq, ref NextByteHeader); if (ErrorOfTransmission) { state = TransfertState.Error; if (NeedAttnSeq) { Console.WriteLine("NeedAttn"); } Console.WriteLine("CRC error detected, long pause (to make sure that no data remains in buffer), then try to resume"); ThreadRequestSerialPort = true; Thread.Sleep(0); portserie.DiscardOutBuffer(); portserie.DiscardInBuffer(); Thread.Sleep(500); receivedBytes.Clear(); SendCommand(BuildZRPOSFrame((int)msfile.Position)); Thread.Sleep(0); EndOfFrame = true; FrameInProgress = false; NextByteHeader = true; continue; } else if (EndOfFrame) { FrameInProgress = false; //HeaderInProgress = false; if (hdata.type == HeaderType.ZFILE) { receivedBytes.Clear(); //Console.WriteLine("ZFILE FRAME: "); //Byte[] buf = msZfile.ToArray(); //for (int i = 0; i < buf.Length; i++) // Console.Write((char)buf[i]); //Console.WriteLine(""); zfileInfo = new ZFileInfo(hdata, msZfile); if (FileInfoEvent != null) { FileInfoEvent(null, new FileInfoEventArgs(zfileInfo.fileName, zfileInfo.size)); } SendCommand(BuildZRPOSFrame((int)msfile.Position)); continue; } else if (ZackRequested) { SendCommand(BuildZACKFrame((int)msfile.Position)); continue; } else if (hdata.type == HeaderType.ZDATA) { if (zfileInfo.size != msfile.Length) { Console.WriteLine("File not fully transfered, " + msfile.Length.ToString() + " / " + zfileInfo.size + "Bytes transfered"); } else { Console.WriteLine("File successfully transfered, " + msfile.Length.ToString() + " Bytes transfered!"); } //Thread.Sleep(200); continue; } else { Console.WriteLine("An unattempted header had been received: " + hdata.type.ToString()); } continue; } else if (ZackRequested) { SendCommand(BuildZACKFrame((int)msfile.Position)); continue; } else { continue; } } else if (HeaderInProgress) { hdata.ReceivedNewByteInHeader(b, ref ErrorInHeader, ref HeaderInProgress); if (ErrorInHeader) { state = TransfertState.Error; receivedBytes.Clear(); portserie.DiscardOutBuffer(); SendCommand(BuildZNACKFrame()); HeaderInProgress = false; continue; } else if (HeaderInProgress) { continue; } else { //Analyze header and answer accordingly if (hdata.type == HeaderType.ZRQINIT) { state = TransfertState.Initialized; portserie.DiscardOutBuffer(); SendCommand(BuildZRINITFrame(ZRINIT_Header_ZF0.CANBREAK, 1024)); } else if (hdata.type == HeaderType.ZFILE) { bdata = new BynaryDataSubPacketReceiver(ref msZfile); FrameInProgress = true; } else if (hdata.type == HeaderType.ZDATA) { if (hdata.GetIntArg() != msfile.Position) { throw new Exception("Position Error: Stream is not starting from the right place!"); } state = TransfertState.Transfering; bdata = new BynaryDataSubPacketReceiver(ref msfile); bdata.BytesTransferedEvent += new BynaryDataSubPacketReceiver.BytesTransferedHandler(bdata_BytesTransferedEvent); FrameInProgress = true; } else if (hdata.type == HeaderType.ZEOF) { Console.Write("End of file... "); state = TransfertState.Ended; portserie.DiscardOutBuffer(); HeaderInProgress = false; SendCommand(BuildZRINITFrame(ZRINIT_Header_ZF0.CANBREAK, 1024)); } else if (hdata.type == HeaderType.ZFIN) { Console.Write("End of File List..."); state = TransfertState.ClosingSession; SendCommand(BuildZFINFrame()); } else { throw new Exception("Unknow case??"); } continue; } } else { sdata.ReceivedNewByte(b, ref SessionInit, ref SessionClose, ref HeaderInProgress, ref ErrorInData); if (ErrorInData) { portserie.DiscardInBuffer(); portserie.DiscardOutBuffer(); receivedBytes.Clear(); Thread.Sleep(100); SendCommand(""); ErrorInData = false; } else if (HeaderInProgress) { hdata = new HeaderReceiver(); StartReceiveHeader = DateTime.Now; } else if (NextByteHeader) { Console.WriteLine("This byte should have been * !!"); NeedAttnSeq = true; Thread.Sleep(0); Thread.Sleep(100); portserie.DiscardInBuffer(); receivedBytes.Clear(); SendCommand(ZModem.EndOfSession); } else if (SessionClose) { return; } continue; } } if (HeaderInProgress) { if ((DateTime.Now - StartReceiveHeader).TotalMilliseconds > 500) { Console.WriteLine("Too much time without an header!"); NeedAttnSeq = true; ThreadRequestSerialPort = true; portserie.DiscardOutBuffer(); portserie.DiscardInBuffer(); receivedBytes.Clear(); Thread.Sleep(500); SendCommand(BuildZRPOSFrame((int)msfile.Position)); HeaderInProgress = false; } } else { Thread.Sleep(0); } } //Console.WriteLine("Treatment Thread Stops!"); }