Skip to content

Commit

Permalink
Enforce TLV constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
jdomnitz committed Dec 28, 2024
1 parent b73072b commit 0981e0c
Show file tree
Hide file tree
Showing 68 changed files with 435 additions and 238 deletions.
80 changes: 74 additions & 6 deletions Generator/ClassGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private static void WriteTag(string indent, Tag tag, StreamWriter writer)
if (child.Type != DataType.Structure)
writer.WriteLine($"{indent} {(child.Optional? "public" : "public required")} {GetType(child)}{((child.Nullable || child.Optional) ? "?" : "")} {child.Name} {{ get; set; }} ");
}
writer.WriteLine($"\r\n{indent} /// <inheritdoc />\r\n{indent} [SetsRequiredMembers]\r\n{indent} public {tag.Name}(TLVReader reader, long structNumber = -1) {{");
writer.WriteLine($"\r\n{indent} [SetsRequiredMembers]\r\n{indent} internal {tag.Name}(TLVReader reader, long structNumber = -1) {{");
if (tag.Type == DataType.List)
writer.WriteLine($"{indent} reader.StartList(structNumber);");
else if (tag.Type != DataType.Choice)
Expand Down Expand Up @@ -109,10 +109,42 @@ private static void WriteTag(string indent, Tag tag, StreamWriter writer)
writer.WriteLine($"{totalIndent}{child.Name} = reader.GetDouble({child.TagNumber}{(child.Nullable ? ", true)" : ")")}{(!child.Nullable && !child.Optional ? "!.Value;" : ";")}");
break;
case DataType.Bytes:
writer.WriteLine($"{totalIndent}{child.Name} = reader.GetBytes({child.TagNumber}{(child.Nullable ? ", true)" : ")")}{(!child.Nullable && !child.Optional ? "!;" : ";")}");
writer.Write($"{totalIndent}{child.Name} = reader.GetBytes({child.TagNumber}");
if (child.Nullable)
writer.Write(", true");
else if (child.Max != 0 || child.Min != 0)
writer.Write(", false");
if (child.Max != 0)
writer.Write($", {child.Max}");
if (child.Min != 0)
{
if (child.Max == 0)
writer.Write(", int.MaxValue");
writer.Write($", {child.Min}");
}
if (!child.Nullable && !child.Optional)
writer.WriteLine(")!;");
else
writer.WriteLine(");");
break;
case DataType.String:
writer.WriteLine($"{totalIndent}{child.Name} = reader.GetString({child.TagNumber}{(child.Nullable ? ", true)" : ")")}{(!child.Nullable && !child.Optional ? "!;" : ";")}");
writer.Write($"{totalIndent}{child.Name} = reader.GetString({child.TagNumber}");
if (child.Nullable)
writer.Write(", true");
else if (child.Max != 0 || child.Min != 0)
writer.Write(", false");
if (child.Max != 0)
writer.Write($", {child.Max}");
if (child.Min != 0)
{
if (child.Max == 0)
writer.Write(", int.MaxValue");
writer.Write($", {child.Min}");
}
if (!child.Nullable && !child.Optional)
writer.WriteLine(")!;");
else
writer.WriteLine(");");
break;
case DataType.Any:
writer.WriteLine($"{totalIndent}{child.Name} = reader.GetAny({child.TagNumber}{(child.Nullable ? ", true)" : ")")}{(!child.Nullable && !child.Optional ? "!;" : ";")}");
Expand All @@ -125,7 +157,7 @@ private static void WriteTag(string indent, Tag tag, StreamWriter writer)
}
if (tag.Type != DataType.Choice)
writer.WriteLine($"{indent} reader.EndContainer();");
writer.WriteLine($"{indent} }}\r\n\r\n{indent} /// <inheritdoc />\r\n{indent} public override void Serialize(TLVWriter writer, long structNumber = -1) {{");
writer.WriteLine($"{indent} }}\r\n\r\n{indent} internal override void Serialize(TLVWriter writer, long structNumber = -1) {{");
if (tag.Type == DataType.List)
writer.WriteLine($"{indent} writer.StartList(structNumber);");
else if (tag.Type != DataType.Choice)
Expand All @@ -143,6 +175,14 @@ private static void WriteTag(string indent, Tag tag, StreamWriter writer)
{
case DataType.Array:
writer.WriteLine($"{totalIndent}{{");
if (child.Min != 0 || child.Max != 0)
{
writer.Write($"{totalIndent} Constrain({child.Name}, {child.Min}");
if (child.Max != 0)
writer.WriteLine($", {child.Max});");
else
writer.WriteLine(");");
}
writer.WriteLine($"{totalIndent} writer.StartArray({child.TagNumber});");
writer.WriteLine($"{totalIndent} foreach (var item in {child.Name}) {{");
writer.WriteLine($"{totalIndent} {GetWriter(GetEnumerationType(child), GetEnumerationIndex(child))};");
Expand All @@ -152,6 +192,14 @@ private static void WriteTag(string indent, Tag tag, StreamWriter writer)
break;
case DataType.List:
writer.WriteLine($"{totalIndent}{{");
if (child.Min != 0 || child.Max != 0)
{
writer.Write($"{totalIndent} Constrain({child.Name}, {child.Min}");
if (child.Max != 0)
writer.WriteLine($", {child.Max});");
else
writer.WriteLine(");");
}
writer.WriteLine($"{totalIndent} writer.StartList({child.TagNumber});");
writer.WriteLine($"{totalIndent} foreach (var item in {child.Name}) {{");
writer.WriteLine($"{totalIndent} {GetWriter(GetEnumerationType(child), GetEnumerationIndex(child))};");
Expand Down Expand Up @@ -189,10 +237,30 @@ private static void WriteTag(string indent, Tag tag, StreamWriter writer)
writer.WriteLine($"{totalIndent}writer.WriteDouble({child.TagNumber}, {child.Name});");
break;
case DataType.Bytes:
writer.WriteLine($"{totalIndent}writer.WriteBytes({child.TagNumber}, {child.Name});");
writer.Write($"{totalIndent}writer.WriteBytes({child.TagNumber}, {child.Name}");
if (child.Max != 0)
writer.Write($", {child.Max}");
if (child.Min != 0)
{
if (child.Max == 0)
writer.Write($", int.MaxValue, {child.Min}");
else
writer.Write($", {child.Min}");
}
writer.WriteLine(");");
break;
case DataType.String:
writer.WriteLine($"{totalIndent}writer.WriteString({child.TagNumber}, {child.Name});");
writer.Write($"{totalIndent}writer.WriteString({child.TagNumber}, {child.Name}");
if (child.Max != 0)
writer.Write($", {child.Max}");
if (child.Min != 0)
{
if (child.Max == 0)
writer.Write($", int.MaxValue, {child.Min}");
else
writer.Write($", {child.Min}");
}
writer.WriteLine(");");
break;
case DataType.Any:
writer.WriteLine($"{totalIndent}writer.WriteAny({child.TagNumber}, {child.Name});");
Expand Down
14 changes: 7 additions & 7 deletions Generator/ClusterGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,21 +168,21 @@ private static void WriteStruct(clusterCommand command, bool toServer, StreamWri
}
if (toServer)
{
writer.WriteLine(" public override void Serialize(TLVWriter writer, long structNumber = -1) {");
writer.WriteLine(" internal override void Serialize(TLVWriter writer, long structNumber = -1) {");
writer.WriteLine(" writer.StartStructure(structNumber);");
foreach (clusterCommandField field in command.field)
{
if (field.type == null || field.disallowConform != null) //Reserved/removed fields
continue;
WriteStructType(field.optionalConform != null, field.type, field.id, (field.name == GeneratorUtil.SanitizeName(command.name) ? field.name + "Field" : field.name), cluster, writer);
WriteStructType(field.optionalConform != null, field.type, field.id, field.constraint?.fromSpecified == true ? field.constraint.from : null, field.constraint?.toSpecified == true ? field.constraint.to : null, (field.name == GeneratorUtil.SanitizeName(command.name) ? field.name + "Field" : field.name), cluster, writer);
}
writer.WriteLine(" writer.EndContainer();");
writer.WriteLine(" }");
}
writer.WriteLine(" }");
}

private static void WriteStructType(bool optional, string type, byte id, string name, Cluster cluster, StreamWriter writer)
private static void WriteStructType(bool optional, string type, byte id, int? from, int? to, string name, Cluster cluster, StreamWriter writer)
{
string totalIndent = " ";
if (optional)
Expand Down Expand Up @@ -291,10 +291,10 @@ private static void WriteStructType(bool optional, string type, byte id, string
case "ref_Ipv6Adr":
case "ipv6pre":
case "Hardware Address":
writer.WriteLine($"{totalIndent}writer.WriteBytes({id}, {name});");
writer.WriteLine($"{totalIndent}writer.WriteBytes({id}, {name}{(to != null ? $", {to.Value});" : ");")}");
break;
case "string":
writer.WriteLine($"{totalIndent}writer.WriteString({id}, {name});");
writer.WriteLine($"{totalIndent}writer.WriteString({id}, {name}{(to != null ? $", {to.Value});" : ");")}");
break;
default:
if (HasEnum(cluster, type))
Expand Down Expand Up @@ -443,10 +443,10 @@ private static void WriteStruct(clusterDataTypesStruct structType, Cluster clust
else
writer.WriteLine();
}
writer.WriteLine(" public override void Serialize(TLVWriter writer, long structNumber = -1) {");
writer.WriteLine(" internal override void Serialize(TLVWriter writer, long structNumber = -1) {");
writer.WriteLine(" writer.StartStructure(structNumber);");
foreach (clusterDataTypesStructField field in structType.field)
WriteStructType(field.@default != null, field.type, field.id, (field.name == GeneratorUtil.SanitizeName(structType.name) ? field.name + "Field" : field.name), cluster, writer);
WriteStructType(field.@default != null, field.type, field.id, field.constraint?.fromSpecified == true ? field.constraint.from : null, field.constraint?.toSpecified == true ? field.constraint.to : null, (field.name == GeneratorUtil.SanitizeName(structType.name) ? field.name + "Field" : field.name), cluster, writer);
writer.WriteLine(" writer.EndContainer();");
writer.WriteLine(" }");
writer.WriteLine(" }");
Expand Down
65 changes: 63 additions & 2 deletions Generator/Schema/Cluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Generator.Schema
{
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
Expand Down Expand Up @@ -822,13 +822,73 @@ public bool nullable
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class clusterDataTypesStructFieldConstraint
{
private int toField;
private int fromField;
private bool fromFieldSpecified;
private bool toFieldSpecified;

private string typeField;

private string valueField;

private bool valueFieldSpecified;

/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public int from
{
get
{
return this.fromField;
}
set
{
this.fromField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool fromSpecified
{
get
{
return this.fromFieldSpecified;
}
set
{
this.fromFieldSpecified = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public int to
{
get
{
return this.toField;
}
set
{
this.toField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool toSpecified
{
get
{
return this.toFieldSpecified;
}
set
{
this.toFieldSpecified = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type
Expand Down Expand Up @@ -1684,7 +1744,7 @@ public bool fabricScopedSpecified
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class clusterCommandField
{
private clusterCommandFieldQuality qualityField;
private clusterCommandFieldQuality? qualityField;

private object optionalConformField;

Expand Down Expand Up @@ -1956,4 +2016,5 @@ public bool toSpecified
}
}
}
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
}
4 changes: 2 additions & 2 deletions MatterDotNet/Clusters/AdministratorCommissioningCluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private record OpenCommissioningWindowPayload : TLVPayload {
public required ushort Discriminator { get; set; }
public required uint Iterations { get; set; }
public required byte[] Salt { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUShort(0, CommissioningTimeout);
writer.WriteBytes(1, PAKEPasscodeVerifier);
Expand All @@ -72,7 +72,7 @@ public override void Serialize(TLVWriter writer, long structNumber = -1) {

private record OpenBasicCommissioningWindowPayload : TLVPayload {
public required ushort CommissioningTimeout { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUShort(0, CommissioningTimeout);
writer.EndContainer();
Expand Down
4 changes: 2 additions & 2 deletions MatterDotNet/Clusters/BasicInformationCluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public enum ProductFinishEnum {
public record CapabilityMinima : TLVPayload {
public ushort? CaseSessionsPerFabric { get; set; } = 3;
public ushort? SubscriptionsPerFabric { get; set; } = 3;
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
if (CaseSessionsPerFabric != null)
writer.WriteUShort(0, CaseSessionsPerFabric);
Expand All @@ -168,7 +168,7 @@ public override void Serialize(TLVWriter writer, long structNumber = -1) {
public record ProductAppearance : TLVPayload {
public required ProductFinishEnum Finish { get; set; }
public required ColorEnum PrimaryColor { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUShort(0, (ushort)Finish);
writer.WriteUShort(1, (ushort)PrimaryColor);
Expand Down
2 changes: 1 addition & 1 deletion MatterDotNet/Clusters/DescriptorCluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public DescriptorCluster(ushort endPoint) : base(endPoint) { }
public record DeviceType : TLVPayload {
public required uint DeviceTypeField { get; set; }
public required ushort Revision { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUInt(0, DeviceTypeField);
writer.WriteUShort(1, Revision);
Expand Down
6 changes: 3 additions & 3 deletions MatterDotNet/Clusters/GeneralCommissioningCluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public enum RegulatoryLocationTypeEnum {
public record BasicCommissioningInfo : TLVPayload {
public required ushort FailSafeExpiryLengthSeconds { get; set; }
public required ushort MaxCumulativeFailsafeSeconds { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUShort(0, FailSafeExpiryLengthSeconds);
writer.WriteUShort(1, MaxCumulativeFailsafeSeconds);
Expand All @@ -95,7 +95,7 @@ public override void Serialize(TLVWriter writer, long structNumber = -1) {
private record ArmFailSafePayload : TLVPayload {
public required ushort ExpiryLengthSeconds { get; set; } = 900;
public required ulong Breadcrumb { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUShort(0, ExpiryLengthSeconds);
writer.WriteULong(1, Breadcrumb);
Expand All @@ -112,7 +112,7 @@ private record SetRegulatoryConfigPayload : TLVPayload {
public required RegulatoryLocationTypeEnum NewRegulatoryConfig { get; set; }
public required string CountryCode { get; set; }
public required ulong Breadcrumb { get; set; }
public override void Serialize(TLVWriter writer, long structNumber = -1) {
internal override void Serialize(TLVWriter writer, long structNumber = -1) {
writer.StartStructure(structNumber);
writer.WriteUShort(0, (ushort)NewRegulatoryConfig);
writer.WriteString(1, CountryCode);
Expand Down
Loading

0 comments on commit 0981e0c

Please sign in to comment.