Skip to content

Commit

Permalink
Add Backwards compatibility for ArtNet 1/2 in ArtPollReply
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-dmxc committed Nov 29, 2023
1 parent 21d87bc commit b7595f7
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 40 deletions.
1 change: 1 addition & 0 deletions ArtNetSharp/ArtNetSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<Company>DMXControl-Projects e.V.</Company>
<Authors>Patrick Grote</Authors>
<Title>$(AssemblyName)</Title>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions ArtNetSharp/Communication/AbstractInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ private async Task sendArtPollReply(IPv4Address ownIp, IPv4Address destinationIp
MinorVersion,
net,
subnet,
new Universe[0],
new Universe[0],
new object[0],
new object[0],
OEMProductCode,
ESTAManufacturerCode,
nodeReport: nodeReport);
Expand Down
22 changes: 13 additions & 9 deletions ArtNetSharp/Communication/RemoteClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public ArtPollReply Root
this.IsArtNet4Capable = root.Status.HasFlag(ENodeStatus.NodeSupports15BitPortAddress);
}
}
private ConcurrentDictionary<byte, RemoteClientPort> ports= new ConcurrentDictionary<byte, RemoteClientPort>();
private ConcurrentDictionary<int, RemoteClientPort> ports= new ConcurrentDictionary<int, RemoteClientPort>();
public IReadOnlyCollection<RemoteClientPort> Ports { get; private set; }
public event EventHandler<RemoteClientPort> PortDiscovered;
public event EventHandler<RemoteClientPort> PortTimedOut;
Expand Down Expand Up @@ -260,16 +260,20 @@ public void processArtPollReply(ArtPollReply artPollReply)
return;
try
{
RemoteClientPort port = null;
if (ports.TryGetValue(artPollReply.BindIndex, out port))
port.processArtPollReply(artPollReply);
else
for (byte portIndex = 0; portIndex < artPollReply.Ports; portIndex++)
{
port = new RemoteClientPort(artPollReply);
if (ports.TryAdd(port.BindIndex, port))
int physicalPort = ((artPollReply.BindIndex - 1) * artPollReply.Ports) + portIndex;
RemoteClientPort port = null;
if (ports.TryGetValue(physicalPort, out port))
port.processArtPollReply(artPollReply);
else
{
PortDiscovered?.Invoke(this, port);
port.RDMUIDReceived += Port_RDMUIDReceived;
port = new RemoteClientPort(artPollReply, portIndex);
if (ports.TryAdd(physicalPort, port))
{
PortDiscovered?.Invoke(this, port);
port.RDMUIDReceived += Port_RDMUIDReceived;
}
}
}
}
Expand Down
29 changes: 21 additions & 8 deletions ArtNetSharp/Communication/RemoteClientPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public sealed class RemoteClientPort : INotifyPropertyChanged
public readonly string ID;
public readonly byte BindIndex;
public readonly byte PortIndex;
public readonly int PhysicalPort;
private DateTime lastSeen;
public DateTime LastSeen
{
Expand Down Expand Up @@ -160,16 +161,18 @@ internal byte Sequence

public RemoteClientPort(in ArtPollReply artPollReply, byte portIndex = 0)
{
ID = getIDOf(artPollReply);
ID = getIDOf(artPollReply, portIndex);
IpAddress = artPollReply.OwnIp;
BindIndex = artPollReply.BindIndex;
PortIndex = portIndex;
PhysicalPort = ((BindIndex - 1) * artPollReply.Ports) + portIndex;
processArtPollReply(artPollReply);
KnownRDMUIDs = knownRDMUIDs.Values.ToList().AsReadOnly();
}
public static string getIDOf(ArtPollReply artPollReply)
public static string getIDOf(ArtPollReply artPollReply, byte portIndex)
{
return $"{RemoteClient.getIDOf(artPollReply)}==>{artPollReply.BindIndex}";
int physicalPort = ((artPollReply.BindIndex - 1) * artPollReply.Ports) + portIndex;
return $"{RemoteClient.getIDOf(artPollReply)}==>{physicalPort}";
}

public void processArtPollReply(ArtPollReply artPollReply)
Expand All @@ -186,17 +189,27 @@ public void processArtPollReply(ArtPollReply artPollReply)
PortType = artPollReply.PortTypes[PortIndex];
GoodOutput = artPollReply.GoodOutput[PortIndex];
GoodOutput = artPollReply.GoodOutput[PortIndex];
Universe output = artPollReply.OutputUniverses[PortIndex];
Universe input = artPollReply.InputUniverses[PortIndex];
var output = artPollReply.OutputUniverses[PortIndex];
var input = artPollReply.InputUniverses[PortIndex];
IsRDMCapable = artPollReply.Status.HasFlag(ENodeStatus.RDM_Supported) && !GoodOutput.HasFlag(EGoodOutput.RDMisDisabled);

if (PortType.HasFlag(EPortType.OutputFromArtNet))
OutputPortAddress = new PortAddress(artPollReply.Net, artPollReply.Subnet, output);
{
if (output is Universe outputUniverse)
OutputPortAddress = new PortAddress(artPollReply.Net, artPollReply.Subnet, outputUniverse);
else if (output is Address outputAddress)
OutputPortAddress = new PortAddress(outputAddress);
}
else
OutputPortAddress = null;

if (PortType.HasFlag(EPortType.InputToArtNet))
InputPortAddress = new PortAddress(artPollReply.Net, artPollReply.Subnet, input);
{
if (input is Universe inputUniverse)
InputPortAddress = new PortAddress(artPollReply.Net, artPollReply.Subnet, inputUniverse);
else if (input is Address inputAddress)
InputPortAddress = new PortAddress(inputAddress);
}
else
InputPortAddress = null;

Expand Down Expand Up @@ -249,7 +262,7 @@ internal void ProcessArtRDM(ArtRDM artRDM)

public override string ToString()
{
return $"{nameof(RemoteClientPort)}: {IpAddress}#{BindIndex}";
return $"{nameof(RemoteClientPort)}: {IpAddress}#{BindIndex},{PortIndex}";
}
}
}
112 changes: 91 additions & 21 deletions ArtNetSharp/Messages/ArtPollReply.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public sealed class ArtPollReply: AbstractArtPacketCore
/// </summary>
public readonly Net Net;
public readonly Subnet Subnet;
public readonly Universe[] OutputUniverses;
public readonly Universe[] InputUniverses;
public readonly object[] OutputUniverses;
public readonly object[] InputUniverses;
public readonly byte UbeaVersion;
public readonly ENodeStatus Status;
/// <summary>
Expand All @@ -54,6 +54,61 @@ public sealed class ArtPollReply: AbstractArtPacketCore
public readonly RDMUID? DefaulRespUID;

private const byte MaxPortCount = 4;
public ArtPollReply(in IPv4Address ownIp,
in IPv4Address bindIp,
in MACAddress mac,
in string shortName,
in string longName,
in byte bindIndex,
in ENodeStatus status,
in byte majorVersion,
in byte minorVersion,
in Address outputUniverse,
in Address inputUniverse,
in ushort oemCode = Constants.DEFAULT_OEM_CODE,
in ushort manufacturerCode = Constants.DEFAULT_ESTA_MANUFACTURER_CODE,
in NodeReport? nodeReport = null,
in EPortType portType = default,
in EGoodInput goodInput = default,
in EGoodOutput goodOutput = default,
in EMacroState macro = EMacroState.None,
in ERemoteState remote = ERemoteState.None,
in byte ubeaVersion = 0,
in byte acnPriority = 0,
in ushort user = 0,
in ushort refreshRate = 0,
in EStCodes style = EStCodes.StController,
in RDMUID? defaulRespUID = null)
: this(ownIp,
bindIp,
mac,
shortName,
longName,
bindIndex,
status & ~ENodeStatus.NodeSupports15BitPortAddress,
majorVersion,
minorVersion,
0,
0,
new object[] { outputUniverse },
new object[] { inputUniverse },
oemCode,
manufacturerCode,
1,
nodeReport,
new EPortType[] { portType },
new EGoodInput[] { goodInput },
new EGoodOutput[] { goodOutput },
macro,
remote,
ubeaVersion,
acnPriority,
user,
refreshRate,
style,
defaulRespUID)
{
}
public ArtPollReply(in IPv4Address ownIp,
in IPv4Address bindIp,
in MACAddress mac,
Expand Down Expand Up @@ -87,13 +142,13 @@ public ArtPollReply(in IPv4Address ownIp,
shortName,
longName,
bindIndex,
status,
status | ENodeStatus.NodeSupports15BitPortAddress,
majorVersion,
minorVersion,
net,
subNet,
new Universe[] { outputUniverse },
new Universe[] { inputUniverse },
new object[] { outputUniverse },
new object[] { inputUniverse },
oemCode,
manufacturerCode,
1,
Expand Down Expand Up @@ -122,8 +177,8 @@ public ArtPollReply(in IPv4Address ownIp,
in byte minorVersion,
in Net net,
in Subnet subNet,
in Universe[] outputUniverses,
in Universe[] inputUniverses,
in object[] outputUniverses,
in object[] inputUniverses,
in ushort oemCode = Constants.DEFAULT_OEM_CODE,
in ushort manufacturerCode = Constants.DEFAULT_ESTA_MANUFACTURER_CODE,
in byte ports = 1,
Expand Down Expand Up @@ -249,15 +304,6 @@ public ArtPollReply(in byte[] packet) : base(packet)
for (int i = 0; i < 4; i++)
goodOutputA.Add((EGoodOutput)packet[182 + i]);

// 23 SwIn [4] Input Universe
List<Universe> swIn = new List<Universe>();
for (int i = 0; i < 4; i++)
swIn.Add((Universe)packet[186 + i]);

// 24 SwIn [4] Input Universe
List<Universe> swOut = new List<Universe>();
for (int i = 0; i < 4; i++)
swOut.Add((Universe)packet[190 + i]);

AcnPriority = packet[194]; // 25 AcnPriority
Macro = (EMacroState)packet[195]; // 26 SwMacro
Expand Down Expand Up @@ -311,7 +357,31 @@ public ArtPollReply(in byte[] packet) : base(packet)

// 53 Filler 11x8

// 23 SwIn [4] Input Universe
List<object> swIn = new List<object>();
// 24 SwIn [4] Input Universe
List<object> swOut = new List<object>();

Status = (ENodeStatus)((status3 << 16) + (status2 << 8) + status1);
if (!Status.HasFlag(ENodeStatus.NodeSupports15BitPortAddress))
{
for (int i = 0; i < 4; i++)
swIn.Add((Address)packet[186 + i]);

for (int i = 0; i < 4; i++)
swOut.Add((Address)packet[190 + i]);

Net = 0;
Subnet = 0;
}
else
{
for (int i = 0; i < 4; i++)
swIn.Add((Universe)packet[186 + i]);

for (int i = 0; i < 4; i++)
swOut.Add((Universe)packet[190 + i]);
}

List<EGoodOutput> goodOutput = new List<EGoodOutput>();
for(int i = 0; i < goodOutputA.Count; i++)
Expand Down Expand Up @@ -376,14 +446,14 @@ protected sealed override void fillPacketCore(ref byte[] p)
//p[186] = ReceiveUniverse;
if (InputUniverses != null)
for (int i = 0; i < InputUniverses.Length; i++)
p[186 + i] = InputUniverses[i];
p[186 + i] = InputUniverses[i] is Universe? (Universe)InputUniverses[i]: (Address)InputUniverses[i];

// 24 SwIn [4] Input Universe
//p[190] = SendUniverse;
if (OutputUniverses != null)
for (int i = 0; i < OutputUniverses.Length; i++)
p[190 + i] = OutputUniverses[i];
p[190 + i] = OutputUniverses[i] is Universe ? (Universe)OutputUniverses[i] : (Address)OutputUniverses[i];

p[194] = AcnPriority; // 25 AcnPriority
p[195] = (byte)Macro; // 26 SwMacro
p[196] = (byte)Remote; // 27 SwRemote
Expand Down Expand Up @@ -488,8 +558,8 @@ public override int GetHashCode()
hashCode = hashCode * -1521134295 + RefreshRate.GetHashCode();
hashCode = hashCode * -1521134295 + Net.GetHashCode();
hashCode = hashCode * -1521134295 + Subnet.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<Universe[]>.Default.GetHashCode(OutputUniverses);
hashCode = hashCode * -1521134295 + EqualityComparer<Universe[]>.Default.GetHashCode(InputUniverses);
hashCode = hashCode * -1521134295 + OutputUniverses.GetHashCode();
hashCode = hashCode * -1521134295 + InputUniverses.GetHashCode();
hashCode = hashCode * -1521134295 + UbeaVersion.GetHashCode();
hashCode = hashCode * -1521134295 + Status.GetHashCode();
hashCode = hashCode * -1521134295 + AcnPriority.GetHashCode();
Expand Down

0 comments on commit b7595f7

Please sign in to comment.