I've spent some time reversing how the bootloader tries to do this update. It turns out that "upgrade_info_7db780a713a4.txt" contains a bunch of u-boot commands which are executed in sequence (with a couple of extra lines at the beginning of the file).
The first line contains the crc32 of the rest of the file, while the second line contains a fixed string.
So the upgrade file looks like:
Code:
CRC:<crc32 (in decimal) of the rest of the file, starting from the next line>
MagicString:c016dcd6-cdeb-45df-9fd0-e821bf0e1e62
command1
command2
command3
...
Note that u-boot does not check the 'CRC' and 'MagicString' labels (I made them up, you can put anything there), it just scans the line until it finds the ':', and whathever finds after that is the crc32 (1st line) or the magic string (2nd line).
The text file can use LF or CR/LF as line separators.
In case of failure (e.g. "upgrade_info_7db780a713a4.txt" not found, crc32 does not match, magic string does not match, etc.), the bootloader tries to transfer a file named "failed.txt", otherwise it tries to transfer a file named "success.txt". It does not seem to do anything with the content of the file (as a matter of facts, it also ignores if the transfer succeeds or fails).
The network configuration is based on the following environment variables (with the default value listed next to them):
Camera IP config:
autolip 192.168.1.108
autogw 192.168.1.1
autonm 255.255.255.0
TFTP server IP:
autosip 192.168.254.254
Note that the camera and the TFTP server are on different networks, so make sure to configure your network properly in order for the TFTP transfer to take place.
The following is simple python script to generate the "upgrade_info_7db780a713a4.txt" from a file containig a list of commands:
Code:
#!/usr/bin/env python
import zlib
import sys
input_file=sys.argv[1]
with open(input_file, 'rb') as cmdfile:
data=cmdfile.read()
checksumed_data = b'MagicString:c016dcd6-cdeb-45df-9fd0-e821bf0e1e62\n' + data
crc = zlib.crc32(checksumed_data) & 0xffffffff
crc_str = str(crc).encode("ascii")
output_data = b'CRC:' + crc_str + b'\n' + checksumed_data
with open("upgrade_info_7db780a713a4.txt", 'wb') as outfile:
outfile.write(output_data)
As a test, I created a simple command file which contains a ping to the TFTP server IP address. In this way, I can figure out if the command is effectively executed by u-boot by looking at the packet capture.
Text file with the command(s) to execute:
Code:
> cat commands.txt
ping 192.168.254.254
Generate the corresponding "upgrade_info_7db780a713a4.txt":
Code:
> ./generate_upgrade_info.py commands.txt
Resulting file:
Code:
> cat upgrade_info_7db780a713a4.txt
CRC:2819959008
MagicString:c016dcd6-cdeb-45df-9fd0-e821bf0e1e62
ping 192.168.254.254
After booting the camera, I can see from the tftp server logs that u-boot transfers both "upgrade_info_7db780a713a4.txt" and "success.txt":
Code:
Feb 13 20:41:36 linux in.tftpd[4237]: connect from ::ffff:192.168.1.108 (::ffff:192.168.1.108)
Feb 13 20:41:36 linux tftpd[4238]: tftpd: trying to get file: upgrade_info_7db780a713a4.txt
Feb 13 20:41:36 linux tftpd[4238]: tftpd: serving file from /srv/tftp
Feb 13 20:41:36 linux in.tftpd[4239]: connect from ::ffff:192.168.1.108 (::ffff:192.168.1.108)
Feb 13 20:41:36 linux tftpd[4240]: tftpd: trying to get file: success.txt
Feb 13 20:41:36 linux tftpd[4240]: tftpd: serving file from /srv/tftp
Also, the packet capture shows the same TFTP transfers, and the ping to the TFTP server IP address, confirming that the command has been executed by u-boot:
Code:
57 14.951755 192.168.1.108 192.168.254.254 TFTP 111 Read Request, File: upgrade_info_7db780a713a4.txt, Transfer type: octet, timeout=1, tsize=0, blksize=1468
58 14.956915 192.168.254.254 192.168.1.108 TFTP 131 Data Packet, Block: 1 (last)
59 14.959557 192.168.1.108 192.168.254.254 TFTP 60 Acknowledgement, Block: 1
62 15.153631 192.168.1.108 192.168.254.254 ICMP 60 Echo (ping) request id=0x0000, seq=0/0, ttl=255 (reply in 63)
63 15.153902 192.168.254.254 192.168.1.108 ICMP 42 Echo (ping) reply id=0x0000, seq=0/0, ttl=63 (request in 62)
91 15.563283 192.168.1.108 192.168.254.254 TFTP 93 Read Request, File: success.txt, Transfer type: octet, timeout=5, tsize=0, blksize=1468
92 15.568086 192.168.254.254 192.168.1.108 TFTP 55 Data Packet, Block: 1 (last)
93 15.570812 192.168.1.108 192.168.254.254 TFTP 60 Acknowledgement, Block: 1
It should be possible to flash the firmware using the same u-boot commands described in
Dahua IPC unbricking / recovery over serial UART and TFTP (I haven't tried since I have no need at this moment).