I bought the cheapest Wifi camera on Amazon
- 4 WiFi 1080p indendørs ip-camera $17 each delivered
as far as I understand, the intention is to install an app on your phone, and via their app and their WEB server you can then use the camera. There is plenty of opportunity to commit to a YI solution where you pay close to the camera’s price per month in subscription. – That’s by no means what I want.
Fortunately, I can change the firmware so it can spit an RTSP stream out on my local network that our server can use, the software is on Github: roleoroleo/yi-hack-Allwinner-v2
First install attemp – SUCCESS we can watch a RTSP stream
Here is the recipe for how I changed the firmware, see also the link above:
- check serial number as described on Github mine is IFUS… so we found the right one
- configurer the IP-Camera via YI-Home-App, note: phone and ip camera should be on 2.4 Ghz Wifi
- insert SD-card in camera, format SD-card via YI-Home-App
- power off IP camera, move SD-card to a linux box and install backup.tar.gz from Dump your backup firmware (SD card)
- move SD-card back to IP-camera and power on – a backup of the original fir mware will be made (the script SD-card/Factory/config.sh is executed on boot-up.
- onGitHup shoose the newst tag (was 0.1.8)
- from Release download y211ga_0.1.8.tgz whhich is the Firmware version of my cameraet
- install y211ga_01.8.tgz on SD-card
- move SD-card to IP-cameraet, reboot and the new firmware is installed ( by executing SD-card/Factory/config.sh)
- HURRAH th cameraet belongs to me and is under my control
- check http://camera-ip:8080
- try vlc rtsp://camera-ip/ch0_0.h264 we see a livevideo feed – delayed a little
- try ssh root@camera-ip
- No more YI-Home-App for me
I am impressed, for $20 (incl sdcard) I got a nice 1080p wifi-camera, that can provide an RTSP stream.
Iron out some bugs
On the status page, most of the fields are empty. lets fix that
When I ssh into the camera and execute stautus.json I get:
root@yi-cam1:~# /tmp/sd/yi-hack/www/cgi-bin/status.json
Content-type: application/json
/tmp/sd/yi-hack/www/cgi-bin/status.json: line 6: hostname: not found
/tmp/sd/yi-hack/www/cgi-bin/status.json: line 23: free: not found
/tmp/sd/yi-hack/www/cgi-bin/status.json: line 24: free: not found
{
"name":"yi-hack-allwinner-v2",
"hostname":"",
"fw_version":"0.1.8",
"home_version":"9.0.36.00_202011101611",
"model_suffix":"y211ga",
"ptz":"no",
"serial_number":"
FFFFFFFFFFFFFFFF",
"local_time":"Mon Aug 23 14:14:53 GMT 2021",
"uptime":"18924.75",
"load_avg":"1.97 1.83 1.77",
"total_memory":"",
"free_memory":"",
"free_sd":"88%",
"local_ip":"192.168.2.162",
"netmask":"255.255.255.0",
"gateway":"192.168.2.1",
"mac_addr":"84:7A:B6:60:70:92",
"wlan_essid":"Wi2-ve",
"wlan_strength":"50"
}root@yi-cam1:~#
Two commands not available, but the real culpritt here is the Serial number, Here are the changes to get this right:
diff -Naur yi-hack/www/cgi-bin/status.json status.json
--- yi-hack/www/cgi-bin/status.json 2021-06-17 16:35:43.000000000 -0400
+++ status.json 2021-08-23 10:46:00.432358750 -0400
@@ -3,7 +3,7 @@
printf "Content-type: application/json\r\n\r\n"
NAME="yi-hack-allwinner-v2"
-HOSTNAME=$(hostname)
+HOSTNAME=$(cat /tmp/sd/yi-hack/etc/hostname)
FW_VERSION=$(cat /tmp/sd/yi-hack/version)
HOME_VERSION=$(cat /home/app/.appver)
MODEL_SUFFIX=$(cat /tmp/sd/yi-hack/model_suffix)
@@ -12,7 +12,7 @@
else
PTZ="no"
fi
-if [ "$MODEL_SUFFIX" == "y211ga" ] || [ "$MODEL_SUFFIX" == "h60ga" ]; then
+if [ "$MODEL_SUFFIX" == "h60ga" ]; then
SERIAL_NUMBER=$(dd bs=1 count=20 skip=784 if=/tmp/mmap.info 2>/dev/null | cut -c1-20)
else
SERIAL_NUMBER=$(dd bs=1 count=20 skip=656 if=/tmp/mmap.info 2>/dev/null | cut -c1-20)
@@ -20,8 +20,8 @@
LOCAL_TIME=$(date)
UPTIME=$(cat /proc/uptime | cut -d ' ' -f1)
LOAD_AVG=$(cat /proc/loadavg | cut -d ' ' -f1-3)
-TOTAL_MEMORY=$(free -k | awk 'NR==2{print $2}')
-FREE_MEMORY=$(free -k | awk 'NR==2{print $4+$6+$7}')
+TOTAL_MEMORY=$(awk '/MemTotal/{print $2}' /proc/meminfo)
+FREE_MEMORY=$(awk '/MemAvailable/{print $2}' /proc/meminfo)
FREE_SD=$(df | grep -m1 '/tmp/sd' | grep mmc | awk '{print $5}' | tr -d '%')
if [ -z "$FREE_SD" ]; then
FREE_SD="N/A"
lets try it. Now we see this:
root@yi-cam1:~# /tmp/sd/yi-hack/www/cgi-bin/status.json
Content-type: application/json
{
"name":"yi-hack-allwinner-v2",
"hostname":"yi-cam1",
"fw_version":"0.1.8",
"home_version":"9.0.36.00_202011101611",
"model_suffix":"y211ga",
"ptz":"no",
"serial_number":"IFUSY65Q5HJHAE210315",
"local_time":"Mon Aug 23 14:50:05 GMT 2021",
"uptime":"873.00",
"load_avg":"0.96 1.60 1.09",
"total_memory":"60912",
"free_memory":"0",
"free_sd":"88%",
"local_ip":"192.168.2.162",
"netmask":"255.255.255.0",
"gateway":"192.168.2.1",
"mac_addr":"84:7A:B6:60:70:92",
"wlan_essid":"Wi2-ve",
"wlan_strength":"53"
}root@yi-cam1:~#
Getting comfortable hacking.
We can ssh into the Wifi-Camera, and poke around, unfortunately the busybox that comes with the system is rather limited, and the busybox that yi-hack install is also not as complete as I would like,no dmesg command f.ex. so lets fix it.
The swiss-army-knife when it comes to embedded systems is busybox/dropbear, which combines a number of commands into a single program, saving a lot of diskspace but also memory space since an instance of the code will most likely already be running and can be shared.
The filesystem used on the SD-card is fat32, hence we do not have the normal Unix filesystem facilities, no hard-link, no symlinks. instead we can use shell wrappers, the current version of yi-hack has just copied the commands onto the SD-card, and many are missing even though the functionallity is there, lets get dmesg working:
cp /tmp/sd/yi-hack/bin/base64" /tmp/sd/yi-hack/bin/busybox
echo "#!/tmp/sd/yi-hack/bin/busybox" >/tmp/sd/yi-hack/bin/dmesg
/tmp/sd/yi-hack/bin/dmesg
We have the source code on GiHub so he proper way to fix this is to fix the source code and build it from scratch, check Build-your-own-firmware.
Here are the changes I made to expose all the commands and at the same time the size of yi-hacks dropped from 13Mb to 6.2Mb.
diff --git a/src/busybox/install.busybox b/src/busybox/install.busybox
index 1e4fad2..a923696 100755
--- a/src/busybox/install.busybox
+++ b/src/busybox/install.busybox
@@ -8,6 +8,13 @@ mkdir -p ../../build/yi-hack/bin
mkdir -p ../../build/yi-hack/sbin
mkdir -p ../../build/yi-hack/usr/bin
mkdir -p ../../build/yi-hack/usr/sbin
+cp -f ./_install/yi-hack/bin/busybox ../../build/yi-hack/bin
+# destination is fat32 filesystem so no symlink, so we use shell script wrappers
+for i in $(cd ./_install/yi-hack; find -type l); do
+# was /bin/busybox, need to use our version /tmp/sd/yi-hack/bin/busybox
+ echo "#!/tmp/sd/yi-hack/bin/busybox" > ../../build/yi-hack/$i
+done
+exit
cp -f ./_install/yi-hack/bin/busybox ../../build/yi-hack/bin/base64
cp -f ./_install/yi-hack/bin/busybox ../../build/yi-hack/bin/gzip
cp -f ./_install/yi-hack/bin/busybox ../../build/yi-hack/bin/hostname
diff --git a/src/dropbear/install.dropbear b/src/dropbear/install.dropbear
index 553df25..e6c0033 100755
--- a/src/dropbear/install.dropbear
+++ b/src/dropbear/install.dropbear
@@ -9,6 +9,11 @@ mkdir -p ../../build/yi-hack/usr/bin/
arm-openwrt-linux-strip ./_install/dropbearmulti
cp -f ./_install/dropbearmulti ../../build/yi-hack/bin/
+# use wrappers since fat32 doesn't support symbolic links
+for i in dbclient dropbearconvert dropbearkey scp ssh ../sbin/dropbear;do
+ echo "#!/tmp/sd/yi-hack/bin/dropbearmulti" > ../../build/yi-hack/bin/$i
+done
+exit
# Copy binary with different names: fat32 doesn't support symbolic links
cp -f ../../build/yi-hack/bin/dropbearmulti ../../build/yi-hack/bin/dbclient
To enable further commands selext what you want with
yi-hack-Allwinner-v2# cd src/busybox/busybox/
busybox# make menuconfig
# make your choices
busybox# cd -
yi-hack-Allwinner-v2# ./scripts/compile.sh
Copy it to your SD-card, reboot the camera, and you are all set
How does the system startup
- proces 1 is /sbin/init which is a link to busybox
- init will read /etc/inittab and call /etc/init.d/rcS boot
- /etc/init.d/rcS will mount -a (/etc/fstab) and call all the /etc/init.d/S* script
- /etc/init.d/S01udev starts the udev system
- /etc/init.d/S02app will call /backup/init.sh
- /backup/init.sh is on a rw-filesystem (first rw file-system encounteres) so here we the hack begins
- /tmp/sd mounted
- /tmp/sd/lower_half.sh is run if found – ELSE
- /backup/lower_half.sh will run and we will have normal boot
/tmp/sd/lower_half.sh is the basis for yi-hack
Compared to /backup/lower_half.sh many system services has been commented out and the following scripts will be called
- /tmp/sd/debug.sh & is called if it exists
- /tmp/sd/yi-hack/script/system.sh & Here is where the new system is started.
Here it is a very long shell script.
#!/bin/sh
CONF_FILE="etc/system.conf"
YI_HACK_PREFIX="/tmp/sd/yi-hack"
YI_HACK_UPGRADE_PATH="/tmp/sd/.fw_upgrade"
YI_HACK_VER=$(cat /tmp/sd/yi-hack/version)
MODEL_SUFFIX=$(cat /tmp/sd/yi-hack/model_suffix)
get_config()
{
key=$1
grep -w $1 $YI_HACK_PREFIX/$CONF_FILE | cut -d "=" -f2
}
start_buffer()
{
# Trick to start circular buffer filling
./cloud &
IDX=`hexdump -n 16 /dev/shm/fshare_frame_buf | awk 'NR==1{print $8}'`
N=0
while [ "$IDX" -eq "0000" ] && [ $N -lt 60 ]; do
IDX=`hexdump -n 16 /dev/shm/fshare_frame_buf | awk 'NR==1{print $8}'`
N=$(($N+1))
sleep 0.2
done
killall cloud
ipc_cmd -x
}
export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/home/base/tools:/home/app/localbin:/home/base:/tmp/sd/yi-hack/bin:/tmp/sd/yi-hack/sbin:/tmp/sd/yi-hack/usr/bin:/tmp/sd/yi-hack/usr/sbin
export LD_LIBRARY_PATH=/lib:/usr/lib:/home/lib:/home/qigan/lib:/home/app/locallib:/tmp/sd:/tmp/sd/gdb:/tmp/sd/yi-hack/lib
ulimit -s 1024
# Remove core files, if any
rm -f $YI_HACK_PREFIX/bin/core
rm -f $YI_HACK_PREFIX/www/cgi-bin/core
touch /tmp/httpd.conf
if [ -f $YI_HACK_UPGRADE_PATH/yi-hack/fw_upgrade_in_progress ]; then
echo "#!/bin/sh" > /tmp/fw_upgrade_2p.sh
echo "# Complete fw upgrade and restore configuration" >> /tmp/fw_upgrade_2p.sh
echo "sleep 1" >> /tmp/fw_upgrade_2p.sh
echo "cd $YI_HACK_UPGRADE_PATH" >> /tmp/fw_upgrade_2p.sh
echo "cp -rf * .." >> /tmp/fw_upgrade_2p.sh
echo "cd .." >> /tmp/fw_upgrade_2p.sh
echo "rm -rf $YI_HACK_UPGRADE_PATH" >> /tmp/fw_upgrade_2p.sh
echo "rm $YI_HACK_PREFIX/fw_upgrade_in_progress" >> /tmp/fw_upgrade_2p.sh
echo "sync" >> /tmp/fw_upgrade_2p.sh
echo "sync" >> /tmp/fw_upgrade_2p.sh
echo "sync" >> /tmp/fw_upgrade_2p.sh
echo "reboot" >> /tmp/fw_upgrade_2p.sh
sh /tmp/fw_upgrade_2p.sh
exit
fi
$YI_HACK_PREFIX/script/check_conf.sh
hostname -F $YI_HACK_PREFIX/etc/hostname
export TZ=$(get_config TIMEZONE)
if [[ $(get_config SWAP_FILE) == "yes" ]] ; then
SD_PRESENT=$(mount | grep mmc | grep -c ^)
if [[ $SD_PRESENT -eq 1 ]]; then
if [[ -f /tmp/sd/swapfile ]]; then
swapon /tmp/sd/swapfile
else
dd if=/dev/zero of=/tmp/sd/swapfile bs=1M count=64
chmod 0600 /tmp/sd/swapfile
mkswap /tmp/sd/swapfile
swapon /tmp/sd/swapfile
fi
fi
fi
if [[ x$(get_config USERNAME) != "x" ]] ; then
USERNAME=$(get_config USERNAME)
PASSWORD=$(get_config PASSWORD)
ONVIF_USERPWD="user=$USERNAME\npassword=$PASSWORD"
echo "/:$USERNAME:$PASSWORD" > /tmp/httpd.conf
fi
if [[ x$(get_config SSH_PASSWORD) != "x" ]] ; then
SSH_PASSWORD=$(get_config SSH_PASSWORD)
PASSWORD_MD5="$(echo "${SSH_PASSWORD}" | mkpasswd --method=MD5 --stdin)"
cp -f "/etc/passwd" "/tmp/sd/yi-hack/etc/passwd"
sed -i 's|^root::|root:'${PASSWORD_MD5}':|g' "/tmp/sd/yi-hack/etc/passwd"
sed -i 's|/root|/tmp/sd/yi-hack|g' "/tmp/sd/yi-hack/etc/passwd"
mount --bind "/tmp/sd/yi-hack/etc/passwd" "/etc/passwd"
cp -f "/etc/shadow" "/tmp/sd/yi-hack/etc/shadow"
sed -i 's|^root::|root:'${PASSWORD_MD5}':|g' "/tmp/sd/yi-hack/etc/shadow"
mount --bind "/tmp/sd/yi-hack/etc/shadow" "/etc/shadow"
fi
case $(get_config RTSP_PORT) in
''|*[!0-9]*) RTSP_PORT=554 ;;
*) RTSP_PORT=$(get_config RTSP_PORT) ;;
esac
case $(get_config ONVIF_PORT) in
''|*[!0-9]*) ONVIF_PORT=80 ;;
*) ONVIF_PORT=$(get_config ONVIF_PORT) ;;
esac
case $(get_config HTTPD_PORT) in
''|*[!0-9]*) HTTPD_PORT=8080 ;;
*) HTTPD_PORT=$(get_config HTTPD_PORT) ;;
esac
# todo
#if [ ! -f $YI_PREFIX/cloudAPI_real ]; then
# mv $YI_PREFIX/cloudAPI $YI_PREFIX/cloudAPI_real
# cp $YI_HACK_PREFIX/script/cloudAPI $YI_PREFIX/
#fi
if [[ $(get_config DISABLE_CLOUD) == "no" ]] ; then
(
if [ $(get_config RTSP_AUDIO) != "no" ]; then
touch /tmp/audio_fifo.requested
fi
if [ $(get_config SPEAKER_AUDIO) != "no" ]; then
touch /tmp/audio_in_fifo.requested
fi
cd /home/app
LD_LIBRARY_PATH="/tmp/sd/yi-hack/lib:/lib:/usr/lib:/home/lib:/home/qigan/lib:/home/app/locallib:/tmp/sd:/tmp/sd/gdb" ./rmm &
sleep 6
dd if=/tmp/audio_fifo of=/dev/null bs=1 count=8192
# dd if=/dev/zero of=/tmp/audio_in_fifo bs=1 count=1024
./mp4record &
./cloud &
./p2p_tnp &
./oss &
if [ -f ./oss_fast ]; then
./oss_fast &
fi
if [ -f ./oss_lapse ]; then
./oss_lapse &
fi
./rtmp &
./watch_process &
)
else
(
if [ $(get_config RTSP_AUDIO) != "no" ]; then
touch /tmp/audio_fifo.requested
fi
if [ $(get_config SPEAKER_AUDIO) != "no" ]; then
touch /tmp/audio_in_fifo.requested
fi
cd /home/app
LD_LIBRARY_PATH="/tmp/sd/yi-hack/lib:/lib:/usr/lib:/home/lib:/home/qigan/lib:/home/app/locallib:/tmp/sd:/tmp/sd/gdb" ./rmm &
sleep 6
dd if=/tmp/audio_fifo of=/dev/null bs=1 count=8192
# dd if=/dev/zero of=/tmp/audio_in_fifo bs=1 count=1024
# Trick to start circular buffer filling
start_buffer
if [[ $(get_config REC_WITHOUT_CLOUD) == "yes" ]] ; then
./mp4record &
fi
mkdir /tmp/etc
cp -R /etc/* /tmp/etc
mount --bind /tmp/etc /etc
echo "127.0.0.1 api.eu.xiaoyi.com" >> /etc/hosts
)
fi
if [[ $(get_config HTTPD) == "yes" ]] ; then
mkdir -p /tmp/sd/record
mkdir -p /tmp/sd/yi-hack/www/record
mount --bind /tmp/sd/record /tmp/sd/yi-hack/www/record
httpd -p $HTTPD_PORT -h $YI_HACK_PREFIX/www/ -c /tmp/httpd.conf
fi
if [[ $(get_config TELNETD) == "no" ]] ; then
killall telnetd
fi
if [[ $(get_config FTPD) == "yes" ]] ; then
if [[ $(get_config BUSYBOX_FTPD) == "yes" ]] ; then
tcpsvd -vE 0.0.0.0 21 ftpd -w &
else
pure-ftpd -B
fi
fi
if [[ $(get_config SSHD) == "yes" ]] ; then
mkdir -p $YI_HACK_PREFIX/etc/dropbear
if [ ! -f $YI_HACK_PREFIX/etc/dropbear/dropbear_ecdsa_host_key ]; then
dropbearkey -t ecdsa -f /tmp/dropbear_ecdsa_host_key
mv /tmp/dropbear_ecdsa_host_key $YI_HACK_PREFIX/etc/dropbear/
fi
# Restore keys
# mkdir -p /etc/dropbear
# cp -f $SONOFF_HACK_PREFIX/etc/dropbear/* /etc/dropbear/
chmod 0600 $YI_HACK_PREFIX/etc/dropbear/*
dropbear -R -B
fi
if [[ $(get_config NTPD) == "yes" ]] ; then
# Wait until all the other processes have been initialized
sleep 5 && ntpd -p $(get_config NTP_SERVER) &
fi
ipc_multiplexer &
sleep 1
if [[ $(get_config MQTT) == "yes" ]] ; then
mqttv4 &
mqtt-config &
fi
sleep 5
if [[ $RTSP_PORT != "554" ]] ; then
D_RTSP_PORT=:$RTSP_PORT
fi
if [[ $HTTPD_PORT != "80" ]] ; then
D_HTTPD_PORT=:$HTTPD_PORT
fi
if [[ $ONVIF_PORT != "80" ]] ; then
D_ONVIF_PORT=:$ONVIF_PORT
fi
if [[ $(get_config ONVIF_WM_SNAPSHOT) == "yes" ]] ; then
WATERMARK="&watermark=yes"
fi
if [[ $(get_config RTSP) == "yes" ]] ; then
RTSP_AUDIO_COMPRESSION=$(get_config RTSP_AUDIO)
if [[ "$RTSP_AUDIO_COMPRESSION" == "none" ]] ; then
RTSP_AUDIO_COMPRESSION="no"
fi
RRTSP_MODEL=$MODEL_SUFFIX RRTSP_RES=$(get_config RTSP_STREAM) RRTSP_AUDIO=$RTSP_AUDIO_COMPRESSION RRTSP_PORT=$RTSP_PORT RRTSP_USER=$USERNAME RRTSP_PWD=$PASSWORD rRTSPServer &
if [[ $(get_config RTSP_STREAM) == "low" ]]; then
ONVIF_PROFILE_1="name=Profile_1\nwidth=640\nheight=360\nurl=rtsp://%s$D_RTSP_PORT/ch0_1.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=low$WATERMARK\ntype=H264"
fi
if [[ $(get_config RTSP_STREAM) == "high" ]]; then
ONVIF_PROFILE_0="name=Profile_0\nwidth=1920\nheight=1080\nurl=rtsp://%s$D_RTSP_PORT/ch0_0.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=high$WATERMARK\ntype=H264"
fi
if [[ $(get_config RTSP_STREAM) == "both" ]]; then
if [[ $(get_config ONVIF_PROFILE) == "low" ]] || [[ $(get_config ONVIF_PROFILE) == "both" ]] ; then
ONVIF_PROFILE_1="name=Profile_1\nwidth=640\nheight=360\nurl=rtsp://%s$D_RTSP_PORT/ch0_1.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=low$WATERMARK\ntype=H264"
fi
if [[ $(get_config ONVIF_PROFILE) == "high" ]] || [[ $(get_config ONVIF_PROFILE) == "both" ]] ; then
ONVIF_PROFILE_0="name=Profile_0\nwidth=1920\nheight=1080\nurl=rtsp://%s$D_RTSP_PORT/ch0_0.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=high$WATERMARK\ntype=H264"
fi
fi
$YI_HACK_PREFIX/script/wd_rtsp.sh &
fi
if [ "$MODEL_SUFFIX" == "h60ga" ]; then
SERIAL_NUMBER=$(dd bs=1 count=20 skip=784 if=/tmp/mmap.info 2>/dev/null | cut -c1-20)
HW_ID=$(dd bs=1 count=4 skip=784 if=/tmp/mmap.info 2>/dev/null | cut -c1-4)
else
SERIAL_NUMBER=$(dd bs=1 count=20 skip=656 if=/tmp/mmap.info 2>/dev/null | cut -c1-20)
HW_ID=$(dd bs=1 count=4 skip=656 if=/tmp/mmap.info 2>/dev/null | cut -c1-4)
fi
if [[ $(get_config ONVIF) == "yes" ]] ; then
if [[ $(get_config ONVIF_NETIF) == "wlan0" ]] ; then
ONVIF_NETIF="wlan0"
else
ONVIF_NETIF="eth0"
fi
ONVIF_SRVD_CONF="/tmp/onvif_srvd.conf"
echo "pid_file=/var/run/onvif_srvd.pid" > $ONVIF_SRVD_CONF
echo "model=Yi Hack" >> $ONVIF_SRVD_CONF
echo "manufacturer=Yi" >> $ONVIF_SRVD_CONF
echo "firmware_ver=$YI_HACK_VER" >> $ONVIF_SRVD_CONF
echo "hardware_id=$HW_ID" >> $ONVIF_SRVD_CONF
echo "serial_num=$SERIAL_NUMBER" >> $ONVIF_SRVD_CONF
echo "ifs=$ONVIF_NETIF" >> $ONVIF_SRVD_CONF
echo "port=$ONVIF_PORT" >> $ONVIF_SRVD_CONF
echo "scope=onvif://www.onvif.org/Profile/S" >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
if [ ! -z $ONVIF_PROFILE_0 ]; then
echo "#Profile 0" >> $ONVIF_SRVD_CONF
echo -e $ONVIF_PROFILE_0 >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
fi
if [ ! -z $ONVIF_PROFILE_1 ]; then
echo "#Profile 1" >> $ONVIF_SRVD_CONF
echo -e $ONVIF_PROFILE_1 >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
fi
if [ ! -z $ONVIF_USERPWD ]; then
echo -e $ONVIF_USERPWD >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
fi
if [[ $MODEL_SUFFIX == "r30gb" ]] || [[ $MODEL_SUFFIX == "r40ga" ]] || [[ $MODEL_SUFFIX == "h51ga" ]] || [[ $MODEL_SUFFIX == "h52ga" ]] || [[ $MODEL_SUFFIX == "h60ga" ]] || [[ $MODEL_SUFFIX == "q321br_lsx" ]] ; then
echo "#PTZ" >> $ONVIF_SRVD_CONF
echo "ptz=1" >> $ONVIF_SRVD_CONF
echo "move_left=/tmp/sd/yi-hack/bin/ipc_cmd -M left" >> $ONVIF_SRVD_CONF
echo "move_right=/tmp/sd/yi-hack/bin/ipc_cmd -M right" >> $ONVIF_SRVD_CONF
echo "move_up=/tmp/sd/yi-hack/bin/ipc_cmd -M up" >> $ONVIF_SRVD_CONF
echo "move_down=/tmp/sd/yi-hack/bin/ipc_cmd -M down" >> $ONVIF_SRVD_CONF
echo "move_stop=/tmp/sd/yi-hack/bin/ipc_cmd -M stop" >> $ONVIF_SRVD_CONF
echo "move_preset=/tmp/sd/yi-hack/bin/ipc_cmd -p %t" >> $ONVIF_SRVD_CONF
fi
onvif_srvd --conf_file $ONVIF_SRVD_CONF
if [[ $(get_config ONVIF_WSDD) == "yes" ]] ; then
wsdd --pid_file /var/run/wsdd.pid --if_name $ONVIF_NETIF --type tdn:NetworkVideoTransmitter --xaddr "http://%s$D_ONVIF_PORT" --scope "onvif://www.onvif.org/name/Unknown onvif://www.onvif.org/Profile/Streaming"
fi
fi
framefinder $MODEL_SUFFIX &
# Add crontab
CRONTAB=$(get_config CRONTAB)
FREE_SPACE=$(get_config FREE_SPACE)
mkdir -p /var/spool/cron/crontabs/
if [ ! -z "$CRONTAB" ]; then
echo -e "$CRONTAB" > /var/spool/cron/crontabs/root
fi
if [ "$FREE_SPACE" != "0" ]; then
echo "0 * * * * /tmp/sd/yi-hack/script/clean_records.sh $FREE_SPACE" >> /var/spool/cron/crontabs/root
fi
$YI_HACK_PREFIX/usr/sbin/crond -c /var/spool/cron/crontabs/
# Add MQTT Advertise
if [ -f "$YI_HACK_PREFIX/script/mqtt_advertise/startup.sh" ]; then
$YI_HACK_PREFIX/script/mqtt_advertise/startup.sh
fi
# Remove log files written to SD on boot containing the WiFi password
#rm -f "/tmp/sd/log/log_first_login.tar.gz"
#rm -f "/tmp/sd/log/log_login.tar.gz"
#rm -f "/tmp/sd/log/log_p2p_clr.tar.gz"
#rm -f "/tmp/sd/log/log_wifi_connected.tar.gz"
if [[ $(get_config FTP_UPLOAD) == "yes" ]] ; then
/tmp/sd/yi-hack/script/ftppush.sh start &
fi
if [ -f "/tmp/sd/yi-hack/startup.sh" ]; then
/tmp/sd/yi-hack/startup.sh
fi
root@bin/dmesg:/etc#
root@bin/dmesg:/etc# cat /tmp/sd/yi-hack/script/system.sh
#!/bin/sh
CONF_FILE="etc/system.conf"
YI_HACK_PREFIX="/tmp/sd/yi-hack"
YI_HACK_UPGRADE_PATH="/tmp/sd/.fw_upgrade"
YI_HACK_VER=$(cat /tmp/sd/yi-hack/version)
MODEL_SUFFIX=$(cat /tmp/sd/yi-hack/model_suffix)
get_config()
{
key=$1
grep -w $1 $YI_HACK_PREFIX/$CONF_FILE | cut -d "=" -f2
}
start_buffer()
{
# Trick to start circular buffer filling
./cloud &
IDX=`hexdump -n 16 /dev/shm/fshare_frame_buf | awk 'NR==1{print $8}'`
N=0
while [ "$IDX" -eq "0000" ] && [ $N -lt 60 ]; do
IDX=`hexdump -n 16 /dev/shm/fshare_frame_buf | awk 'NR==1{print $8}'`
N=$(($N+1))
sleep 0.2
done
killall cloud
ipc_cmd -x
}
export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/home/base/tools:/home/app/localbin:/home/base:/tmp/sd/yi-hack/bin:/tmp/sd/yi-hack/sbin:/tmp/sd/yi-hack/usr/bin:/tmp/sd/yi-hack/usr/sbin
export LD_LIBRARY_PATH=/lib:/usr/lib:/home/lib:/home/qigan/lib:/home/app/locallib:/tmp/sd:/tmp/sd/gdb:/tmp/sd/yi-hack/lib
ulimit -s 1024
# Remove core files, if any
rm -f $YI_HACK_PREFIX/bin/core
rm -f $YI_HACK_PREFIX/www/cgi-bin/core
touch /tmp/httpd.conf
if [ -f $YI_HACK_UPGRADE_PATH/yi-hack/fw_upgrade_in_progress ]; then
echo "#!/bin/sh" > /tmp/fw_upgrade_2p.sh
echo "# Complete fw upgrade and restore configuration" >> /tmp/fw_upgrade_2p.sh
echo "sleep 1" >> /tmp/fw_upgrade_2p.sh
echo "cd $YI_HACK_UPGRADE_PATH" >> /tmp/fw_upgrade_2p.sh
echo "cp -rf * .." >> /tmp/fw_upgrade_2p.sh
echo "cd .." >> /tmp/fw_upgrade_2p.sh
echo "rm -rf $YI_HACK_UPGRADE_PATH" >> /tmp/fw_upgrade_2p.sh
echo "rm $YI_HACK_PREFIX/fw_upgrade_in_progress" >> /tmp/fw_upgrade_2p.sh
echo "sync" >> /tmp/fw_upgrade_2p.sh
echo "sync" >> /tmp/fw_upgrade_2p.sh
echo "sync" >> /tmp/fw_upgrade_2p.sh
echo "reboot" >> /tmp/fw_upgrade_2p.sh
sh /tmp/fw_upgrade_2p.sh
exit
fi
$YI_HACK_PREFIX/script/check_conf.sh
hostname -F $YI_HACK_PREFIX/etc/hostname
export TZ=$(get_config TIMEZONE)
if [[ $(get_config SWAP_FILE) == "yes" ]] ; then
SD_PRESENT=$(mount | grep mmc | grep -c ^)
if [[ $SD_PRESENT -eq 1 ]]; then
if [[ -f /tmp/sd/swapfile ]]; then
swapon /tmp/sd/swapfile
else
dd if=/dev/zero of=/tmp/sd/swapfile bs=1M count=64
chmod 0600 /tmp/sd/swapfile
mkswap /tmp/sd/swapfile
swapon /tmp/sd/swapfile
fi
fi
fi
if [[ x$(get_config USERNAME) != "x" ]] ; then
USERNAME=$(get_config USERNAME)
PASSWORD=$(get_config PASSWORD)
ONVIF_USERPWD="user=$USERNAME\npassword=$PASSWORD"
echo "/:$USERNAME:$PASSWORD" > /tmp/httpd.conf
fi
if [[ x$(get_config SSH_PASSWORD) != "x" ]] ; then
SSH_PASSWORD=$(get_config SSH_PASSWORD)
PASSWORD_MD5="$(echo "${SSH_PASSWORD}" | mkpasswd --method=MD5 --stdin)"
cp -f "/etc/passwd" "/tmp/sd/yi-hack/etc/passwd"
sed -i 's|^root::|root:'${PASSWORD_MD5}':|g' "/tmp/sd/yi-hack/etc/passwd"
sed -i 's|/root|/tmp/sd/yi-hack|g' "/tmp/sd/yi-hack/etc/passwd"
mount --bind "/tmp/sd/yi-hack/etc/passwd" "/etc/passwd"
cp -f "/etc/shadow" "/tmp/sd/yi-hack/etc/shadow"
sed -i 's|^root::|root:'${PASSWORD_MD5}':|g' "/tmp/sd/yi-hack/etc/shadow"
mount --bind "/tmp/sd/yi-hack/etc/shadow" "/etc/shadow"
fi
case $(get_config RTSP_PORT) in
''|*[!0-9]*) RTSP_PORT=554 ;;
*) RTSP_PORT=$(get_config RTSP_PORT) ;;
esac
case $(get_config ONVIF_PORT) in
''|*[!0-9]*) ONVIF_PORT=80 ;;
*) ONVIF_PORT=$(get_config ONVIF_PORT) ;;
esac
case $(get_config HTTPD_PORT) in
''|*[!0-9]*) HTTPD_PORT=8080 ;;
*) HTTPD_PORT=$(get_config HTTPD_PORT) ;;
esac
# todo
#if [ ! -f $YI_PREFIX/cloudAPI_real ]; then
# mv $YI_PREFIX/cloudAPI $YI_PREFIX/cloudAPI_real
# cp $YI_HACK_PREFIX/script/cloudAPI $YI_PREFIX/
#fi
if [[ $(get_config DISABLE_CLOUD) == "no" ]] ; then
(
if [ $(get_config RTSP_AUDIO) != "no" ]; then
touch /tmp/audio_fifo.requested
fi
if [ $(get_config SPEAKER_AUDIO) != "no" ]; then
touch /tmp/audio_in_fifo.requested
fi
cd /home/app
LD_LIBRARY_PATH="/tmp/sd/yi-hack/lib:/lib:/usr/lib:/home/lib:/home/qigan/lib:/home/app/locallib:/tmp/sd:/tmp/sd/gdb" ./rmm &
sleep 6
dd if=/tmp/audio_fifo of=/dev/null bs=1 count=8192
# dd if=/dev/zero of=/tmp/audio_in_fifo bs=1 count=1024
./mp4record &
./cloud &
./p2p_tnp &
./oss &
if [ -f ./oss_fast ]; then
./oss_fast &
fi
if [ -f ./oss_lapse ]; then
./oss_lapse &
fi
./rtmp &
./watch_process &
)
else
(
if [ $(get_config RTSP_AUDIO) != "no" ]; then
touch /tmp/audio_fifo.requested
fi
if [ $(get_config SPEAKER_AUDIO) != "no" ]; then
touch /tmp/audio_in_fifo.requested
fi
cd /home/app
LD_LIBRARY_PATH="/tmp/sd/yi-hack/lib:/lib:/usr/lib:/home/lib:/home/qigan/lib:/home/app/locallib:/tmp/sd:/tmp/sd/gdb" ./rmm &
sleep 6
dd if=/tmp/audio_fifo of=/dev/null bs=1 count=8192
# dd if=/dev/zero of=/tmp/audio_in_fifo bs=1 count=1024
# Trick to start circular buffer filling
start_buffer
if [[ $(get_config REC_WITHOUT_CLOUD) == "yes" ]] ; then
./mp4record &
fi
mkdir /tmp/etc
cp -R /etc/* /tmp/etc
mount --bind /tmp/etc /etc
echo "127.0.0.1 api.eu.xiaoyi.com" >> /etc/hosts
)
fi
if [[ $(get_config HTTPD) == "yes" ]] ; then
mkdir -p /tmp/sd/record
mkdir -p /tmp/sd/yi-hack/www/record
mount --bind /tmp/sd/record /tmp/sd/yi-hack/www/record
httpd -p $HTTPD_PORT -h $YI_HACK_PREFIX/www/ -c /tmp/httpd.conf
fi
if [[ $(get_config TELNETD) == "no" ]] ; then
killall telnetd
fi
if [[ $(get_config FTPD) == "yes" ]] ; then
if [[ $(get_config BUSYBOX_FTPD) == "yes" ]] ; then
tcpsvd -vE 0.0.0.0 21 ftpd -w &
else
pure-ftpd -B
fi
fi
if [[ $(get_config SSHD) == "yes" ]] ; then
mkdir -p $YI_HACK_PREFIX/etc/dropbear
if [ ! -f $YI_HACK_PREFIX/etc/dropbear/dropbear_ecdsa_host_key ]; then
dropbearkey -t ecdsa -f /tmp/dropbear_ecdsa_host_key
mv /tmp/dropbear_ecdsa_host_key $YI_HACK_PREFIX/etc/dropbear/
fi
# Restore keys
# mkdir -p /etc/dropbear
# cp -f $SONOFF_HACK_PREFIX/etc/dropbear/* /etc/dropbear/
chmod 0600 $YI_HACK_PREFIX/etc/dropbear/*
dropbear -R -B
fi
if [[ $(get_config NTPD) == "yes" ]] ; then
# Wait until all the other processes have been initialized
sleep 5 && ntpd -p $(get_config NTP_SERVER) &
fi
ipc_multiplexer &
sleep 1
if [[ $(get_config MQTT) == "yes" ]] ; then
mqttv4 &
mqtt-config &
fi
sleep 5
if [[ $RTSP_PORT != "554" ]] ; then
D_RTSP_PORT=:$RTSP_PORT
fi
if [[ $HTTPD_PORT != "80" ]] ; then
D_HTTPD_PORT=:$HTTPD_PORT
fi
if [[ $ONVIF_PORT != "80" ]] ; then
D_ONVIF_PORT=:$ONVIF_PORT
fi
if [[ $(get_config ONVIF_WM_SNAPSHOT) == "yes" ]] ; then
WATERMARK="&watermark=yes"
fi
if [[ $(get_config RTSP) == "yes" ]] ; then
RTSP_AUDIO_COMPRESSION=$(get_config RTSP_AUDIO)
if [[ "$RTSP_AUDIO_COMPRESSION" == "none" ]] ; then
RTSP_AUDIO_COMPRESSION="no"
fi
RRTSP_MODEL=$MODEL_SUFFIX RRTSP_RES=$(get_config RTSP_STREAM) RRTSP_AUDIO=$RTSP_AUDIO_COMPRESSION RRTSP_PORT=$RTSP_PORT RRTSP_USER=$USERNAME RRTSP_PWD=$PASSWORD rRTSPServer &
if [[ $(get_config RTSP_STREAM) == "low" ]]; then
ONVIF_PROFILE_1="name=Profile_1\nwidth=640\nheight=360\nurl=rtsp://%s$D_RTSP_PORT/ch0_1.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=low$WATERMARK\ntype=H264"
fi
if [[ $(get_config RTSP_STREAM) == "high" ]]; then
ONVIF_PROFILE_0="name=Profile_0\nwidth=1920\nheight=1080\nurl=rtsp://%s$D_RTSP_PORT/ch0_0.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=high$WATERMARK\ntype=H264"
fi
if [[ $(get_config RTSP_STREAM) == "both" ]]; then
if [[ $(get_config ONVIF_PROFILE) == "low" ]] || [[ $(get_config ONVIF_PROFILE) == "both" ]] ; then
ONVIF_PROFILE_1="name=Profile_1\nwidth=640\nheight=360\nurl=rtsp://%s$D_RTSP_PORT/ch0_1.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=low$WATERMARK\ntype=H264"
fi
if [[ $(get_config ONVIF_PROFILE) == "high" ]] || [[ $(get_config ONVIF_PROFILE) == "both" ]] ; then
ONVIF_PROFILE_0="name=Profile_0\nwidth=1920\nheight=1080\nurl=rtsp://%s$D_RTSP_PORT/ch0_0.h264\nsnapurl=http://%s$D_HTTPD_PORT/cgi-bin/snapshot.sh?res=high$WATERMARK\ntype=H264"
fi
fi
$YI_HACK_PREFIX/script/wd_rtsp.sh &
fi
if [ "$MODEL_SUFFIX" == "h60ga" ]; then
SERIAL_NUMBER=$(dd bs=1 count=20 skip=784 if=/tmp/mmap.info 2>/dev/null | cut -c1-20)
HW_ID=$(dd bs=1 count=4 skip=784 if=/tmp/mmap.info 2>/dev/null | cut -c1-4)
else
SERIAL_NUMBER=$(dd bs=1 count=20 skip=656 if=/tmp/mmap.info 2>/dev/null | cut -c1-20)
HW_ID=$(dd bs=1 count=4 skip=656 if=/tmp/mmap.info 2>/dev/null | cut -c1-4)
fi
if [[ $(get_config ONVIF) == "yes" ]] ; then
if [[ $(get_config ONVIF_NETIF) == "wlan0" ]] ; then
ONVIF_NETIF="wlan0"
else
ONVIF_NETIF="eth0"
fi
ONVIF_SRVD_CONF="/tmp/onvif_srvd.conf"
echo "pid_file=/var/run/onvif_srvd.pid" > $ONVIF_SRVD_CONF
echo "model=Yi Hack" >> $ONVIF_SRVD_CONF
echo "manufacturer=Yi" >> $ONVIF_SRVD_CONF
echo "firmware_ver=$YI_HACK_VER" >> $ONVIF_SRVD_CONF
echo "hardware_id=$HW_ID" >> $ONVIF_SRVD_CONF
echo "serial_num=$SERIAL_NUMBER" >> $ONVIF_SRVD_CONF
echo "ifs=$ONVIF_NETIF" >> $ONVIF_SRVD_CONF
echo "port=$ONVIF_PORT" >> $ONVIF_SRVD_CONF
echo "scope=onvif://www.onvif.org/Profile/S" >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
if [ ! -z $ONVIF_PROFILE_0 ]; then
echo "#Profile 0" >> $ONVIF_SRVD_CONF
echo -e $ONVIF_PROFILE_0 >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
fi
if [ ! -z $ONVIF_PROFILE_1 ]; then
echo "#Profile 1" >> $ONVIF_SRVD_CONF
echo -e $ONVIF_PROFILE_1 >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
fi
if [ ! -z $ONVIF_USERPWD ]; then
echo -e $ONVIF_USERPWD >> $ONVIF_SRVD_CONF
echo "" >> $ONVIF_SRVD_CONF
fi
if [[ $MODEL_SUFFIX == "r30gb" ]] || [[ $MODEL_SUFFIX == "r40ga" ]] || [[ $MODEL_SUFFIX == "h51ga" ]] || [[ $MODEL_SUFFIX == "h52ga" ]] || [[ $MODEL_SUFFIX == "h60ga" ]] || [[ $MODEL_SUFFIX == "q321br_lsx" ]] ; then
echo "#PTZ" >> $ONVIF_SRVD_CONF
echo "ptz=1" >> $ONVIF_SRVD_CONF
echo "move_left=/tmp/sd/yi-hack/bin/ipc_cmd -M left" >> $ONVIF_SRVD_CONF
echo "move_right=/tmp/sd/yi-hack/bin/ipc_cmd -M right" >> $ONVIF_SRVD_CONF
echo "move_up=/tmp/sd/yi-hack/bin/ipc_cmd -M up" >> $ONVIF_SRVD_CONF
echo "move_down=/tmp/sd/yi-hack/bin/ipc_cmd -M down" >> $ONVIF_SRVD_CONF
echo "move_stop=/tmp/sd/yi-hack/bin/ipc_cmd -M stop" >> $ONVIF_SRVD_CONF
echo "move_preset=/tmp/sd/yi-hack/bin/ipc_cmd -p %t" >> $ONVIF_SRVD_CONF
fi
onvif_srvd --conf_file $ONVIF_SRVD_CONF
if [[ $(get_config ONVIF_WSDD) == "yes" ]] ; then
wsdd --pid_file /var/run/wsdd.pid --if_name $ONVIF_NETIF --type tdn:NetworkVideoTransmitter --xaddr "http://%s$D_ONVIF_PORT" --scope "onvif://www.onvif.org/name/Unknown onvif://www.onvif.org/Profile/Streaming"
fi
fi
framefinder $MODEL_SUFFIX &
# Add crontab
CRONTAB=$(get_config CRONTAB)
FREE_SPACE=$(get_config FREE_SPACE)
mkdir -p /var/spool/cron/crontabs/
if [ ! -z "$CRONTAB" ]; then
echo -e "$CRONTAB" > /var/spool/cron/crontabs/root
fi
if [ "$FREE_SPACE" != "0" ]; then
echo "0 * * * * /tmp/sd/yi-hack/script/clean_records.sh $FREE_SPACE" >> /var/spool/cron/crontabs/root
fi
$YI_HACK_PREFIX/usr/sbin/crond -c /var/spool/cron/crontabs/
# Add MQTT Advertise
if [ -f "$YI_HACK_PREFIX/script/mqtt_advertise/startup.sh" ]; then
$YI_HACK_PREFIX/script/mqtt_advertise/startup.sh
fi
# Remove log files written to SD on boot containing the WiFi password
#rm -f "/tmp/sd/log/log_first_login.tar.gz"
#rm -f "/tmp/sd/log/log_login.tar.gz"
#rm -f "/tmp/sd/log/log_p2p_clr.tar.gz"
#rm -f "/tmp/sd/log/log_wifi_connected.tar.gz"
if [[ $(get_config FTP_UPLOAD) == "yes" ]] ; then
/tmp/sd/yi-hack/script/ftppush.sh start &
fi
if [ -f "/tmp/sd/yi-hack/startup.sh" ]; then
/tmp/sd/yi-hack/startup.sh
fi
You must be logged in to post a comment.