public static int GetFullResponseLength(ResponseCodes response, byte[] buffer, int offset) { switch (response) { case ResponseCodes.Setting: { SettingValue setting = (SettingValue)(buffer[offset] & 0xF); return(GetSettingResponseLength(setting)); } case ResponseCodes.Pixels: { PixelFormat format; byte width; byte height; byte bufferLength; int headerLen = BadgeResponses.DecodePixels(buffer, offset, out format, out width, out height, out bufferLength); return(headerLen + bufferLength); } case ResponseCodes.Memory: { byte numDWords; short address; byte bufferLength; int headerLen = BadgeResponses.DecodeMemory(buffer, offset, out numDWords, out address, out bufferLength); return(headerLen + bufferLength); } default: return(GetMinResponseLength(response)); } }
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()); } }