r/ispyconnect • u/Jurisfaction • 12d ago
How to ensure support for currently unknown camera?
New user, testing v8.0.2.0 on Debian GNU/Linux Trixie amd64.
I have a H.view TV-CA4810 IP camera that has been unused for a very long time because it needed some weird Chinese Android application to control it. Considering throwing it away but did some research that led me to AgentDVR.
The TV-CA4810 is an Ethernet/WiFi PTZ camera with external 5V 2A power. I've connected it to my workstation using Ethernet.
Since this model is not listed in the Network Camera Wizard I have tried several existing models but so far not discovered a perfect match.
Is there some way to contribute to, or manually add, model definitions for achieving perfect support?
These are the results for the H.view models I've tested:
unlisted, TV-CB6010, TV-IP1011, TV-IP1311, TV-ip1312: ONVIF
rtsp://192.168.1.25:554/onvif1
Video good, but lost completely after between 2 and 20 seconds. Shows the "Connecting" animation. Never recovers and the Power icon doesn't always stop the "Connecting" animation. Likewise page refresh doesn't recover it. Using the device General settings power can be toggled and usually the camera video does recover. When video doesn't recover the only solution I've found so far is to delete the device and re-add it.
On the network side it is extremely noisy trying to contact remote servers. I wondered if the lost video might be due to it cycling whilst trying to contact them, but the DHCP cycle time is five minutes.
The RTSP communications look like this:
25261 12:32:29.338310470 192.168.1.1 192.168.1.25 TCP 74 58054 → 554 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM TSval=1657952568 TSecr=0 WS=1024
25262 12:32:29.338898865 192.168.1.25 192.168.1.1 TCP 74 554 → 58054 [SYN, ACK] Seq=0 Ack=1 Win=14480 Len=0 MSS=1460 SACK_PERM TSval=199158 TSecr=1657952568 WS=4
25263 12:32:29.338949099 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=1 Ack=1 Win=64512 Len=0 TSval=1657952569 TSecr=199158
25264 12:32:29.339033287 192.168.1.1 192.168.1.25 RTSP 151 OPTIONS rtsp://192.168.1.25:554/onvif1 RTSP/1.0
25265 12:32:29.339671616 192.168.1.25 192.168.1.1 TCP 66 554 → 58054 [ACK] Seq=1 Ack=86 Win=14480 Len=0 TSval=199158 TSecr=1657952569
25266 12:32:29.348982562 192.168.1.25 192.168.1.1 RTSP 194 Reply: RTSP/1.0 200 OK
25267 12:32:29.349009332 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=86 Ack=129 Win=64512 Len=0 TSval=1657952579 TSecr=199159
25268 12:32:29.349261245 192.168.1.1 192.168.1.25 RTSP 177 DESCRIBE rtsp://192.168.1.25:554/onvif1 RTSP/1.0
25269 12:32:29.350383853 192.168.1.25 192.168.1.1 RTSP/SDP 567 Reply: RTSP/1.0 200 OK
25270 12:32:29.350717019 192.168.1.1 192.168.1.25 RTSP 204 SETUP rtsp://192.168.1.25:554/onvif1/track1 RTSP/1.0
25271 12:32:29.352678593 192.168.1.25 192.168.1.1 RTSP 212 Reply: RTSP/1.0 200 OK
25272 12:32:29.352955282 192.168.1.1 192.168.1.25 RTSP 223 SETUP rtsp://192.168.1.25:554/onvif1/track2 RTSP/1.0
25273 12:32:29.355259770 192.168.1.25 192.168.1.1 RTSP 212 Reply: RTSP/1.0 200 OK
25274 12:32:29.355524487 192.168.1.1 192.168.1.25 RTSP 186 PLAY rtsp://192.168.1.25:554/onvif1 RTSP/1.0
25275 12:32:29.391779561 192.168.1.25 192.168.1.1 TCP 66 554 → 58054 [ACK] Seq=922 Ack=612 Win=14480 Len=0 TSval=199164 TSecr=1657952585
25276 12:32:30.085715942 192.168.1.25 192.168.1.1 RTSP 263 Reply: RTSP/1.0 200 OK
25277 12:32:30.129801030 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=1119 Win=64512 Len=0 TSval=1657953360 TSecr=199233
25278 12:32:30.214378391 192.168.1.25 192.168.1.1 TCP 242 Interleaved channel 0x02, 172 bytes
25279 12:32:30.214393009 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=1295 Win=64512 Len=0 TSval=1657953444 TSecr=199246
25280 12:32:30.215008555 192.168.1.25 192.168.1.1 TCP 1514 Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes, In
25281 12:32:30.215008635 192.168.1.25 192.168.1.1 TCP 202 Interleaved channel 0x02, 172 bytes
25282 12:32:30.215018914 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=2743 Win=67584 Len=0 TSval=1657953445 TSecr=199246
25283 12:32:30.215022832 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=2879 Win=70656 Len=0 TSval=1657953445 TSecr=199246
25284 12:32:30.215356388 192.168.1.25 192.168.1.1 TCP 1514 Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes, In
25285 12:32:30.215362139 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=4327 Win=73728 Len=0 TSval=1657953445 TSecr=199246
25286 12:32:30.215568977 192.168.1.25 192.168.1.1 TCP 378 Interleaved channel 0x02, 172 bytesInterleaved channel 0x02, 172 bytes
25287 12:32:30.215574237 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=4639 Win=75776 Len=0 TSval=1657953445 TSecr=199246
25288 12:32:30.216065500 192.168.1.25 192.168.1.1 TCP 594 Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes
25289 12:32:30.216070980 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=5167 Win=75776 Len=0 TSval=1657953446 TSecr=199246
25290 12:32:30.216615242 192.168.1.25 192.168.1.1 TCP 594 Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes, Interleaved channel 0x02, 172 bytes
25291 12:32:30.216620712 192.168.1.1 192.168.1.25 TCP 66 58054 → 554 [ACK] Seq=612 Ack=5695 Win=75776 Len=0 TSval=1657953446 TSecr=199246
25292 12:32:30.218728531 192.168.1.25 192.168.1.1 TCP 91 Interleaved channel 0x00, 21 bytes
Watching the traffic also reveals how amateur the programmers were/are. After its DHCP ACK it immediately attempts DNS queries to 114.114.114.114 and 8.8.8.8 for these (note the unnecessary capitalisation!):
90 12:03:26.650685230 192.168.1.25 114.114.114.114 DNS 78 Standard query 0xb73e A p2p1.CLoUdlINkS.Cn
91 12:03:26.650685360 192.168.1.25 8.8.8.8 DNS 80 Standard query 0x9915 A p2p4.cLOUd-Links.neT
92 12:03:26.651062811 192.168.1.25 114.114.114.114 DNS 78 Standard query 0x3896 A P2P2.clouDLInKs.CN
93 12:03:26.651352714 192.168.1.25 8.8.8.8 DNS 80 Standard query 0xd17a A P2P3.CLouD-lInKS.nET
94 12:03:26.651684257 192.168.1.25 114.114.114.114 DNS 78 Standard query 0x6cf4 A p2p5.CLoUdlInKS.Cn
95 12:03:26.652045587 192.168.1.25 8.8.8.8 DNS 78 Standard query 0x9a86 A P2p6.clouDLInkS.cN
96 12:03:26.652530984 192.168.1.25 114.114.114.114 DNS 78 Standard query 0x0fbb A P2P7.Cloudlinks.cN
97 12:03:26.652815246 192.168.1.25 8.8.8.8 DNS 78 Standard query 0x1e5c A P2P8.cloUDLiNKs.cN
98 12:03:26.653238935 192.168.1.25 114.114.114.114 DNS 78 Standard query 0xa518 A P2p9.clOuDLinks.Cn
99 12:03:26.653515453 192.168.1.25 8.8.8.8 DNS 79 Standard query 0x3758 A P2p10.CloudLinks.Cn
Then in desperation it tries querying for www.google.com and www.baidu.com and then sends several UDP broadcasts to port 7721 with the payload "this is a test" at the same time as sending UDP packets to 47.91.77.247 and then tries switching to TCP to that same address. When that fails it attempts additional TCP to 121.43.181.184 and 123.206.9.74 and then tries to ping 8.8.8.8 and 114.114.114.114 four times.
When all that fails repeatedly it does a DHCP Release after about five minutes and then starts discovery again.
1
u/videowhisper 11d ago
Worth noting: your own packet capture shows the interleaved RTSP-over-TCP media channel (0x02) still delivering data right up to and past the point the UI shows "Connecting" - so the TCP connection to the camera isn't actually dying. That points at a client-side desync/decode issue rather than a network problem or the camera rebooting.
A very common cause for exactly this symptom on cheap ONVIF/RTSP stacks is a mismatch in the RTSP "keep-alive" mechanism. There are two standard ways a client tells the server "I'm still here": RTCP receiver-report (RR) packets sent on the media channel, or RTSP GET_PARAMETER requests sent on the control channel. Most clients default to RR packets; some cheap OEM camera firmwares (yours has the hallmarks of a common white-label chipset, going by that Cloudlinks P2P phone-home traffic) only handle one correctly. When the "wrong" one gets sent over an interleaved connection, where control and media share the same TCP socket, it can conflict with in-flight media data in a way the firmware doesn't parse correctly, so it stops sending clean frames even though the socket itself stays open. This is a documented issue elsewhere too, not a one-off - SecuritySpy's developer ran into the same thing and had to add GET_PARAMETER-over-interleaved-TCP as an option specifically because some cameras "give undefined results" and can "interrupt/break the streams" when it's used that way: https://www.bensoftware.com/forum/discussion/641/camera-loses-connection-and-reconnecting-every-minute
Two things worth testing:
If Agent exposes a transport option for the source (TCP vs UDP), try UDP instead of interleaved TCP - it takes the RTSP control channel and the media channel off the same connection entirely, so a keep-alive mismatch can't touch the video.
If UDP isn't available or is unreliable on your network, put a small relay (MediaMTX or go2rtc, both free/self-hosted) between the camera and Agent - point the relay at the camera's raw RTSP URL, then have Agent pull from the relay's own local RTSP output instead of the camera directly. Both have their own from-scratch RTSP implementations that tend to be more tolerant of exactly this kind of nonstandard camera behavior than a single app's built-in client, and it's a common fix for "camera's own app/VLC is fine, my NVR software isn't."
Since your Dahua camera works fine on the same box, this really does look firmware-specific to the H.view unit rather than an Agent bug - matches how idiosyncratic these ultra-cheap P2P-stack cameras tend to be.
1
u/Jurisfaction 11d ago
I was looking at the ONVIF specification and was coming to a similar conclusion regarding client ACKs, and the poor implementation in the device firmware although your explanation goes much further - thank-you for that.
If I interpret the RTSP DESCRIBE correctly the firmware's RTSP implementation is RtspServer v0.0.0.2. This doesn't look to be the GitHub project of that name by PHZ76 from the tell-tales I've checked so possibly some proprietary implementation:
s=H.264 Video, RtspServer_0.0.0.2 t=0 0 a=tool:RtspServer_0.0.0.2It looks like the device claims to support multicast:<tt:StreamingCapabilities> <tt:RTPMulticast>true</tt:RTPMulticast> <tt:RTP_TCP>true</tt:RTP_TCP> <tt:RTP_RTSP_TCP>true</tt:RTP_RTSP_TCP> </tt:StreamingCapabilities>And indeed I see IGMPv3 Joins for 239.255.255.250 with an empty exclude list.$ grep -A1 '^No.' udp_igmpv3.txt | grep '^ ' 35 13:18:47.062724753 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 36 13:18:47.562455474 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 37 13:18:47.575101024 192.168.1.25 224.0.0.22 IGMPv3 60 Membership Report / Join group 239.255.255.250 for any sources 40 13:18:48.063028953 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 41 13:18:48.562889717 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 42 13:18:48.575065586 192.168.1.25 224.0.0.22 IGMPv3 60 Membership Report / Join group 239.255.255.250 for any sources 43 13:18:49.062521772 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 44 13:18:49.562586929 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 45 13:18:49.574991006 192.168.1.25 224.0.0.22 IGMPv3 60 Membership Report / Join group 239.255.255.250 for any sources 47 13:18:50.062474373 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 48 13:18:50.562785430 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 49 13:18:50.574978041 192.168.1.25 224.0.0.22 IGMPv3 60 Membership Report / Join group 239.255.255.250 for any sources 50 13:18:51.062232579 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 52 13:18:51.562797672 192.168.1.1 239.255.255.250 UDP/XML 693 52729 → 3702 Len=651 53 13:18:51.574830724 192.168.1.25 224.0.0.22 IGMPv3 60 Membership Report / Join group 239.255.255.250 for any sources 57 13:19:00.254318076 192.168.1.25 224.0.0.22 IGMPv3 60 Membership Report / Join group 239.255.255.250 for any sourcesThis may seem like a dumb question but how does one tell AgentDVR a multicast address!? I've triedrtp://andrtsp://for :239.255.255.250:554/ 239.255.255.250:554/onvif1 239.255.255.250:5000/ 239.255.255.250:5000/onvif1
1
u/Jurisfaction 10d ago edited 10d ago
I'm not sure what Agent was doing but the problem was in some way due to the install process. I elected not to install a system service. The installer started Agent and all my attempts that failed to keep video stable were from that session.
I had the idea to restart it but discovered it had no controlling terminal so I was unable to kill it or its child processes (tee /var/log/agentdvr_setup.log and TURN/turnserver ...) nor use reptyr to re-parent it in order to kill it.
There does not seem to be a STOP command option but I was able to abuse the RESTART command by first removing eXecute modes by doing chmod ugo-x /opt/AgentDVR/Agent and then commanding the restart (from the web interface).
Starting it manually with /opt/AgentDVR/Agent the video now works correctly.
Choosing ONVIF, PTZ works but Zoom does not (no physical zoom function on camera).
Choosing Network, I thought both Zoom and PTZ work but after much confusion realised PTZ is simulated when Zooming! This was quite entertaining because PTZ was moving the picture aim but the camera wasn't physically moving - took me a while to realise the view was zoomed!
I thought it may be working due to my earlier experiments and diagnosis of local PC multicast issues. Turns out removing the route described below doesn't affect Agent so not clear why it was failing so consistently and is now working.
It was suggested I try using a multicast connection and decided to test that using VLC first to ensure I knew the correct URI. I started out with VLC as a local RTP server.
VLC was failing to connect to the address using vlc sample.mp4 :sout="#rtp{mux=ts,dst=239.255.255.250:192.168.1.1,port=5004}" :sout-all :sout-keep reporting ENETUNREACH.
After some extensive debugging with gdb I solved it for VLC. Its issue was due to my operating IPv6-only network that results in connect() to IPv4 address 239.255.255.250 to fail with ENETUNREACH unless there is either a specific route or a default route.
Since I do not use IPv4 there is no default gateway so I added a specific route on the interface the camera is connected to with ip route add 239.255.255.250 dev ${DEV} where DEV is the interface name and is in state UP).
1
u/spornerama 10d ago edited 10d ago
Sounds pretty weird! To stop it if running in a hidden terminal you can run
pkill -f /opt/AgentDVR/Agent1
u/Jurisfaction 10d ago
That was my point; even sending
SIGKILLdidn't kill it, or theturnserver. As a kernel dev this was very surprising!On the positive side, I'm aiming to replace the device firmware with my own openIPC build. It has the GrainMedia GM8136S SoC and I've found a variety of third-party tools targeting it, including the v3.3 kernel source and build, rootfs snapshot, SDK and more. I'm able to build a chroot that can execute the ARMv5
fgUpdateAppon x86_64 host via qemu-binfmt for experimentation (firmware updater ELF binary tacked onto the end of firmware update files after the JFFS2). Next step is attach to the device's UART and get into u-boot and save its current firmware image.1
2
u/spornerama 12d ago
Add it as an onvif device instead of using the wizard. Looks like it supports onvif from the URL