Brings in three new commits on capture:
- 117f2212d Simplify token-activated subscription (channel is always ISecureChannel) (CA1508)
- f07501e0e Merge origin/master into capture
- daf3c8a8b Address PR review feedback (3 unresolved threads)
Auto-merged cleanly (no conflicts) — my "Integration with the central
channel manager" section in Docs/PacketCapture.md was preserved
unchanged alongside the capture-branch documentation tweaks (McpServer.md,
MigrationGuide.md, README.md, deletion of PacketCaptureFileFormats.md).
Folded in one nullability fix to make McpServer build:
- Applications/McpServer/Tools/PacketDecodeTools.cs:
CreateActiveChannelInfo assigned EndpointDescription.EndpointUrl and
.SecurityPolicyUri (both nullable strings) to ActiveChannelInfo's
non-nullable string init properties, triggering CS8601 under the
capture branch's strict nullability settings. Coalesce to string.Empty
to match the default-init pattern used by ActiveChannelInfo itself.
Verified locally on net10.0:
- Stack/Opc.Ua.Bindings.Pcap build: 0 warnings, 0 errors.
- Applications/McpServer build: 0 warnings, 0 errors.
- Tests/Opc.Ua.Bindings.Pcap.Tests: 53/53 passed.
- Tests/Opc.Ua.Client.Tests ClientChannelManager filter: 29/29 passed.
Add a dedicated 'Integration with the central channel manager' section
to Docs/PacketCapture.md spelling out the three properties of the
channel manager (sharing, transparent reconnect, faulted-entry swap)
that flow through to capture for free, plus the standard DI
registration order. Update the in-process-client quick-start to show
the channel manager registered alongside the Pcap binding.
Add a back-link from Docs/Sessions.md 'See also' so readers of the
channel-manager doc discover the capture composition.
* Docs/PacketCapture.md: removed the duplicate 'MCP tool reference' section, moved into Docs/McpServer.md where the rest of the MCP tool surface lives.
* Docs/PacketCaptureFileFormats.md: inlined into Docs/PacketCapture.md (as 'File format reference' section) and deleted the standalone file. Removed the link from Docs/README.md.
* Docs/MigrationGuide.md: removed the orphaned 'Packet capture diagnostics hooks' TOC entry (the corresponding section was already removed in 67e803c, the TOC entry was missed).
Three changes addressing the design feedback on PR #3855:
1. Renamed Stack/Opc.Ua.Diagnostics.Pcap -> Stack/Opc.Ua.Bindings.Pcap (and the corresponding test project). PackageId, AssemblyName and RootNamespace updated to Opc.Ua.Bindings.Pcap; references in McpServer, signlists, slnx files, docs, and the interop-tester agent updated; Opc.Ua.Core's InternalsVisibleTo entries updated.
2. Replaced UaSCUaBinaryChannel.FrameCaptureSink + per-call NotifyFrameCaptureSink null check with a transport-binding decorator. New files in Opc.Ua.Bindings.Pcap/Bindings:
- IChannelCaptureRegistry / ChannelCaptureRegistry: singleton with a volatile IFrameCaptureSink slot (1 atomic write to switch recording on/off).
- CapturingMessageSocket / CapturingMessageSocketFactory: IMessageSocket decorator that taps Send/Receive bytes via a single volatile read of CurrentObserver.
- PcapTransportChannelBinding: ITransportChannelFactory decorator that injects the capturing socket factory into every TcpTransportChannel and wires ISecureChannel.OnTokenActivated through to the active observer.
- PcapBindings.Install(): non-DI installer for direct TransportBindings.Channels.SetBinding wiring.
IFrameCaptureSink moved to Opc.Ua.Core/Stack/Bindings and gained an OnTokenActivated method so the binding can publish key material alongside chunks. UaSCUaBinaryChannel.FrameCaptureSink property and all three NotifyFrameCaptureSink call sites removed - hot path returns to original shape with zero indirection when the binding is not installed. IMessageSocketAsyncEventArgs gains Offset + Count getters (additive).
AddOpcUaDiagnosticsPcap/Formatters/Replay extension methods renamed to AddOpcUaBindingsPcap[Formatters|Replay]; the new AddOpcUaBindingsPcap also installs the binding into TransportBindings.Channels.
InProcessClientCaptureSource / InProcessServerCaptureSource: dropped reflection-based AttachClientChannel/AttachServerChannel. The source itself implements IFrameCaptureSink and on Start publishes itself as the registry observer; on Stop clears it. McpServer's PacketCaptureTools simplified accordingly (no more per-channel attach loop).
3. Discarded the source-generator suggestion. Confirmed that the dissection path already 100% reuses the source-generated decoders: UaSCUaBinaryChannel.ReadSymmetricMessage for chunk decryption and BinaryDecoder.ReadEncodeable + EncodeableFactory.GlobalFactory (populated by Tools/Opc.Ua.SourceGeneration's DataTypeGenerator) for service-type decoding. Emitting additional dissection code would duplicate what's already there.
Validation:
- Full UA.slnx builds clean: 0 errors, 2 pre-existing unrelated warnings.
- All 53 tests pass on net10.0 (49 existing + 4 new CapturingMessageSocketTests covering hot-path: not-installed/installed-off/installed-on costs, byte equality, exception isolation).
- CI command line (dotnet build/test --framework net10.0 --configuration Release /p:CustomTestTarget=net10.0) reproduces clean locally.
Adds a new diagnostics library (Stack/Opc.Ua.Diagnostics.Pcap) plus 13 MCP tools that capture OPC UA traffic, decode it offline by reusing the stack's own UaSCUaBinaryChannel, and replay it. Includes additive stack hooks (IFrameCaptureSink, TcpListenerChannel.OnTokenActivated), four capture sources (nic / inproc-client / inproc-server / replay), two keylog formats (.uakeys.json, .uakeys.txt), six output formats (pcap, pcapng, json, csv, text, service-timeline), and mock-server / mock-client replay engines. 49 new tests pass; no regressions in the 163 existing transport tests; full UA.slnx builds clean.