Dahua VTO2111D-P-S2: registration flapping (nonce/nc reuse) + call media negotiation fails (PCM/16000)
Environment
- VoIP Stack version: 2026.8.0
- Home Assistant Core: 2026.7.3 (HAOS 18.1, running as a Proxmox VM,
--network=host)
- Device: Dahua VTO2111D-P-S2, firmware
V4.700.0.3, User-Agent: Dahua UAC/3.0 VTO2111D-P-S2
- SIP transport: UDP, port 5060
- Auth: local SIP account created in VoIP Stack (username
100, digest auth, realm="voip_stack")
- VTO configured as Third-party SIP server client (its own "SIP Server" toggle OFF), registering to HA.
Summary
A Dahua VTO can register to the VoIP Stack local registrar and signaling reaches HA, but I run into three separate Dahua-specific interop problems. All three are reproducible and I have full tcpdump traces for each.
1. Registration flapping (digest nonce / nc reuse)
The VTO reuses the same cnonce="0a4f113b" on every request and always sends nc=00000001. On the periodic re-REGISTER (Expires: 60) it also reuses the previous nonce. The result: one REGISTER succeeds with 200 OK, but subsequent refreshes with the same nonce/nc get 401, so the contact flaps online/offline roughly every 60 seconds.
Username in Authorization matches From/Contact (both 100), and response is recomputed correctly — it still gets 401 on refresh:
REGISTER sip:192.168.1.112 SIP/2.0
From: <sip:100@192.168.1.112:5060>;tag=...
To: <sip:100@192.168.1.112:5060>
Contact: <sip:100@192.168.1.108:5060>
Authorization: Digest username="100", realm="voip_stack",
nonce="3fc65932afe543221c87b7786c11246d", uri="sip:192.168.1.112",
response="5c298e37bcfba35afe8c7b4a3de856e4", algorithm=MD5,
cnonce="0a4f113b", qop=auth, nc=00000001
Expires: 60
User-Agent: Dahua UAC/3.0 VTO2111D-P-S2 V4.700.0.3
-> SIP/2.0 200 OK (first REGISTER)
-> SIP/2.0 401 Unauthorized (subsequent refreshes, same nonce + nc=00000001)
Question: can the registrar tolerate Dahua's non-incrementing nc / nonce reuse (or issue a fresh nonce) without dropping the binding, so the endpoint stays stable? Similar Dahua deployments report the device also expects OPTIONS/keepalive after registration.
tcpdump — registration flap (successful 200 OK surrounded by 401 refreshes)
# initial REGISTER (no auth) -> 401 challenge
18:20:38 In 192.168.1.108.5060 > 192.168.1.112.5060: REGISTER sip:192.168.1.112 SIP/2.0
Call-ID: 9ec5b5b1152be0e4341c0876f2f3fef4
From: <sip:100@192.168.1.112:5060>;tag=09dd7576ce183adb2a78115eb529b00c
Contact: <sip:100@192.168.1.108:5060>
CSeq: 1 REGISTER Expires: 60
18:20:38 Out 192.168.1.112.5060 > 192.168.1.108.5060: SIP/2.0 401 Unauthorized
WWW-Authenticate: Digest realm="voip_stack", nonce="e513d352dad9c93e767c1c17e98227e9", algorithm=MD5, qop="auth"
# authed REGISTER, username matches From/Contact, response recomputed
18:34:20 Out ... 401 Unauthorized
18:34:21 In 192.168.1.108.5060 > 192.168.1.112.5060: REGISTER sip:192.168.1.112 SIP/2.0
Authorization: Digest username="100", realm="voip_stack",
nonce="...", uri="sip:192.168.1.112",
response="faa90fe346dc97fbbb79d4416778a6ea", algorithm=MD5,
cnonce="0a4f113b", qop=auth, nc=00000001
Expires: 60
18:34:21 Out 192.168.1.112.5060 > 192.168.1.108.5060: SIP/2.0 200 OK <-- succeeds once
# next refresh reuses same nonce + nc=00000001 -> 401 again, contact flaps offline
18:34:49 Out ... SIP/2.0 401 Unauthorized
18:34:50 Out ... SIP/2.0 401 Unauthorized
18:34:51 Out ... SIP/2.0 401 Unauthorized
Note: across many capture sessions the cnonce is always 0a4f113b and nc is always 00000001.
2. Call media negotiation fails — VTO offers PCM/16000, HA sends BYE
Calling HA softphone -> VTO: INVITE -> 180 Ringing -> 200 OK, then HA immediately sends ACK followed by BYE, so the call drops right after answer.
HA offered:
a=rtpmap:98 OPUS/48000/2
a=rtpmap:8 PCMA/8000/1
a=rtpmap:0 PCMU/8000/1
a=rtpmap:96 L16/16000/1
VTO 200 OK SDP answer:
a=rtpmap:96 PCM/16000
a=rtpmap:99 telephone-event/8000
a=fmtp:99 0-15
a=sendrecv
a=rtpmap:103 H264/90000
a=sendonly
The VTO advertises Dahua wideband PCM/16000 (payload 96) for audio plus H264 sendonly video, which does not match HA's offered L16/16000 / PCMA / PCMU / OPUS. HA appears unable to select a common audio format and tears the call down with BYE right after ACK.
Question: is Dahua PCM/16000 (payload 96) meant to be treated as L16/16000, or is a G.711-only (PCMA/PCMU) path the expected way to interoperate with Dahua VTO? Is there a way to force/pin the negotiated audio codec for a given account or route?
tcpdump — HA softphone -> VTO: INVITE -> 180 -> 200 OK -> ACK -> immediate BYE
# HA offers OPUS / PCMA / PCMU / L16
17:55:43 Out 192.168.1.112.43269 > 192.168.1.108.5060: INVITE sip:DOORBELL@192.168.1.108:5060 SIP/2.0
From: <sip:Home%20Assistant@192.168.1.112:43269;transport=udp>;tag=2f112417ef5364c6
To: <sip:DOORBELL@192.168.1.108:5060>
a=rtpmap:98 OPUS/48000/2
a=rtpmap:8 PCMA/8000/1
a=rtpmap:0 PCMU/8000/1
a=rtpmap:96 L16/16000/1
17:55:43 In 192.168.1.108.5060 > 192.168.1.112.43269: SIP/2.0 180 Ringing
17:55:43 In 192.168.1.108.5060 > 192.168.1.112.43269: SIP/2.0 200 OK
Content-Type: application/sdp (VTO answer)
a=rtpmap:96 PCM/16000
a=rtpmap:99 telephone-event/8000
a=fmtp:99 0-15
a=sendrecv
a=rtpmap:103 H264/90000
a=sendonly
17:55:43 Out 192.168.1.112.43269 > 192.168.1.108.5060: ACK sip:DOORBELL@192.168.1.108:5060 SIP/2.0
17:55:43 Out 192.168.1.112.43269 > 192.168.1.108.5060: BYE sip:DOORBELL@192.168.1.108:5060 SIP/2.0
<-- HA hangs up immediately after ACK; call never streams audio
3. Button-call routing
- Pressing the door button also emits Dahua-proprietary
MESSAGE requests with alarm JSON (e.g. "SenseMethod": "DoorMagnetism"), which HA answers with 405 Method Not Allowed.
- The button's voice
INVITE targets the Dahua "management centre" number, not a normal phonebook contact.
- Routing the button call to a TCP-registered softphone yields
480 Temporarily Unavailable with X-Voip-Stack-Decline-Reason: transport_unreachable, because the VTO leg is UDP and the softphone registered over TCP.
INVITE sip:102@192.168.1.112 SIP/2.0 (from VTO, UDP)
-> SIP/2.0 480 Temporarily Unavailable
Reason: X-Voip-Stack;cause=480;text="transport_unreachable"
X-Voip-Stack-Decline-Reason: transport_unreachable
Question: is cross-transport bridging (UDP caller -> TCP-registered callee) expected to work through HA, or must both legs share a transport?
tcpdump — Dahua MESSAGE (alarm JSON) + UDP INVITE to TCP-registered softphone -> 480
# Dahua-proprietary MESSAGE on button/event -> 405
In 192.168.1.108.5060 > 192.168.1.112.5060: MESSAGE sip:100@192.168.1.112:5060 SIP/2.0
Content-Type: json/aplication
{ "Alarm": { "Channel": 5, "RoomNumber": "DOORBELL", "SenseMethod": "DoorMagnetism" } }
Out 192.168.1.112.5060 > 192.168.1.108.5060: SIP/2.0 405 Method Not Allowed
# VTO (UDP) INVITEs softphone registered over TCP -> transport_unreachable
In 192.168.1.108.5060 > 192.168.1.112.5060: INVITE sip:102@192.168.1.112:5060 SIP/2.0
From: <sip:DOORBELL@192.168.1.112>;tag=...
To: <sip:102@192.168.1.112:5060>
Out 192.168.1.112.5060 > 192.168.1.108.5060: SIP/2.0 480 Temporarily Unavailable
Reason: X-Voip-Stack;cause=480;text="transport_unreachable"
X-Voip-Stack-Decline-Reason: transport_unreachable
# the softphone in question is registered over TCP:
In 192.168.1.160.58266 > 192.168.1.112.5060: REGISTER sip:192.168.1.112:5060 SIP/2.0
Via: SIP/2.0/TCP 192.168.1.160:58266;alias;...
From: "phone" <sip:phone@192.168.1.112>;tag=...
Out SIP/2.0 200 OK
Notes
- Registration only became stable-ish once
From/Contact identity and the Authorization username were both aligned to the same value (100). Earlier the VTO put its device number (8001) in From/Contact while sending a different Authorization username, which never authenticated.
- I can attach full
tcpdump captures for registration (the 401/200 flap) and for the call (INVITE -> 200 OK -> BYE) on request.
Dahua VTO2111D-P-S2: registration flapping (nonce/nc reuse) + call media negotiation fails (PCM/16000)
Environment
--network=host)V4.700.0.3,User-Agent: Dahua UAC/3.0 VTO2111D-P-S2100, digest auth,realm="voip_stack")Summary
A Dahua VTO can register to the VoIP Stack local registrar and signaling reaches HA, but I run into three separate Dahua-specific interop problems. All three are reproducible and I have full
tcpdumptraces for each.1. Registration flapping (digest nonce / nc reuse)
The VTO reuses the same
cnonce="0a4f113b"on every request and always sendsnc=00000001. On the periodic re-REGISTER (Expires: 60) it also reuses the previousnonce. The result: one REGISTER succeeds with200 OK, but subsequent refreshes with the same nonce/nc get401, so the contact flaps online/offline roughly every 60 seconds.Username in
AuthorizationmatchesFrom/Contact(both100), andresponseis recomputed correctly — it still gets401on refresh:Question: can the registrar tolerate Dahua's non-incrementing
nc/ nonce reuse (or issue a fresh nonce) without dropping the binding, so the endpoint stays stable? Similar Dahua deployments report the device also expectsOPTIONS/keepalive after registration.tcpdump — registration flap (successful 200 OK surrounded by 401 refreshes)
Note: across many capture sessions the
cnonceis always0a4f113bandncis always00000001.2. Call media negotiation fails — VTO offers
PCM/16000, HA sends BYECalling HA softphone -> VTO:
INVITE->180 Ringing->200 OK, then HA immediately sendsACKfollowed byBYE, so the call drops right after answer.HA offered:
VTO
200 OKSDP answer:The VTO advertises Dahua wideband
PCM/16000(payload 96) for audio plus H264 sendonly video, which does not match HA's offeredL16/16000/PCMA/PCMU/OPUS. HA appears unable to select a common audio format and tears the call down withBYEright afterACK.Question: is Dahua
PCM/16000(payload 96) meant to be treated asL16/16000, or is a G.711-only (PCMA/PCMU) path the expected way to interoperate with Dahua VTO? Is there a way to force/pin the negotiated audio codec for a given account or route?tcpdump — HA softphone -> VTO: INVITE -> 180 -> 200 OK -> ACK -> immediate BYE
3. Button-call routing
MESSAGErequests with alarm JSON (e.g."SenseMethod": "DoorMagnetism"), which HA answers with405 Method Not Allowed.INVITEtargets the Dahua "management centre" number, not a normal phonebook contact.480 Temporarily UnavailablewithX-Voip-Stack-Decline-Reason: transport_unreachable, because the VTO leg is UDP and the softphone registered over TCP.Question: is cross-transport bridging (UDP caller -> TCP-registered callee) expected to work through HA, or must both legs share a transport?
tcpdump — Dahua MESSAGE (alarm JSON) + UDP INVITE to TCP-registered softphone -> 480
Notes
From/Contactidentity and theAuthorizationusername were both aligned to the same value (100). Earlier the VTO put its device number (8001) inFrom/Contactwhile sending a differentAuthorizationusername, which never authenticated.tcpdumpcaptures for registration (the 401/200 flap) and for the call (INVITE -> 200 OK -> BYE) on request.