Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New firmware support #16

Closed
marcosdvpereira opened this issue Apr 23, 2023 · 16 comments
Closed

New firmware support #16

marcosdvpereira opened this issue Apr 23, 2023 · 16 comments

Comments

@marcosdvpereira
Copy link

Hi.

My cam came with FW version: 202303131805.
Is there any way to support this version?

My setup:

  • OpenWRT hijaking DNS requests to PiHole
  • PiHole with DNS Record as recommend on your guide (PiHole dedicated to my IoT network only working with WhiteLists. Everything else is blocked)
  • Docker Nginx container listening port 80 and 443. Added a domain based configuration as suggested here
  • Docker Python container running fake server
  • Docker MQTT container

No MQTT message is received nor receive feedback trying sending one.
Device list always empty.

Thanks any help here :)

@intx82
Copy link
Owner

intx82 commented Apr 26, 2023

Hello
Could you please make a capture of camera data? They may change hostnames of servers or entirely remove DNS resolve from camera. Check the domain names what camera try to resolve.

I saw they change an MQTT server host in version 20230301*, before was p2p.v720.naxclow.com after v720.p2p.naxclow.com

@marcosdvpereira
Copy link
Author

marcosdvpereira commented Apr 28, 2023

I've followed all steps on documentation, and as soon I connected it to IoT SSID it's only try to resolve v720.naxclow.com once and nothing more happens. The light of "mode" button blinks until no battery remains, and that's it!
I successfully can connect directly to the cam using the python script, but no luck using routers WiFi.

My goal here is trying to use the cam on Home Assistant without wan/cloud access.

Is there any useful info that I can take from the cam?

Edited: Noticed now the disclaimer "only in AP mode" 😅

@intx82
Copy link
Owner

intx82 commented Apr 29, 2023

i would be appreciated if you attach somewhere PCAP file and verbose logs from server, if content is not secret of course.

Did you seen HTTP request to the server from camera? (you may add '-v' argument to the server to retrieve more logs)

@grrosminet
Copy link

grrosminet commented May 2, 2023

Hi

Same firmware here

the camera connects to wifi, then I got two DNS requests and the mode light becomes still

May  2 11:54:25 pi4 dnsmasq[22625]: query[A] v720.naxclow.com from 192.168.5.35
May  2 11:54:25 pi4 dnsmasq[22625]: query[A] v720.p2p.naxclow.com from 192.168.5.35

In MQTT broker I got two topics :

  1. Naxclow/P2P/Users/Device/Status : {"device":"0800c00A4DF4","token":"NAXCLOW","status": 1}
  2. Naxclow/P2P/Users/Device/Info : {"apStatus": 0,"devPower": 69,"IrLed": 1,"sdCapacity": 0,"SD_freeDisk": -1,"SD_blockDisk": -1,"sdMoveMode": 0,"sdCardReco": 1,"sd_State": 0,"cameraState": 0,"instLed": 1,"random":"UVWXYZ","token":"ca9c11a604","devicesCode":"0800c00A4DF4","wifiName":"Domotique","version":"202303131805"}

Logs from the fake server are empty ... ( python3 src/a9_naxclow.py -s -vvvv )

$ cat nohup.out 
2023-05-02 10:17:01,700  [   INFO] [TCP-SRV :6123] Waiting for connection
2023-05-02 10:17:01,721  [   INFO] [UDP-SRV :6123] Waiting for connection
2023-05-02 10:24:37,860  [   INFO] [HTTP] GET device list: /dev/list
2023-05-02 10:24:37,862  [   INFO] [HTTP] "GET /dev/list HTTP/1.1" 200 -

devices list is empty ...

$ wget -q http://127.0.0.1/dev/list -O -
[]

the only request from camera trying to get out of network is the DNS request (iptables logs)

the fake server is running on a dedicated pi-zero

some tcpdump info :

$ tcpdump -n | grep 192.168.5.35
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:18:48.558518 ARP, Request who-has 192.168.5.35 tell 0.0.0.0, length 28
14:18:48.964398 ARP, Request who-has 192.168.5.35 tell 0.0.0.0, length 28
14:18:48.964595 ARP, Request who-has 192.168.5.35 tell 0.0.0.0, length 28
14:18:49.578803 ARP, Request who-has 192.168.5.35 tell 192.168.5.35, length 28
14:18:51.012388 ARP, Request who-has 192.168.5.254 tell 192.168.5.35, length 28
14:18:51.012621 ARP, Request who-has 192.168.5.23 tell 192.168.5.35, length 28
14:18:51.012952 ARP, Request who-has 192.168.5.23 tell 192.168.5.35, length 28
14:18:51.016221 IP 192.168.5.35.52432 > 192.168.5.23.80: Flags [S], seq 6509, win 8760, options [mss 1400], length 0
14:18:51.016596 IP 192.168.5.23.80 > 192.168.5.35.52432: Flags [S.], seq 4036021453, ack 6510, win 64240, options [mss 1460], length 0
14:18:51.019002 IP 192.168.5.35.52432 > 192.168.5.23.80: Flags [.], ack 1, win 8760, length 0
14:18:51.023488 IP 192.168.5.35.52432 > 192.168.5.23.80: Flags [P.], seq 1:155, ack 1, win 8760, length 154: HTTP: POST /app/api/ApiServer/getA9ConfCheck?devicesCode=0800c00A4DF4&random=JKLMNO&token=0ae3ea002d HTTP/1.1
14:18:51.023814 IP 192.168.5.23.80 > 192.168.5.35.52432: Flags [.], ack 155, win 64086, length 0
14:18:51.048059 IP 192.168.5.23.80 > 192.168.5.35.52432: Flags [P.], seq 1:396, ack 155, win 64086, length 395: HTTP: HTTP/1.1 200
14:18:51.051016 IP 192.168.5.35.52432 > 192.168.5.23.80: Flags [F.], seq 155, ack 396, win 8365, length 0
14:18:51.052106 IP 192.168.5.23.80 > 192.168.5.35.52432: Flags [F.], seq 396, ack 156, win 64085, length 0
14:18:51.075729 IP 192.168.5.35.52432 > 192.168.5.23.80: Flags [.], ack 397, win 8364, length 0
14:18:51.076917 IP 192.168.5.35.54680 > 192.168.5.23.6123: Flags [S], seq 6509, win 8760, options [mss 1400], length 0
14:18:51.077254 IP 192.168.5.23.6123 > 192.168.5.35.54680: Flags [S.], seq 1865193774, ack 6510, win 64240, options [mss 1460], length 0
14:18:51.079535 IP 192.168.5.35.54680 > 192.168.5.23.6123: Flags [.], ack 1, win 8760, length 0
14:18:51.080413 IP 192.168.5.35.54680 > 192.168.5.23.6123: Flags [P.], seq 1:108, ack 1, win 8760, length 107
14:18:51.080675 IP 192.168.5.23.6123 > 192.168.5.35.54680: Flags [.], ack 108, win 64133, length 0
14:18:51.114770 IP 192.168.5.23.6123 > 192.168.5.35.54680: Flags [P.], seq 1:49, ack 108, win 64133, length 48
14:18:51.121260 IP 192.168.5.35.65451 > 192.168.5.23.1883: Flags [S], seq 6510, win 8760, options [mss 1400], length 0
14:18:51.121642 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [S.], seq 1922266112, ack 6511, win 64240, options [mss 1460], length 0
14:18:51.124158 IP 192.168.5.35.65451 > 192.168.5.23.1883: Flags [.], ack 1, win 8760, length 0
14:18:51.130013 IP 192.168.5.35.65451 > 192.168.5.23.1883: Flags [P.], seq 1:146, ack 1, win 8760, length 145
14:18:51.130335 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [.], ack 146, win 64095, length 0
14:18:51.131273 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [P.], seq 1:5, ack 146, win 64095, length 4
14:18:51.134119 IP 192.168.5.35.65451 > 192.168.5.23.1883: Flags [P.], seq 146:194, ack 5, win 8756, length 48
14:18:51.134399 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [.], ack 194, win 64047, length 0
14:18:51.135012 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [P.], seq 5:10, ack 194, win 64047, length 5
14:18:51.137537 IP 192.168.5.35.65451 > 192.168.5.23.1883: Flags [P.], seq 194:284, ack 10, win 8751, length 90
14:18:51.137822 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [.], ack 284, win 64047, length 0
14:18:51.315902 IP 192.168.5.23.6123 > 192.168.5.35.54680: Flags [P.], seq 1:49, ack 108, win 64133, length 48
14:18:51.321415 IP 192.168.5.35.54680 > 192.168.5.23.6123: Flags [.], ack 49, win 8712, length 0
14:18:52.139549 IP 192.168.5.35.65451 > 192.168.5.23.1883: Flags [P.], seq 284:604, ack 10, win 8751, length 320
14:18:52.139854 IP 192.168.5.23.1883 > 192.168.5.35.65451: Flags [.], ack 604, win 64047, length 0

14:25:17.283636 IP (tos 0x0, ttl 255, id 5, offset 0, flags [none], proto TCP (6), length 194)
    192.168.5.35.52432 > 192.168.5.23.80: Flags [P.], cksum 0x827e (correct), seq 1:155, ack 1, win 8760, length 154: HTTP, length: 154
        POST /app/api/ApiServer/getA9ConfCheck?devicesCode=0800c00A4DF4&random=XYZABC&token=113786486f HTTP/1.1
        Host: v720.naxclow.com
        version: 202303131805

14:25:17.283957 IP (tos 0x0, ttl 64, id 9366, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.5.23.80 > 192.168.5.35.52432: Flags [.], cksum 0x2b49 (correct), seq 1, ack 155, win 64086, length 0
14:25:17.299475 IP (tos 0x0, ttl 64, id 9367, offset 0, flags [DF], proto TCP (6), length 435)
    192.168.5.23.80 > 192.168.5.35.52432: Flags [P.], cksum 0x15fb (correct), seq 1:396, ack 155, win 64086, length 395: HTTP, length: 395
        HTTP/1.1 200
        Server: nginx/1.14.0 (Ubuntu)
        Date: Tue, 02 May 2023 14:25:17 -0000
        Content-Type: application/json
        Connection: keep-alive
        Content-Length: 230


        {"code": 200, "message": "OK", "data": {"tcpPort": 6123, "uid": "0800c00A4DF4", "isBind": "8", "domain": "v720.naxclow.com", "updateUrl": null, "host": "192.168.5.23", "currTime": "1683030317", "pwd": "deadbeef", "version": null}}[!http]

tried to connect to official server : camera-v720.pcap

what can I provide you to help ?

@dbuezas
Copy link

dbuezas commented May 7, 2023

I also have the same fw version. I saw the camera tries to resolve these dns names:

  • caps.xmcsrv.net
  • pub-cfg.secu100.net

(update) Afterthought: I have another cheap chinese camera (internet blocked ofc), so it may have been that one

@dbuezas
Copy link

dbuezas commented May 7, 2023

It just started working by accident!
Since adguard was reporting all dns requests as coming from the same client (my router's IP), I searched and found that I should Set your adguard instance as the DNS server that is advertised over DHCP, not as the global DNS server of the router in reddit.
I don't understand how that would make a difference, and maybe it was just a matter of waiting, but I can now see the video stream.
Here I see the fw version to be the one reported in this issue:
image
And here the output of the server now:
image

My setup:

  • AdGuard doing the DNS rewrites (as a HomeAssistant AddOn)
  • Fritz!Box Router
  • My Mac running this "fake server"

@dbuezas
Copy link

dbuezas commented May 9, 2023

I found something interesting: I had p2p.v720.naxclow.com redirected to broker.hivemq.com, but had also cut the a9 camera from the internet. This means that it couldn't connect to the mqtt server at all.
If I give it internet access, the server crashes when I try to see the stream and the device disconnects:
image
Interestingly, the light stays on, so it thinks it is still connected to the fake server. If I kill the fake server, it starts blinking again.

It looks like something happens in the new firmware when the device can reach out to to the mqtt broker

@dbuezas
Copy link

dbuezas commented May 9, 2023

Ok, that may have been only a coincidence. Now it is very unstable regardless of what I do

@dbuezas
Copy link

dbuezas commented May 9, 2023

Ok I found something more, Internet access may be irrelevant but this seems to hold:
If the camera is turned off and on again, it connects again but the error above appears when I try to get a stream or snapshot. To make it work again I need to kill the fake-server, turn the camera off, start the fake-server again and then the camera.

@dbuezas
Copy link

dbuezas commented May 10, 2023

I got another camera which happens to have the older firmware today so I have been experimenting a bit more:

  • The camera with the old firmware reconnects quickly and it is generally faster to recover.
  • The new camera eventually reconnects, it just takes a while (after either a cam restart or a server restart), but it eventually connects.

This means that at least for me, this software works on both versions, it is just better on the old firmware. On the bright side, the new FW has much better picture quality and wider FOV.

I have been playing around with making a Home Assistant addon and doing some ffmpeg reencoding, and I ended up with a slightly contrived but reliably working system, I'll post the AddOn soon.

The only thing I'd like to add is the ability to get status and send commands from/to the camera. I know this can be done through mqtt (and it works really well :) ), the issue is that the local mqtt broker one would have in HA is not an anonymous one. This means one needs to either use a public one in the internet or just live without it.

Seeing that commands are sent during the initial handshake, I hacked myself an extra endpoint in the http server meant to get the list of devices, snapshot and live stream. This one sends this json to the camera via both udp and tcp open connections, but the camera doesn't switch to IR mode. Do you know if this is possible without MQTT?
I added this to the v720_sta.py file:

def fsm_send_any(self, json_string: str):
        import json as jsonlib
        resp = prot_json_udp(json=jsonlib.loads(json_string))
        print(f'[TCP] Send any: {resp}')
        self._tcp.send(resp.req())
        print(f'[UDP] Send any: {resp}')
        self._udp.send(resp.req())

And call it from v720_http.py.

I get this in the console
image
but the video feed doesn't switch to black and white. Any tips?

@dbuezas
Copy link

dbuezas commented May 12, 2023

Ok, I found how to send them via TCP.
BTW, it looks like the new fw version does work, it just takes a very long time to go online. Once that happens (and as long as the server is still running) it is quite stable.
Also the video and audio quality is much better.

@intx82
Copy link
Owner

intx82 commented May 12, 2023

Sorry guys, I have a vacation and was off. :)

Nice to hear that you have solved yours issues, if you have any changes into code, please make pull-request

About MQTT topics, check file fake-server.md there were examples how to put it back into color mode or other way put it into AP mode and use argument --ir (ie send this command from AP mode, not from MQTT)

@dbuezas
Copy link

dbuezas commented May 12, 2023

After researching your code for a while, I found out how to send commands via UDP and the IR mode can be sent via STA mode. I'll eventually add entities for this to the Home Assistant Add-on I just made :)
https://github.com/dbuezas/a9-camera-ha-add-on
Still very rough, but it is functional.

I managed to get the audio stream working in sta mode and merge it with the video stream using ffmpeg. Here's the relevant code:
https://github.com/dbuezas/a9-camera-ha-add-on/blob/main/rootfs/usr/local/a9-v720/src/v720_http.py#L73-L166

I had to butcher your code to remove the dependencies that don't work well with the alpine docker base, so I just put it in that repo. If you want I can make a PR with the new stream api (it works fine in vlc too, with audio and all :) )

Thanks for this repo! Considering the effort it took me to "just" make it work as an addon with audio, I have gained a lot of respect for the work you did here reverse engineering everything bout this cam 🙇

@dbuezas
Copy link

dbuezas commented May 12, 2023

BTW, the new FW version does work, but it is unstable and takes ages to connect. I didn't find out why, but something is obviously different.

@grrosminet
Copy link

gave it a second chance today and .. it works ! don't know what was wrong last time, maybe I started the fake-server as standard user instead of root

@dbuezas
Copy link

dbuezas commented May 16, 2023

I've been also testing it for a while now and it works stable. It just takes a while to connect if the server os restarted after the camera was already connected

@intx82 intx82 closed this as completed May 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants