private int readFromOffset(int offset, byte[] rawData) { totalPacketCount++; if (totalPacketCount == estimateRateStartPacket) { ticksAtRateEstimateStart = DateTime.Now.Ticks; } else if (totalPacketCount == estimateRateEndPacket && ticksAtRateEstimateStart > 0) { rateEstimate = (float)(TimeSpan.TicksPerSecond * (estimateRateEndPacket - estimateRateStartPacket)) / (float)(DateTime.Now.Ticks - ticksAtRateEstimateStart); } // the first 2 bytes are the version - discard it for now int frameTypeAndSequence = rawData[offset + 2]; int frameType = frameTypeAndSequence & 3; int sequence = frameTypeAndSequence >> 2; int frameLength = 0; if (frameType == 0) { telemPacketCount++; frameLength = sTelemetryData_PacketSize; Boolean sequenceCheckOK = isNextInSequence(sequence); if (strictPacketOrdering && !sequenceCheckOK) { discardedTelemCount++; } else { handle = GCHandle.Alloc(rawData.Skip(offset).Take(frameLength).ToArray(), GCHandleType.Pinned); sTelemetryData telem = (sTelemetryData)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(sTelemetryData)); if (sequenceCheckOK || !telemIsOutOfSequence(telem)) { //buttonsState = ConvertByteToBoolArray(telem.sDPad); lastSequenceNumberForTelemPacket = sequence; workingGameState = StructHelper.MergeWithExistingState(workingGameState, telem); // newSpotterData = workingGameState.hasNewPositionData; handle.Free(); } } } else if (frameType == 1) { frameLength = sParticipantInfoStrings_PacketSize; handle = GCHandle.Alloc(rawData.Skip(offset).Take(frameLength).ToArray(), GCHandleType.Pinned); sParticipantInfoStrings strings = (sParticipantInfoStrings)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(sParticipantInfoStrings)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, strings); handle.Free(); } else if (frameType == 2) { frameLength = sParticipantInfoStringsAdditional_PacketSize; handle = GCHandle.Alloc(rawData.Skip(offset).Take(frameLength).ToArray(), GCHandleType.Pinned); sParticipantInfoStringsAdditional additional = (sParticipantInfoStringsAdditional)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(sParticipantInfoStringsAdditional)); workingGameState = StructHelper.MergeWithExistingState(workingGameState, additional); handle.Free(); } return(frameLength + offset); }
public static pCarsAPIStruct MergeWithExistingState(pCarsAPIStruct existingState, sParticipantInfoStringsAdditional udpAdditionalStrings) { if (existingState.mParticipantData == null) { existingState.mParticipantData = new pCarsAPIParticipantStruct[udpAdditionalStrings.sName.Count()]; } for (int i = 0; i < udpAdditionalStrings.sName.Count(); i++) { String name = getNameFromBytes(udpAdditionalStrings.sName[i].nameByteArray); // TODO: will the mIsActive flag always have been set by the time we reach here? existingState.mParticipantData[i + udpAdditionalStrings.sOffset].mIsActive = name != null && name.Length > 0; existingState.mParticipantData[i + udpAdditionalStrings.sOffset].mName = name; } return(existingState); }