Files
Marc Schier 87dcfc10cf Merge origin/capture into channelrefinements2
Brings the packet-capture / dissection / replay engine
(Opc.Ua.Bindings.Pcap) onto the channel-refinements branch so it
composes cleanly with the central IClientChannelManager work landed in
PR #3852 (channelrefinements).

Conflicts resolved:
- Applications/McpServer/Program.cs: union of both ConfigureServices
  changes — registers AddOpcUa().AddClient() (channel manager) AND
  AddOpcUaBindingsPcap() / Formatters / Replay (capture). Channel
  manager picks up the capture binding automatically via the shared
  TransportBindings.Channels registry.
- Stack/Opc.Ua.Core/Stack/Tcp/TcpListenerChannel.cs: keep both
  m_sessionCount (channelrefinements2) and m_tokenActivated event
  (origin/capture). Server-side capture relies on
  TcpListenerChannel.OnTokenActivated to snapshot per-channel
  ChannelToken keys for offline decoding.
- UA.slnx: keep both Opc.Ua.Di.Tests and Opc.Ua.Bindings.Pcap.Tests
  project entries.

Pre-existing fix folded in (build-blocker introduced earlier on
channelrefinements2, not by the capture merge):
- Applications/Quickstarts.Servers/ReferenceServer/ReferenceServerConfigurationNodeManager.cs
  s_optionalPubSubFolders previously referenced ObjectIds.SecurityGroups
  and ObjectIds.KeyPushTargets, neither of which exists on the curated
  Stack/Opc.Ua.Types/Internal/ObjectIds.cs surface. Inlined the
  NodeId literals (i=15443 / i=25440) per the docstring above the
  array so the merged tree builds end-to-end across all TFMs and
  every transitive test project (Tests/Opc.Ua.Client.Tests,
  Tests/Opc.Ua.Sessions.Tests, etc.) compiles.

Architectural fit ("take advantage of all the changes you made here"):

1. Pcap integrates with the central channel manager via the global
   TransportBindings.Channels registry. ClientChannelManager.ctor
   accepts an injected ITransportChannelBindings? that defaults to the
   global registry, so the Pcap binding installed by
   AddOpcUaBindingsPcap is automatically picked up by every channel
   created through the manager. No code wiring needed — the
   composition is pure layering.

2. Channel sharing transparently includes capture. When multiple
   participants share a single IManagedTransportChannel (the F1
   refcount + key-equivalence work), the underlying CapturingMessageSocket
   captures all participant traffic on the same wire, automatically.

3. Transparent reconnect preserves the capture session. The F8
   diagnostics events on ClientChannelManager (state-change /
   close notifications) and the Phase E SwapFaultedEntryAsync swap
   path produce fresh ChannelEntry instances under the same
   ManagedChannelKey — IChannelCaptureRegistry is keyed by channel
   identity, so a swap rolls the active observer into the new entry
   and the capture session continues recording across the
   reconnect / faulted-swap cycle.

4. MCP server composes both: services.AddOpcUa().AddClient() (channel
   manager + DI), services.AddSingleton<OpcUaSessionManager>(),
   services.AddOpcUaBindingsPcap() (capture binding). OpcUaSessionManager
   resolves IClientChannelManager from IServiceProvider; the Pcap tools
   (Tools/PacketCapture/Decode/ReplayTools.cs) resolve
   CaptureSessionManager and IChannelCaptureRegistry from the same
   provider.

Verified locally on net10.0:
- Stack/Opc.Ua.Bindings.Pcap build: 0 warnings, 0 errors.
- Libraries/Opc.Ua.Client build (channel manager): 0 warnings, 0 errors.
- Tests/Opc.Ua.Bindings.Pcap.Tests: 53/53 passed.
- Tests/Opc.Ua.Client.Tests ClientChannelManager filter: 29/29 passed.
- Tests/Opc.Ua.Sessions.Tests ChannelManager filter: 7/7 passed,
  1 skipped (RequiresSessionRecreate carry-forward).
- Applications/McpServer build: 0 warnings, 0 errors.
2026-06-08 10:01:45 +02:00

58 lines
2.7 KiB
XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(LibCoreTargetFrameworks)</TargetFrameworks>
<AssemblyName>$(AssemblyPrefix).Core</AssemblyName>
<PackageId>$(PackagePrefix).Opc.Ua.Core</PackageId>
<RootNamespace>Opc.Ua</RootNamespace>
<Description>OPC UA Core Class Library</Description>
<IsPackable>true</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net10.0'))">true</IsAotCompatible>
<NoWarn>$(NoWarn);MODELGEN002</NoWarn>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="Opc.Ua.Core.Tests" />
<InternalsVisibleTo Include="Opc.Ua.Core.TestFramework" />
<InternalsVisibleTo Include="Opc.Ua.Core.Encoders.Tests" />
<InternalsVisibleTo Include="Opc.Ua.Security.Certificates.Tests" />
<InternalsVisibleTo Include="Opc.Ua.MigrationAnalyzer.Core" />
<InternalsVisibleTo Include="Opc.Ua.Bindings.Pcap" />
<InternalsVisibleTo Include="Opc.Ua.Bindings.Pcap.Tests" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<PackageId>$(PackageId).Debug</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics" />
<PackageReference Include="Microsoft.Extensions.Http" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Bcl.TimeProvider" />
<PackageReference Include="System.Threading.Channels" />
<PackageReference Include="BitFaster.Caching" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48' OR '$(TargetFramework)' == 'net472'">
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Opc.Ua.Security.Certificates\Opc.Ua.Security.Certificates.csproj" />
<ProjectReference Include="..\Opc.Ua.Core.Types\Opc.Ua.Core.Types.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Types\Utils\LocalizedData.txt" />
</ItemGroup>
<!-- Stack source generation -->
<ItemGroup>
<ProjectReference Include="..\..\Tools\Opc.Ua.SourceGeneration.Stack\Opc.Ua.SourceGeneration.Stack.csproj">
<OutputItemType>Analyzer</OutputItemType>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\Tools\Opc.Ua.SourceGeneration\Opc.Ua.SourceGeneration.csproj">
<OutputItemType>Analyzer</OutputItemType>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Target Name="GetPackagingOutputs" />
</Project>