public IAsyncResult BeginProcess(ATFrame frame, bool waitResponse, int timeout, AsyncCallback callback, Object state) { lock (this.syncRoot) { lock (this.waitingLock) { this.waitingEcho = this.echoEnabled; this.waitingResponse = waitResponse; this.waitingTimeout = Environment.TickCount + timeout; this.waitingCommand = frame.Command; this.waitingCommandType = frame.CommandType; this.waitingCallback = callback; this.waitingAsyncResult = WaitingAsyncResult.GetInstance(); this.waitingAsyncResult.AsyncState = state; } try { this.sendingLength = frame.GetBytes(this.sendingBuffer, 0); this.stream.Write(this.sendingBuffer, 0, this.sendingLength); #if (DEBUG) Debug.Print("Sent frame > "); Debug.Print(new string(ATParser.Bytes2Chars(this.sendingBuffer, 0, this.sendingLength))); #endif return(this.waitingAsyncResult); } catch { lock (this.waitingLock) { this.waitingEcho = false; this.waitingResponse = false; } throw new ATModemException(ATModemError.Generic); } } }
private void ReceiverThreadRun() { try { while (!this.closed) { readBytes = this.stream.Read(this.receivingBuffer, this.receivingBufferIndex + this.receivingBufferCount, receivingBufferSize - this.receivingBufferIndex - this.receivingBufferCount); if (readBytes > 0) { this.receivingBufferCount += readBytes; #if (DEBUG) Debug.Print("ReadBuffer > " + readBytes); Debug.Print(new string(ATParser.Bytes2Chars(this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount))); #endif while (this.receivingBufferCount > 0) { lock (this.waitingLock) { this.parserResult = null; //Verifico se sono in attesa del comando inviato. if (this.waitingEcho) { //Verifico se è scaduto il timeout di attesa. if (Environment.TickCount - this.waitingTimeout > 0) { this.waitingEcho = false; } else { //Cerco il comando inviato. this.frameIndex = ATParser.IndexOfSequence(this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount, this.sendingBuffer, 0, this.sendingLength, true); //Verifico se ho trovato il comando inviato. if (this.frameIndex != -1) { this.waitingEcho = false; this.waitingEchoEvent.Set(); //Cancello il contenuto del buffer relativo al comando inviato. movingBytes = this.receivingBufferIndex + this.receivingBufferCount - this.frameIndex - this.sendingLength; if (movingBytes > 0) { Array.Copy(this.receivingBuffer, this.receivingBufferIndex + this.receivingBufferCount - movingBytes, this.receivingBuffer, this.frameIndex, movingBytes); } this.receivingBufferCount -= this.sendingLength; } } } //Verifico se sono in attesa di una risposta attesa. if (this.receivingBufferCount > 0 && this.waitingResponse && !this.waitingEcho) { //Verifico se è scaduto il timeout di attesa. if (Environment.TickCount - this.waitingTimeout > 0) { this.waitingResponse = false; //Verifico se bisogna invocare una callback. if (this.waitingCallback != null) { this.waitingAsyncResult.AsyncException = new ATModemException(ATModemError.Timeout); this.waitingCallback(this.waitingAsyncResult); } } else { //Eseguo il parse della risposta attesa. this.parserResult = this.parser.ParseResponse(this.waitingCommand, this.waitingCommandType, this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount); if (this.parserResult != null && parserResult.Success) { #if (DEBUG) Debug.Print("ParserResult.Success > " + this.parserResult.Command); #endif this.dataLength = this.parserResult.DataLength; this.dataStream = this.dataLength > 0 ? ATResponseDataStream.GetInstance(this.dataLength) : null; //Notifico la ricezione della risposta attesa. this.waitingResponse = false; this.waitingFrame = ATFrame.GetInstance(parserResult.Command, parserResult.CommandType, this.dataStream, parserResult.Unsolicited, parserResult.Result, parserResult.OutParameters); this.waitingResponseEvent.Set(); //Verifico se bisogna invocare una callback. if (this.waitingCallback != null) { this.waitingCallback(this.waitingAsyncResult); } } } } if (this.receivingBufferCount > 0 && (this.parserResult == null || !parserResult.Success)) { //Eseguo il parse della risposta non attesa. this.parserResult = this.parser.ParseUnsolicitedResponse(this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount); if (this.parserResult != null && parserResult.Success) { #if (DEBUG) Debug.Print("ParserUnsolicitedResult.Success > " + this.parserResult.Command); #endif this.dataLength = this.parserResult.DataLength; this.dataStream = this.dataLength > 0 ? ATResponseDataStream.GetInstance(this.dataLength) : null; //Notifico la ricezione della risposta non attesa. if (this.FrameReceived != null) { this.FrameReceived(this, ATModemFrameEventArgs.GetInstance(ATFrame.GetInstance(parserResult.Command, parserResult.CommandType, this.dataStream, parserResult.Unsolicited, parserResult.Result, parserResult.OutParameters))); } } } if (this.parserResult != null && parserResult.Success) { this.frameIndex = this.parserResult.Index; this.frameLength = this.parserResult.Length; if (this.dataLength > 0) { this.dataIndex = this.frameIndex + this.frameLength; this.dataCount = 0; this.readDataLength = this.receivingBufferIndex + this.receivingBufferCount - this.dataIndex; if (this.readDataLength > this.dataLength) { this.readDataLength = this.dataLength; } if (this.readDataLength > 0) { this.dataCount += this.readDataLength; #if (DEBUG) Debug.Print("ReadData > " + this.readDataLength + "/" + this.dataCount); //Debug.Print(new string(ATParser.Bytes2Chars(this.receivingBuffer, this.dataIndex, this.readDataLength))); #endif this.dataStream.WriteBuffer(this.receivingBuffer, this.dataIndex, this.readDataLength); } //Check if read bytes from the serial port. if (this.dataCount < this.dataLength) { while (this.dataCount < this.dataLength) { this.dataTicks = Environment.TickCount; readBytes = this.stream.Read(this.receivingBuffer, this.frameIndex, receivingBufferSize - this.frameIndex); this.dataTime = Environment.TickCount - this.dataTicks; #if (DEBUG) Debug.Print("ReadDataBuffer > " + readBytes + "/" + this.dataTime); //Debug.Print(new string(ATParser.Bytes2Chars(this.receivingBuffer, this.frameIndex, readBytes))); #endif lock (this.waitingLock) { //Verifico se sono in attesa di una risposta o se è scaduto il data timeout. if (this.dataTime > defaultDataTimeout) { this.dataStream.Close(); this.readDataLength = 0; break; } } this.readDataLength = this.dataLength - this.dataCount; if (this.readDataLength > readBytes) { this.readDataLength = readBytes; } this.dataCount += this.readDataLength; #if (DEBUG) Debug.Print("ReadData > " + this.readDataLength + "/" + this.dataCount); //Debug.Print(new string(ATParser.Bytes2Chars(this.receivingBuffer, this.frameIndex, this.readDataLength))); #endif this.dataStream.WriteBuffer(this.receivingBuffer, this.frameIndex, this.readDataLength); } this.receivingBufferCount += (readBytes - this.frameLength); this.readDataLength -= this.frameLength; } } else { this.readDataLength = 0; } //Cancello il contenuto del buffer relativo alla risposta e ai dati. movingBytes = this.receivingBufferIndex + this.receivingBufferCount - this.frameIndex - this.frameLength - this.readDataLength; if (movingBytes > 0) { Array.Copy(this.receivingBuffer, this.receivingBufferIndex + this.receivingBufferCount - movingBytes, this.receivingBuffer, this.frameIndex, movingBytes); } this.receivingBufferCount -= (this.frameLength + this.readDataLength); } else { #if (DEBUG) Debug.Print("ResponseBuffer > " + this.receivingBufferCount); Debug.Print(new string(ATParser.Bytes2Chars(this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount))); #endif if (this.receivingBufferCount == receivingBufferSize) { //Cancello il contenuto del buffer. this.receivingBufferIndex = 0; this.receivingBufferCount = 0; } if (!this.waitingResponse) { //Cerco il primo delimitatore. firstDelimiterIndex = this.parser.IndexOfDelimitor(this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount, true); if (firstDelimiterIndex != -1) { secondDelimiterIndex = firstDelimiterIndex + this.parser.LengthOfDelimitor(); //Cerco il secondo delimitatore. secondDelimiterIndex = this.parser.IndexOfDelimitor(this.receivingBuffer, secondDelimiterIndex, this.receivingBufferCount + this.receivingBufferIndex - secondDelimiterIndex, true); if (secondDelimiterIndex != -1) { if (firstDelimiterIndex == this.receivingBufferIndex) { firstDelimiterIndex += this.parser.LengthOfDelimitor(); } //Cancello il contenuto del buffer fino al primo delimitatore. this.receivingBufferCount -= (firstDelimiterIndex - this.receivingBufferIndex); this.receivingBufferIndex = firstDelimiterIndex; //Continuo l'elaborazione del buffer. continue; } } } //Forzo il caricamento del buffer per evitare cicli infiniti. break; } } } //Verifico lo stato del buffer. if (this.receivingBufferCount == 0) { this.receivingBufferIndex = 0; } else if (this.receivingBufferIndex + this.receivingBufferCount == receivingBufferSize) { if (this.receivingBufferIndex == 0) { throw new OutOfMemoryException(); } Array.Copy(this.receivingBuffer, this.receivingBufferIndex, this.receivingBuffer, 0, this.receivingBufferCount); this.receivingBufferIndex = 0; } } } } catch (Exception exception) { Debug.Print("ExceptionResponseBuffer > " + this.receivingBufferCount); Debug.Print(new string(ATParser.Bytes2Chars(this.receivingBuffer, this.receivingBufferIndex, this.receivingBufferCount))); exception.ToString(); } }
public ATFrame Process(ATFrame frame, bool waitResponse, int timeout, AsyncCallback callback) { lock (this.syncRoot) { if (waitResponse) { lock (this.waitingLock) { this.waitingEcho = this.echoEnabled; this.waitingResponse = true; this.waitingTimeout = Environment.TickCount + timeout; this.waitingCommand = frame.Command; this.waitingCommandType = frame.CommandType; this.waitingCallback = null; this.waitingEchoEvent.Reset(); this.waitingResponseEvent.Reset(); } } try { this.sendingLength = frame.GetBytes(this.sendingBuffer, 0); this.stream.Write(this.sendingBuffer, 0, this.sendingLength); #if (DEBUG) Debug.Print("Sent frame > "); Debug.Print(new string(ATParser.Bytes2Chars(this.sendingBuffer, 0, this.sendingLength))); #endif if (this.waitingEcho && !this.waitingEchoEvent.WaitOne(defaultEchoTimeout, true)) { throw new ATModemException(ATModemError.Timeout); } if (!waitResponse) { return(null); } if (this.waitingResponseEvent.WaitOne(timeout, true)) { return(this.waitingFrame); } throw new ATModemException(ATModemError.Timeout); } finally { if (waitResponse) { lock (this.waitingLock) { this.waitingEcho = false; this.waitingResponse = false; } } } } }