The parameter existed so the predicate could be called without the gSOAP
headers, but src/CMakeLists.txt:163 sets WITH_GSOAP as a PUBLIC compile
definition on the zm target, so it already reaches the tests target that
links it. The test could name SOAP_FAULT directly all along, and passing
it in only meant every caller repeated the same constant.
The declaration and definition move inside the WITH_GSOAP guard, where
SOAP_FAULT is in scope, and the test is guarded to match.
The predicate stays a free function rather than folding back into
WaitForMessage: it is six conditions over two nullable strings, and
covering it in place would mean constructing an ONVIF object and a live
soap context. The comment now says that, instead of claiming a header
dependency that was not real.
Tests: 16 assertions unchanged and passing. Full suite 10160 assertions in
132 test cases. Builds clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Y6FieTwEXuLhhR4e2yiax
WaitForMessage decided whether a failed PullMessages was an authentication
refusal by looking only for auth wording in the SOAP fault string. That
misses two shapes:
- A camera that rejects at the HTTP layer never produces a SOAP envelope.
gSOAP returns the status code as the result and there is no fault to
read, so a 401 fell through to the generic "Failed to get ONVIF
messages!" branch. That branch logs at Error on every poll, where the
auth branch logs once and then drops to Debug, so a camera in this state
filled the log at the polling rate for as long as it stayed unhappy.
- Several cameras leave the fault string generic and name the reason only
in the fault detail, which was not examined at all.
Both now route through the auth branch. Recovery is unchanged: either
branch increments retry_count, unsubscribes and marks the monitor
unhealthy, so this only affects which message is logged and how often.
The predicate moves to ONVIFIsAuthError, outside the WITH_GSOAP guard so
it can be tested without the gSOAP headers. It takes SOAP_FAULT as an
argument rather than including gsoap to reach the constant. 403 stays out
of it: it is a refusal of a request that did authenticate, so
re-authenticating will not fix it and the generic path is right.
Also fixes the two log sites in this file that pass a 64-bit value to a
%ld conversion. seconds_until_termination and seconds_overdue are
chrono::seconds::rep, and seconds_until_renewal was already being cast to
intmax_t while the format still said %ld. On a 32-bit target that
misaligns the varargs list and prints garbage. Same defect and same fix as
refs #4580. Every other %ld in this file is already explicitly cast to
long and is left alone.
Tests: tests/zm_onvif_auth_error.cpp, 16 assertions. Verified they fail
(2 of 16) against the previous predicate. Full suite: 10160 assertions in
132 test cases, all pass. Builds clean, no new warnings.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Y6FieTwEXuLhhR4e2yiax