public static void ExportSchedulesFITFile(Stream exportStream, MemoryStream dataStream) { MemoryStream tempDataStream = new MemoryStream(); // Reserve size for header tempDataStream.Write(new Byte[12], 0, 12); // File id message FITMessage fileIdMessage = new FITMessage(FITGlobalMessageIds.FileId); FITMessageField fileType = new FITMessageField((Byte)FITFileIdFieldsIds.FileType); FITMessageField manufacturerId = new FITMessageField((Byte)FITFileIdFieldsIds.ManufacturerId); FITMessageField productId = new FITMessageField((Byte)FITFileIdFieldsIds.ProductId); FITMessageField serialNumber = new FITMessageField((Byte)FITFileIdFieldsIds.SerialNumber); FITMessageField exportDate = new FITMessageField((Byte)FITFileIdFieldsIds.ExportDate); FITMessageField number = new FITMessageField((Byte)FITFileIdFieldsIds.Number); manufacturerId.SetUInt16(1); fileType.SetEnum((Byte)FITFileTypes.Schedules); // Invalid fields productId.SetUInt16(0xFFFF); serialNumber.SetUInt32z(0); exportDate.SetUInt32(0xFFFFFFFF); number.SetUInt16(0xFFFF); fileIdMessage.AddField(serialNumber); fileIdMessage.AddField(exportDate); fileIdMessage.AddField(manufacturerId); fileIdMessage.AddField(productId); fileIdMessage.AddField(number); fileIdMessage.AddField(fileType); fileIdMessage.Serialize(tempDataStream); // Write all passed in data to output stream tempDataStream.Write(dataStream.GetBuffer(), 0, (int)dataStream.Length); // Write FIT header at the start of the stream GarminFitnessByteRange headerSize = new GarminFitnessByteRange(12); GarminFitnessByteRange protocolVersion = new GarminFitnessByteRange((Byte)((FITConstants.FITProtocolMajorVersion << 4) | FITConstants.FITProtocolMinorVersion)); GarminFitnessUInt16Range profileVersion = new GarminFitnessUInt16Range((UInt16)((FITConstants.FITProfileMajorVersion * FITConstants.FITProfileMajorVersionMultiplier) + FITConstants.FITProfileMinorVersion)); GarminFitnessInt32Range dataSize = new GarminFitnessInt32Range(0); tempDataStream.Seek(0, SeekOrigin.Begin); dataSize.Value = (int)tempDataStream.Length - 12; headerSize.Serialize(tempDataStream); protocolVersion.Serialize(tempDataStream); profileVersion.Serialize(tempDataStream); dataSize.Serialize(tempDataStream); tempDataStream.Write(Encoding.UTF8.GetBytes(FITConstants.FITFileDescriptor), 0, 4); // Write CRC GarminFitnessUInt16Range crc = new GarminFitnessUInt16Range(FITUtils.ComputeStreamCRC(tempDataStream)); tempDataStream.Seek(0, SeekOrigin.End); crc.Serialize(tempDataStream); // Write all data to output stream exportStream.Write(tempDataStream.GetBuffer(), 0, (int)tempDataStream.Length); }
public void Serialize(Stream stream, bool serializeDefiniton) { // Definition message GarminFitnessByteRange recordHeader = new GarminFitnessByteRange(0x40); if (serializeDefiniton) { GarminFitnessByteRange recordReservedData = new GarminFitnessByteRange(0x00); GarminFitnessByteRange endianness = new GarminFitnessByteRange(0x00); GarminFitnessUInt16Range messageNumber = new GarminFitnessUInt16Range((UInt16)m_GlobalMessageType); GarminFitnessByteRange fieldsCount = new GarminFitnessByteRange((Byte)m_Fields.Count); recordHeader.Serialize(stream); recordReservedData.Serialize(stream); endianness.Serialize(stream); messageNumber.Serialize(stream); fieldsCount.Serialize(stream); foreach (FITMessageField field in m_Fields.Values) { field.SerializeDefinition(stream); } } // Data message recordHeader.Value = 0x00; recordHeader.Serialize(stream); foreach (FITMessageField field in m_Fields.Values) { field.SerializeData(stream); } }
public static void ExportWorkoutToFIT(IWorkout workout, Stream exportStream, bool updateExportDate) { MemoryStream dataStream = new MemoryStream(); // Reserve size for header dataStream.Write(new Byte[12], 0, 12); // File id message FITMessage fileIdMessage = new FITMessage(FITGlobalMessageIds.FileId); FITMessageField fileType = new FITMessageField((Byte)FITFileIdFieldsIds.FileType); FITMessageField manufacturerId = new FITMessageField((Byte)FITFileIdFieldsIds.ManufacturerId); FITMessageField productId = new FITMessageField((Byte)FITFileIdFieldsIds.ProductId); FITMessageField serialNumber = new FITMessageField((Byte)FITFileIdFieldsIds.SerialNumber); FITMessageField exportDate = new FITMessageField((Byte)FITFileIdFieldsIds.ExportDate); FITMessageField number = new FITMessageField((Byte)FITFileIdFieldsIds.Number); fileType.SetEnum((Byte)FITFileTypes.Workout); manufacturerId.SetUInt16(1); productId.SetUInt16(20119); serialNumber.SetUInt32z(0); exportDate.SetUInt32(workout.CreationTimestamp); number.SetUInt16(0xFFFF); fileIdMessage.AddField(serialNumber); fileIdMessage.AddField(exportDate); fileIdMessage.AddField(manufacturerId); fileIdMessage.AddField(productId); fileIdMessage.AddField(number); fileIdMessage.AddField(fileType); fileIdMessage.Serialize(dataStream); // File creator message FITMessage fileCreatorMessage = new FITMessage(FITGlobalMessageIds.FileCreator); FITMessageField software = new FITMessageField((Byte)FITFileCreatorFieldsIds.SoftwareVersion); FITMessageField hardware = new FITMessageField((Byte)FITFileCreatorFieldsIds.HardwareVersion); software.SetUInt16(3605); hardware.SetUInt8(0); fileCreatorMessage.AddField(software); fileCreatorMessage.AddField(hardware); fileCreatorMessage.Serialize(dataStream); // Write workout workout.SerializeToFIT(dataStream); // Write FIT header at the start of the stream GarminFitnessByteRange headerSize = new GarminFitnessByteRange(12); GarminFitnessByteRange protocolVersion = new GarminFitnessByteRange((Byte)((FITConstants.FITProtocolMajorVersion << 4) | FITConstants.FITProtocolMinorVersion)); GarminFitnessUInt16Range profileVersion = new GarminFitnessUInt16Range((UInt16)((FITConstants.FITProfileMajorVersion * FITConstants.FITProfileMajorVersionMultiplier) + FITConstants.FITProfileMinorVersion)); GarminFitnessInt32Range dataSize = new GarminFitnessInt32Range(0); dataStream.Seek(0, SeekOrigin.Begin); dataSize.Value = (int)dataStream.Length - 12; headerSize.Serialize(dataStream); protocolVersion.Serialize(dataStream); profileVersion.Serialize(dataStream); dataSize.Serialize(dataStream); dataStream.Write(Encoding.UTF8.GetBytes(FITConstants.FITFileDescriptor), 0, 4); // Write CRC GarminFitnessUInt16Range crc = new GarminFitnessUInt16Range(FITUtils.ComputeStreamCRC(dataStream)); dataStream.Seek(0, SeekOrigin.End); crc.Serialize(dataStream); // Write all data to output stream exportStream.Write(dataStream.GetBuffer(), 0, (int)dataStream.Length); if (updateExportDate) { workout.LastExportDate = DateTime.Now; } }
public void SerializeDefinition(Stream stream) { GarminFitnessByteRange definitionNumber = new GarminFitnessByteRange(m_DefinitionNumber); GarminFitnessByteRange size = new GarminFitnessByteRange((Byte)(FieldSize * ArraySize)); GarminFitnessByteRange baseType = new GarminFitnessByteRange((Byte)m_Type); definitionNumber.Serialize(stream); size.Serialize(stream); baseType.Serialize(stream); }
public override void Serialize(XmlNode parentNode, String nodeName, XmlDocument document) { base.Serialize(parentNode, nodeName, document); // This node was added by our parent... parentNode = parentNode.LastChild; float lastMaxHR = GarminProfileManager.Instance.UserProfile.GetProfileForActivity(Options.Instance.GetGarminCategory(BaseTarget.ParentStep.ParentWorkout.Category)).MaximumHeartRate; XmlAttribute attribute; XmlNode childNode; GarminFitnessBool exportAsPercentMax = new GarminFitnessBool(Options.Instance.ExportSportTracksHeartRateAsPercentMax, Constants.HeartRateReferenceTCXString[1], Constants.HeartRateReferenceTCXString[0]); GarminFitnessByteRange lowValue = new GarminFitnessByteRange(0); GarminFitnessByteRange highValue = new GarminFitnessByteRange(0); if (float.IsNaN(lastMaxHR)) { exportAsPercentMax.Value = false; } if (exportAsPercentMax) { float baseMultiplier = Constants.MaxHRInPercentMax / lastMaxHR; lowValue.Value = (Byte)Utils.Clamp(Math.Round(Zone.Low * baseMultiplier, 0, MidpointRounding.AwayFromZero), Constants.MinHRInPercentMax, Constants.MaxHRInPercentMax); highValue.Value = (Byte)Utils.Clamp(Math.Round(Zone.High * baseMultiplier, 0, MidpointRounding.AwayFromZero), Constants.MinHRInPercentMax, Constants.MaxHRInPercentMax); } else { lowValue.Value = (Byte)Utils.Clamp(Zone.Low, Constants.MinHRInBPM, Constants.MaxHRInBPM); highValue.Value = (Byte)Utils.Clamp(Zone.High, Constants.MinHRInBPM, Constants.MaxHRInBPM); } // Type attribute = document.CreateAttribute(Constants.XsiTypeTCXString, Constants.xsins); attribute.Value = Constants.HeartRateRangeZoneTCXString[1]; parentNode.Attributes.Append(attribute); // Low childNode = document.CreateElement("Low"); parentNode.AppendChild(childNode); exportAsPercentMax.SerializeAttribute(childNode, Constants.XsiTypeTCXString, Constants.xsins, document); lowValue.Serialize(childNode, Constants.ValueTCXString, document); // High childNode = document.CreateElement("High"); parentNode.AppendChild(childNode); exportAsPercentMax.SerializeAttribute(childNode, Constants.XsiTypeTCXString, Constants.xsins, document); highValue.Serialize(childNode, Constants.ValueTCXString, document); // Extension Utils.SerializeSTZoneInfoXML(BaseTarget.ParentStep, BaseTarget.ParentStep.ParentConcreteWorkout.Category.HeartRateZone, Zone, document); }
public void DeserializeData(Stream stream, bool isLittleEndian) { switch (m_Type) { case DataType.Enum: case DataType.UInt8: case DataType.UInt8z: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessByteRange data = new GarminFitnessByteRange(0); data.Deserialize(stream, Constants.CurrentVersion); m_ByteValues[i] = data; } break; } case DataType.SInt8: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessSByteRange data = new GarminFitnessSByteRange(0); data.Deserialize(stream, Constants.CurrentVersion); m_SByteValues[i] = data; } break; } case DataType.UInt16: case DataType.UInt16z: { for (int i = 0; i < ArraySize; ++i) { Byte[] data = new Byte[sizeof(UInt16)]; stream.Read(data, 0, sizeof(UInt16)); m_UInt16Values[i] = BitConverter.ToUInt16(data, 0); if (!isLittleEndian) { Byte temp = data[0]; data[0] = data[1]; data[1] = temp; m_UInt16Values[i] = BitConverter.ToUInt16(data, 0); } } break; } case DataType.SInt16: { for (int i = 0; i < ArraySize; ++i) { Byte[] data = new Byte[sizeof(Int16)]; stream.Read(data, 0, sizeof(UInt16)); m_Int16Values[i] = BitConverter.ToInt16(data, 0); if (!isLittleEndian) { Byte temp = data[0]; data[0] = data[1]; data[1] = temp; m_Int16Values[i] = BitConverter.ToInt16(data, 0); } } break; } case DataType.UInt32: case DataType.UInt32z: { for (int i = 0; i < ArraySize; ++i) { Byte[] data = new Byte[sizeof(UInt32)]; stream.Read(data, 0, sizeof(UInt32)); m_UInt32Values[i] = BitConverter.ToUInt32(data, 0); if (!isLittleEndian) { Byte temp = data[0]; data[0] = data[3]; data[3] = temp; temp = data[1]; data[1] = data[2]; data[2] = temp; m_UInt32Values[i] = BitConverter.ToUInt32(data, 0); } } break; } case DataType.SInt32: { for (int i = 0; i < ArraySize; ++i) { Byte[] data = new Byte[sizeof(UInt32)]; stream.Read(data, 0, sizeof(UInt32)); m_Int32Values[i] = BitConverter.ToInt32(data, 0); if (!isLittleEndian) { Byte temp = data[0]; data[0] = data[3]; data[3] = temp; temp = data[1]; data[1] = data[2]; data[2] = temp; m_Int32Values[i] = BitConverter.ToInt32(data, 0); } } break; } case DataType.Float32: { for (int i = 0; i < ArraySize; ++i) { Byte[] data = new Byte[sizeof(Single)]; stream.Read(data, 0, sizeof(Single)); m_SingleValues[i] = BitConverter.ToSingle(data, 0); if (!isLittleEndian) { Byte temp = data[0]; data[0] = data[3]; data[3] = temp; temp = data[1]; data[1] = data[2]; data[2] = temp; m_SingleValues[i] = BitConverter.ToSingle(data, 0); } } break; } case DataType.Float64: { for (int i = 0; i < ArraySize; ++i) { Byte[] data = new Byte[sizeof(Double)]; stream.Read(data, 0, sizeof(Double)); m_DoubleValues[i] = BitConverter.ToDouble(data, 0); if (!isLittleEndian) { Byte temp = data[0]; data[0] = data[7]; data[7] = temp; temp = data[1]; data[1] = data[6]; data[6] = temp; temp = data[2]; data[2] = data[5]; data[5] = temp; temp = data[3]; data[3] = data[4]; data[4] = temp; m_DoubleValues[i] = BitConverter.ToDouble(data, 0); } } break; } case DataType.String: case DataType.Byte: { stream.Read(m_ByteValues, 0, m_ByteValues.Length); break; } default: { Debug.Assert(false); break; } } }
public void SerializeData(Stream stream) { switch (m_Type) { case DataType.Enum: case DataType.UInt8: case DataType.UInt8z: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessByteRange data = new GarminFitnessByteRange(m_ByteValues[i]); data.Serialize(stream); } break; } case DataType.SInt8: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessSByteRange data = new GarminFitnessSByteRange(m_SByteValues[i]); data.Serialize(stream); } break; } case DataType.UInt16: case DataType.UInt16z: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessUInt16Range data = new GarminFitnessUInt16Range(m_UInt16Values[i]); data.Serialize(stream); } break; } case DataType.SInt16: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessInt16Range data = new GarminFitnessInt16Range(m_Int16Values[i]); data.Serialize(stream); } break; } case DataType.UInt32: case DataType.UInt32z: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessUInt32Range data = new GarminFitnessUInt32Range(m_UInt32Values[i]); data.Serialize(stream); } break; } case DataType.SInt32: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessInt32Range data = new GarminFitnessInt32Range(m_Int32Values[i]); data.Serialize(stream); } break; } case DataType.Float32: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessFloatRange data = new GarminFitnessFloatRange(m_SingleValues[i]); data.Serialize(stream); } break; } case DataType.Float64: { for (int i = 0; i < ArraySize; ++i) { GarminFitnessDoubleRange data = new GarminFitnessDoubleRange(m_DoubleValues[i]); data.Serialize(stream); } break; } case DataType.String: { Byte[] valueStored = new Byte[FieldSize]; for(int i = 0; i < valueStored.Length; ++i) { if (i < m_ByteValues.Length) { valueStored[i] = m_ByteValues[i]; } else { valueStored[i] = 0; } } stream.Write(valueStored, 0, valueStored.Length); break; } case DataType.Byte: { stream.Write(m_ByteValues, 0, m_ByteValues.Length); break; } default: { Debug.Assert(false); break; } } }
public override void Serialize(Stream stream) { GarminFitnessByteRange intensity = new GarminFitnessByteRange((Byte)m_Intensity); base.Serialize(stream); m_Name.Serialize(stream); Duration.Serialize(stream); Target.Serialize(stream); intensity.Serialize(stream); }
public void Deserialize_V17(Stream stream, DataVersion version) { GarminFitnessByteRange intensity = new GarminFitnessByteRange(0); // Call base deserialization Deserialize(typeof(IStep), stream, version); byte[] intBuffer = new byte[sizeof(Int32)]; m_Name.Deserialize(stream, version); // Duration stream.Read(intBuffer, 0, sizeof(Int32)); DurationFactory.Create((IDuration.DurationType)BitConverter.ToInt32(intBuffer, 0), stream, version, this); // Target stream.Read(intBuffer, 0, sizeof(Int32)); Int32 type = BitConverter.ToInt32(intBuffer, 0); // This sucks but I changed the order of the enum between version 0 and 1, // so make sure the version is right if (version.VersionNumber == 0) { if (type == 3) { // Null was #3, now #0 type = 0; } else { // Everything else is pushed up 1 position ++type; } } TargetFactory.Create((ITarget.TargetType)type, stream, version, this); intensity.Deserialize(stream, Constants.CurrentVersion); m_Intensity = (StepIntensity)(Byte)intensity; }
private void ReadHRZone(int index, XmlNode parentNode) { Debug.Assert(index >= 0 && index < Constants.GarminHRZoneCount); bool viewAsRead = false; bool lowRead = false; bool highRead = false; GarminFitnessByteRange lowLimit = new GarminFitnessByteRange(0); GarminFitnessByteRange highLimit = new GarminFitnessByteRange(0); for (int i = 0; i < parentNode.ChildNodes.Count; ++i) { XmlNode currentChild = parentNode.ChildNodes[i]; if (currentChild.Name == Constants.ViewAsTCXString) { GarminFitnessBool HRIsInPercentMax = new GarminFitnessBool(true, Constants.PercentMaxTCXString, Constants.BPMTCXString); HRIsInPercentMax.Deserialize(currentChild); // When we read % max, make sure we don't overwrite the BPM vs %Max/HRR since there // is no difference between both of these in the TCX file if (!HRIsInPercentMax || HRZonesReferential == HRReferential.HRReferential_BPM) { HRZonesReferential = HRIsInPercentMax ? HRReferential.HRReferential_PercentMax : HRReferential.HRReferential_BPM; } viewAsRead = true; } else if (currentChild.Name == Constants.LowTCXString && currentChild.ChildNodes.Count == 1 && currentChild.FirstChild.Name == Constants.ValueTCXString) { lowLimit.Deserialize(currentChild.FirstChild); lowRead = true; } else if (currentChild.Name == Constants.HighTCXString && currentChild.ChildNodes.Count == 1 && currentChild.FirstChild.Name == Constants.ValueTCXString) { highLimit.Deserialize(currentChild.FirstChild); highRead = true; } } // Check if all was read successfully if (!viewAsRead || !lowRead || !highRead) { throw new GarminFitnessXmlDeserializationException("Missing information in heart rate zone XML node", parentNode); } m_HeartRateZones[index].Lower = new GarminFitnessDoubleRange((double)Math.Min(lowLimit, highLimit) / MaximumHeartRate, 0, 1); m_HeartRateZones[index].Upper = new GarminFitnessDoubleRange((double)Math.Max(lowLimit, highLimit) / MaximumHeartRate, 0, 1); }
public virtual void Serialize(XmlNode parentNode, String nodeName, XmlDocument document) { XmlAttribute attributeNode; XmlNode activityNode, currentChild; activityNode = document.CreateElement(nodeName); parentNode.AppendChild(activityNode); attributeNode = document.CreateAttribute("Sport"); attributeNode.Value = Constants.GarminCategoryTCXString[(int)Category]; activityNode.Attributes.Append(attributeNode); attributeNode = document.CreateAttribute(Constants.XsiTypeTCXString, Constants.xsins); attributeNode.Value = "ProfileActivity_t"; activityNode.Attributes.Append(attributeNode); // Maximum heart rate currentChild = document.CreateElement(Constants.MaxHRBPMTCXString); activityNode.AppendChild(currentChild); m_MaxHeartRate.Serialize(currentChild, Constants.ValueTCXString, document); // Resting HR currentChild = document.CreateElement(Constants.RestHRBPMTCXString); activityNode.AppendChild(currentChild); GarminProfileManager.Instance.UserProfile.InternalRestingHeartRate.Serialize(currentChild, Constants.ValueTCXString, document); GarminFitnessDoubleRange gearWeightinKg = new GarminFitnessDoubleRange(Weight.Convert(m_GearWeightInPounds, Weight.Units.Pound, Weight.Units.Kilogram)); gearWeightinKg.Serialize(activityNode, Constants.GearWeightTCXString, document); // HR zones for (int i = 0; i < Constants.GarminHRZoneCount; ++i) { currentChild = document.CreateElement(Constants.HeartRateZonesTCXString); activityNode.AppendChild(currentChild); // Number XmlNode numberNode = document.CreateElement("Number"); numberNode.AppendChild(document.CreateTextNode((i + 1).ToString())); currentChild.AppendChild(numberNode); // View as BPM or % max GarminFitnessBool HRIsInPercentMax = new GarminFitnessBool(HRZonesReferential != HRReferential.HRReferential_BPM, Constants.PercentMaxTCXString, Constants.BPMTCXString); HRIsInPercentMax.Serialize(currentChild, Constants.ViewAsTCXString, document); // Low GarminFitnessByteRange lowLimit = new GarminFitnessByteRange((Byte)(m_HeartRateZones[i].Lower * MaximumHeartRate)); XmlNode low = document.CreateElement(Constants.LowTCXString); currentChild.AppendChild(low); lowLimit.Serialize(low, Constants.ValueTCXString, document); // High GarminFitnessByteRange highLimit = new GarminFitnessByteRange((Byte)(m_HeartRateZones[i].Upper * MaximumHeartRate)); XmlNode high = document.CreateElement(Constants.HighTCXString); currentChild.AppendChild(high); highLimit.Serialize(high, Constants.ValueTCXString, document); } // Speed zones for (int i = 0; i < Constants.GarminSpeedZoneCount; ++i) { currentChild = document.CreateElement(Constants.SpeedZonesTCXString); activityNode.AppendChild(currentChild); // Number XmlNode numberNode = document.CreateElement("Number"); numberNode.AppendChild(document.CreateTextNode((i + 1).ToString())); currentChild.AppendChild(numberNode); // Name m_SpeedZones[i].InternalName.Serialize(currentChild, "Name", document); XmlNode valueChild = document.CreateElement(Constants.ValueTCXString); currentChild.AppendChild(valueChild); // View as pace or speed m_SpeedIsInPace.Serialize(valueChild, Constants.ViewAsTCXString, document); // Low m_SpeedZones[i].InternalLow.Serialize(valueChild, Constants.LowInMeterPerSecTCXString, document); // High m_SpeedZones[i].InternalHigh.Serialize(valueChild, Constants.HighInMeterPerSecTCXString, document); } }
public void Deserialize_V23(Stream stream, DataVersion version) { m_MaxHeartRate.Deserialize(stream, version); m_GearWeightInPounds.Deserialize(stream, version); GarminFitnessByteRange HRZoneReference = new GarminFitnessByteRange(0); HRZoneReference.Deserialize(stream, version); HRZonesReferential = (HRReferential)(Byte)HRZoneReference; for (int i = 0; i < m_HeartRateZones.Count; ++i) { m_HeartRateZones[i].Lower.Deserialize(stream, version); m_HeartRateZones[i].Upper.Deserialize(stream, version); } m_SpeedIsInPace.Deserialize(stream, version); for (int i = 0; i < m_SpeedZones.Count; ++i) { m_SpeedZones[i].InternalLow.Deserialize(stream, version); m_SpeedZones[i].InternalHigh.Deserialize(stream, version); m_SpeedZones[i].InternalName.Deserialize(stream, version); } }