Beispiel #1
0
        public override ATParserResult Parse(byte[] buffer, int index, int count)
        {
            Match          responseMatch;
            ATParserResult parserResult = null;

            responseMatch = this.Regex.Match(buffer, index, count);

            if (responseMatch.Success)
            {
                parserResult             = this.Unsolicited ? ATParserResult.UnsolicitedInstance : ATParserResult.Instance;
                parserResult.Command     = this.Command;
                parserResult.CommandType = this.CommandType;
                parserResult.Unsolicited = this.Unsolicited;
                parserResult.Success     = true;
                parserResult.Index       = responseMatch.Index;
                parserResult.Length      = responseMatch.Length;

                if (this.RegexResultGroup > 0 &&
                    this.RegexResultGroup < responseMatch.Groups.Length &&
                    responseMatch.Groups[this.RegexResultGroup].Success)
                {
                    parserResult.Result = this.GetText(buffer, responseMatch.Groups[this.RegexResultGroup].index, responseMatch.Groups[this.RegexResultGroup].length);
                }
                else
                {
                    parserResult.Result = null;
                }

                if (this.RegexParametersGroup > 0 &&
                    this.RegexParametersGroup < responseMatch.Groups.Length &&
                    responseMatch.Groups[this.RegexParametersGroup].Success)
                {
                    parserResult.OutParameters = this.GetText(buffer, responseMatch.Groups[this.RegexParametersGroup].index, responseMatch.Groups[this.RegexParametersGroup].length);
                }
                else
                {
                    parserResult.OutParameters = null;
                }

                if (this.RegexDataLengthGroup > 0 &&
                    this.RegexDataLengthGroup < responseMatch.Groups.Length &&
                    responseMatch.Groups[this.RegexDataLengthGroup].Success)
                {
                    parserResult.DataLength = Convert.ToInt32(this.GetText(buffer, responseMatch.Groups[this.RegexDataLengthGroup].index, responseMatch.Groups[this.RegexDataLengthGroup].length));
                }
                else
                {
                    parserResult.DataLength = 0;
                }
            }

            return(parserResult);
        }
Beispiel #2
0
        public ATProtocol(Stream stream, ATParser parser)
        {
            this.stream = stream;

            this.parser = parser;
            this.parserResult = null;

            this.closed = false;
            this.syncRoot = new object();
            this.echoEnabled = true;

            this.sendingLength = 0;
            this.sendingBuffer = new byte[sendingBufferSize];

            this.waitingLock = new object();
            this.waitingEchoEvent = new AutoResetEvent(false);
            this.waitingResponseEvent = new AutoResetEvent(false);

            this.readDataLength = 0;

            this.receivingBuffer = new byte[receivingBufferSize];
            this.receivingThread = new Thread(this.ReceiverThreadRun);
            this.receivingThread.Start();
        }
Beispiel #3
0
        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();
            }
        }