Ejemplo n.º 1
0
        void DataReceived(object sender, SerialDataReceivedEventArgs data)
        {
            List <byte[]> responses = new List <byte[]>();

            byte[] buffer = new byte[Stream.BytesToRead + m_inputBufferLength];
            Array.Copy(m_inputBuffer, 0, buffer, 0, m_inputBufferLength);
            Stream.Read(buffer, m_inputBufferLength, buffer.Length - m_inputBufferLength);
            m_inputBufferLength = 0;

            for (int i = 0; i < buffer.Length;)
            {
                ResponseCodes code = BadgeResponses.GetCode(buffer[i]);

                int rem      = buffer.Length - i;
                int minSize  = BadgeResponses.GetMinResponseLength(code);
                int fullSize = int.MaxValue;
                if (minSize <= rem)
                {
                    fullSize = BadgeResponses.GetFullResponseLength(code, buffer, i);
                }

                if (fullSize <= rem)
                {
                    byte[] fullResponse = new byte[fullSize];
                    Array.Copy(buffer, i, fullResponse, 0, fullSize);
                    responses.Add(fullResponse);
                    i += fullSize;

                    // handle a couple of special responses before forwarding them along
                    if (code == ResponseCodes.Ack)
                    {
                        bool fromSerialPacket = ((fullResponse[0] & 0x08) == 0);
                        if (fromSerialPacket)
                        {
                            // reliable packet success!
                            RetirePendingPacket(fullResponse[1]);
                        }
                    }
                    else if (code == ResponseCodes.Error)
                    {
                        ErrorCodes error = (ErrorCodes)(fullResponse[0] & 0xF);
                        if (error == ErrorCodes.CorruptPacketData || error == ErrorCodes.ReceiveBufferOverrun)
                        {
                            // reliable packet failure!
                            PendingPacket packet = RetirePendingPacket(fullResponse[1]);
                            if (packet.Packet != null)
                            {
                                if (packet.Attempt >= m_retryMax)
                                {
                                    m_dispatcher.NotifySendFailure(this, packet.Packet);
                                }
                                else
                                {
                                    lock (m_resendPackets)
                                    {
                                        m_resendPackets.Add(packet);
                                    }
                                }
                            }
                        }
                    }
                    else if (code == ResponseCodes.Setting)
                    {
                        SettingValue valueType = (SettingValue)(fullResponse[0] & 0xF);
                        if (valueType == SettingValue.Caps)
                        {
                            byte version, width, height, bitDepth;
                            SupportedFeatures features;
                            BadgeResponses.DecodeCapsSetting(fullResponse, 0, out version, out width, out height, out bitDepth, out features);
                            Device = new BadgeCaps(version, width, height, bitDepth, features, Baud);
                        }
                    }
                }
                else
                {
                    // needs more
                    m_inputBufferLength = buffer.Length - i;
                    Array.Copy(buffer, i, m_inputBuffer, 0, m_inputBufferLength);
                    break;
                }
            }

            if (responses.Count > 0 && m_dispatcher != null)
            {
                m_dispatcher.EnqueueResponse(this, responses.ToArray());
            }
        }