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

OFFLINE: common code base #90

Open
jonesMeUp opened this issue Nov 9, 2022 · 40 comments
Open

OFFLINE: common code base #90

jonesMeUp opened this issue Nov 9, 2022 · 40 comments

Comments

@jonesMeUp
Copy link

jonesMeUp commented Nov 9, 2022

This is an attempt to make an universal initrun.sh file for offline patched ppsapp that runs on all firmware versions.
The key to this is to find an entry point in the boot sequence right before the ppsapp is started.
Please post your working env file for a currently not supportet firmware to get it work all all devices.

Functions:

  • All done in a single file
  • Cleanup the streaming folder after every recording (if its necessary)
  • Send MQTT commands to your smarthome central
  • Set the localtime by ntpd-server of your smarthome central

Now we go through it step by step.


Requirements

  • Read guinos instruction about changing the env file again! (0x0A000A at file ending, filelength on some versions, etc)
  • Your device was hacked by guino's guide (telnet and ssh are working).
  • Your device was cut form inet in the router (e.g. parental control) or by pi-hole and you have modified the ppsapp

Latest Update

  • Give 2 hints for putting the device offline
  • Test environment for the env file

[initrun.sh]

#!/bin/sh

DEBUG=0
####################################################################################
# Choose your streaming folder, comment out all other
# PATH_DEPTH: Depth of the day-folder (parent of index file)
####################################################################################
#PATH_VIDEO="/mnt/mmc01/sdrec"; PATH_DEPTH=3; sleep 5 #/sdrec/T-<serialNo>/mp4rec/YYYYMMDD-?M    
PATH_VIDEO="/mnt/mmc01/SDT"; PATH_DEPTH=5           # /mnt/mmc01/SDT/serialNo/record/YYYY/MM/DD
TIMEZONE="UTC-1"               # Coord. Universal Time  (edit me) # Central EU: winter 1, summer 2 hours difference
NTPD_IP="192.168.178.100"      # local NTPD Server IP   (edit me)
MQTT_IP="192.168.178.100"      # local MQTT Server IP   (edit me)
MQTT_PORT="1883"               # local MQTT Server Port (edit me)
HTTP_ALLOW="192.168.178."      # Allowed address space  (edit me)
MQTT_DEVICE="MQTT2_DVES_DOORB" # local MQTT Device Name (edit me)
####################################################################################
# FUNCTION: Set variable and send it as MQTT command
####################################################################################
sendMQTT() { 
  eval $1="$2" # Set Variable ($1: Variable-Name, $2:Variable-Value)
  /mnt/mmc01/mqtt_pub $MQTT_IP $MQTT_PORT $MQTT_DEVICE/$1 $2 
}
####################################################################################
# Create a http.conf that works also on android (remove HTTP Authentification)
####################################################################################
echo -e "H:/mnt/mmc01/ \nA:$HTTP_ALLOW \nD:*" > /mnt/mmc01/httpd.conf
####################################################################################
# Mount /mnt/mmc01 again, because:
# pps_sdcard_hisilinux.c:159]The /dev/mmcblk0p1 has been mounted to /mnt/mmc01!
# pps_sdcard.c:414]Force umount /mnt/mmc01
####################################################################################
mkdir -p /mnt/mmc01
mount -t vfat /dev/mmcblk0p1 /mnt/mmc01
####################################################################################
# Unpack /bin /etc /home /lib
####################################################################################
umount /opt/pps; 
mount -t cramfs /dev/mtdblock5 /opt/pps
tar xzf /opt/pps/app.tar.gz -C /
umount /opt/pps
if [ ! -e /mnt/mmc01/home ]; then cp -r /home /mnt/mmc01/; fi
echo "$TIMEZONE" > /etc/TZ
####################################################################################
# For new password: 'passwd -a des <new passwd>' [tested on 4.0.7]
####################################################################################
cp /mnt/mmc01/passwd /etc/passwd
cp /mnt/mmc01/shadow /etc/shadow # 2.10.5 has no shadow file by default
####################################################################################
# Start init
####################################################################################
rm -f /home/app/ppsapp # prevent initS from starting ppsapp
/home/init.d/initS &
sleep 10 # Wait for initS to finish
BB="/mnt/mmc01/busybox" # Busybox shortcut
$BB ntpd -Np $NTPD_IP &
$BB httpd -c /mnt/mmc01/httpd.conf -p 8080
$BB telnetd
[ $DEBUG -eq 1 ] && echo "" > /mnt/mmc01/buffer.log
[ $DEBUG -eq 1 ] && echo "PATH_DEPTH: $PATH_DEPTH" >  /mnt/mmc01/delete.log
[ $DEBUG -eq 1 ] && echo "PATH_VIDEO: $PATH_VIDEO" >> /mnt/mmc01/delete.log
####################################################################################
# Start ssh
####################################################################################
ln -s /mnt/mmc01/dropbearmulti /bin/scp
if [ ! -f /mnt/mmc01/dropbear_rsa_host_key ]; then 
  /mnt/mmc01/dropbearmulti dropbearkey -t rsa -f /mnt/mmc01/dropbear_rsa_host_key
fi
mkdir /etc/dropbear; cp /mnt/mmc01/dropbear_rsa_host_key /etc/dropbear/
/mnt/mmc01/dropbearmulti dropbear
####################################################################################
# Redirect ppsapp output to /dev/kmsg (more code, but same code for all devices)
####################################################################################
/mnt/mmc01/ppsapp 2>&1 | {
  while true; do 
    read -r BUF; case $BUF in ''|\#*) sleep 1; continue ;; esac
    echo "<1> $BUF" > /dev/kmsg
  done
} &
####################################################################################
# Handle events (Waiting for localtime slows down booting, but needed by MQQT)
####################################################################################
while [ $(date +%s) -lt 1645543474 ]; do :; done
REC_STOP=0 # Time when recording will stop (0: Recording has already ended)
sendMQTT RECORDING $REC_STOP
sendMQTT MMC_SIZE $(df -m /dev/mmcblk0p1 | grep dev/ | awk '{print $2}') #    [MB]
sendMQTT MAX_SIZE $(($MMC_SIZE / 2)) # Max allowed space for streaming videos [MB]
sendMQTT ACT_SIZE $($BB du -ms $PATH_VIDEO | awk '{print $1}')
sendMQTT VERSION  $(cat /tmp/version | awk '{print $5"@"$6}')
while true; do
  BUF=$(dmesg -c); case $BUF in ''|\#*) sleep 1; continue ;; esac 
  [ $DEBUG -eq 1 ] && echo "$BUF" >> /mnt/mmc01/buffer.log
  #################################################################################
  # Motion event has ended, now its paused for the rest of "shield time"
  #################################################################################
  if [ $REC_STOP -gt 0 ] && [ $(date +%s) -gt $REC_STOP ]; then
    REC_STOP=0;  sendMQTT RECORDING 0
    # Delete oldest streaming folder(s) until ACT_SIZE < MAX_SIZE
    while [ $($BB du -ms $PATH_VIDEO | awk '{print $1}') -gt $MAX_SIZE ]
    do 
      OLDEST=$($BB find $PATH_VIDEO -type d -mindepth $PATH_DEPTH \
              -maxdepth $PATH_DEPTH | $BB sort | $BB head -n 1)
      rm -rf $OLDEST
      [ $DEBUG -eq 1 ] && echo "$OLDEST was deleted" >> /mnt/mmc01/delete.log
    done
    sendMQTT ACT_SIZE $($BB du -ms $PATH_VIDEO | awk '{print $1}')
    [ $DEBUG -eq 1 ] && echo "Act folder size: $ACT_SIZE" >> /mnt/mmc01/delete.log
    # Delete empty parent folders (for devices with YYYY/MM/DD/HH folder format)
    $BB find $PATH_VIDEO -type d | $BB sort -r \
      | xargs $BB rmdir --ignore-fail-on-non-empty
  fi
  #################################################################################
  # Motion event
  #################################################################################
  case $BUF in *"motion detect"*)  # 2.10.5 and 4.0.7
    sendMQTT RECORDING 1
    REC_TIME=$(grep event_record_time /home/cfg/tuya_config.json \
     | awk '{sub(",","",$2); print $2}')
    REC_STOP=$((`date +%s` + REC_TIME)) ;;
  esac
  ################################################################################
  # Doorbell event (another case statement for portable case fallthrough)
  ################################################################################
  case $BUF in *"button ev: doorb"* | *"door bell  press do"*) # 2.10.5 | 4.0.7
    sendMQTT BUTTON "down"; sleep 1; sendMQTT BUTTON "up";;
  esac
done

Step 1: Copy needed files to the root of the SD-Card. You will need them for using all functions
Most of them can be found here
ppsMmcTool.txt, env and ppsFactoryTool.txt (from guinos hack)
busybox
dropbearmulti
jpeg-arm
mqtt_pub
passwd
shadow (only if you didn't use guinos Hash trick but passwd -a des <new passwd>)
ppsapp (modified by you)
set
index.html
upload.html
initrun.sh (from above)
cgi-bin folder (without cleanup.cgi)

Step 2: Change the Kernel Bootargs
The part after bootargs= must be from your /proc/cmdline (Read guinos guide)

Version 2.10.5: No need for a change of the kernel bootargs. The env file should look like this:

bootargs=mem=37 console=ttyAMA0,115200n8 mtdparts=hi_sfc:192k(bld)ro,64k(env)ro,64k(enc)ro,64k(sysflg)ro,3136k(sys),4352k(app),320k(cfg) ppsAppParts=0 ppsWatchInitEnd ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,ThankYouGuino,T

Version 4.0.7
Extend the env file with the 'ip= part
AGAIN: Read guinos guide about editing the env file. I am using Notepad++ which keeps the file ending intact.

hack=setenv bootargs mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) 'ip=\\${T//_/\\$S}:::::;S=\\$\\'\\\\x20\\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&";eval
ipaddr=0;run hack;bootm 0x81C08000;

Step 3: Write bootargs to the flash
When you have modified the env file, it must be updated in the flash memory of the device.
This is done by switching the device off (cut power) and holding the reset button for 5s while powering on.

Step 4: Have fun, you are done


What is the env file and why it is important?
The env file holds the kernel bootargs and its our way to jump into the boot sequence. The file differs alot between every device.
It's very important that the bootargs fit to your device and that the null byte is at the end of file (read guio's hacking guide)

Why we have to jump into the boot sequence before ppsapp is started?
The main program of the device (ppsapp) has a watchdog timer that restarts ppsapp when it is stalling.
This is also triggered when ppsapp get killed. So we need to get our modified ppsapp started instead of the original one.

Why the "ip=" parameter looks so fuzzy?
The ip parameter is parsed by u-boot bootloader and then its parsed by /etc/init.d/S80network.
So we have to reverse it back to get the initial ip parameter.


[Background knowledge] How i got the correct parameter for the env file
All tests were done with the busybox version recommended by guino.
Setting up a test scenario for env file in /mnt/mmc01/

env_test file holds only the ip part of our test env (this will be the ip part output of a working /proc/cmdline).
On my action door bell (4.0.7) its
ip=\${T//_/\$S}:::::;S=\$\'\\x20\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run1.sh&";eval

run1.sh file is a very simply initrun.sh version

#!/bin/sh
echo -e "\n\nworking!"

test.sh file does the S80network part of our test

#!/bin/sh

part1=""
unused1=""
unused2=""
unused3=""
unused4=""
part2=""

for command in `cat /mnt/mmc01/env_test`
do
  for var in part1 unused1 unused2 unused3 unused4 part2
  do eval read $var 
  done << EOF
	`echo "$command" | sed "s/:/\n/g" | sed "s/^[ 	]*$/-/g"`
EOF
    part1=`echo "$part1" | cut -d = -f 2`
done
cmd="ifconfig $part2 $part1"
echo "Custom cmd: $cmd"
eval $cmd

When starting test.sh it emulates S80network and should do the mounting of /mnt/mc01 and running run1.sh.
It hopefully says working!. Mounting errors can be ignored.
If there is no working! message you can now edit the env_test file until you find the correct string.

After this is working we have another layer of string conversation. It's done by u-boot and i didn't find a way to test it
with a simple script, so I was forced to edit the env file and restart the doorbell.
I did it several times until /proc/cmdline shows the output i created with the test above.

Remember:
It's not a logical string, its a string thats converted twice (by u-boot and S80network) so its a frustrating job.

@guino
Copy link
Owner

guino commented Nov 9, 2022

One additional note for the less familiar with these devices: make sure ppsapp is on the root of the SD card for this to work.
@jonesMeUp there's actually a way to get the output of the ppsapp (already running) but this is fine.
I like that this approach would work on devices that have issues when you kill and run ppsapp again.

@jonesMeUp
Copy link
Author

One additional note for the less familiar with these devices: make sure ppsapp is on the root of the SD card for this to work

you are right, shame on me. I hated my math teacher for his "as you already know..." and now I am like him lol

there's actually a way to get the output of the ppsapp (already running) but this is fine

I know, i used it in my offline typ1 version for 4.0.7. This is only temporary. I want the same initrun.sh for the 4.0.7 as it runs on 2.10.5 (entry point before starting the init-script)
But i haven't any idea of making this right now. It will cost me tousands of trial and errors and i am in a bit stress right now.
I posted my code that soon, because there is a chance that some people could need it.

I like that this approach would work on devices that have issues when you kill and run ppsapp again

thats the plan - an universal code base that works on all devices with an early entry point, so no kill is needed.
Atm, 4.0.7 needs ~1min longer than 2.10.5 to boot up. I can't accept this, so i will spend some time on this in my next holiday

As always: any help is welcome.

@jonesMeUp
Copy link
Author

Ok, i am not smart enough to get an early entry point for initrun.sh on 4.0.7
I have tried countless versions to get the env file jumping into initrun.sh before ppsapp is loaded.

Using versions of env demo before 4.x ignored my env file completly and booted with the last bootargs.

On the 4.x version i wasn't able to get a boot when changing the env file with the "_" to " " hack.

I don't know what went wrong, but i know with my trial and errors i have no chance of a success.
Example:

hack=setenv bootargs ${bootargs} - ip=\\${T//_/\\$\\'"\\\\x20"\\'}:::::";T=\\"sleep_5;mkdir_-p_/mnt/mmc01;mount_-t_vfat_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&\\";eval"
ipaddr=0;run hack;bootm 0x81C08000;
<NUL>

All tries were done with the special ending and /proc/cmdline from my device.
Changing sleeping time or deleting "date>/tmp/hack" in the original env hack worked, so the testing procedure works, its only my code that makes trouble.

@guino
Copy link
Owner

guino commented Nov 12, 2022

@jonesMeUp the issue I had with some devices (i.e. Merkury720) was that the size of /proc/cmdline was severely reduced compared to the other devices so I could not put 'a lot' of commands in the bootargs (it basically got cut off). Now, I do not have a 4.x firmware device to tell you what size of command line it can take -- I only have the BazzDoorBell (2.9.x), Merkury720 (2.7.x) and the LSC devices I got this past month (2.10.36 and 7.6.32).

One way to figure out how much you can put into the boot args is:
-hack it the normal way so you have telnet
-add some 'useless' parameters after the bootargs to see how much shows up with cat /proc/cmdline in telnet -- you may want to add little by little since too much data may prevent the device from booting (but it should be reversible with a smaller bootargs)

The available boot argsspace may not be enough to mount the card and run the script (I don't think it was enough on the Merkury720), like I said: I don't have a 4.x firmware device to tell you that.

@jonesMeUp
Copy link
Author

@guino Thx for the info of the bootargs size, it explained a lot!
My summary of getting some space for the bootargs into the env file:

Start:

hack=setenv bootargs 'mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 - ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack;(sleep'
ipaddr=0;run hack;bootm 0x81C08000;
<NUL>

End (max number of chars that works on 4.0.7)

hack=setenv bootargs 'mem=64M console=ttySAK0,115200n8 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 - ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/h1aaaaaaaaaa;date>/tmp/h2bbbbbbbbbb;date>/tmp/h3abc;(sleep'
run hack;bootm 0x81C08000;
<NUL>

I think thats not enough size to put the SD-Card mounting (with the built in ash replace function) into the bootargs.

perhaps hack=setenv bootargs 'root=/dev/mmcblk0p1 rw rootwait ... or the u-boot mmc command could be a solution!?
But thats beyond my skills :(

@guino
Copy link
Owner

guino commented Nov 15, 2022

@jonesMeUp if you have a device with MTDNUM=5 in /etc/init.d/S90PPStrong (most newer devices), you could probably remove the ppsAppParts=5 from the boot args (giving you 14 more characters to use). I believe you can probably remove the console= parameter unless you're using the serial terminal for testing (giving you more 24 characters to use) -- I don't know if that gives you enough space. If you remove the other stuff it probalbly won't boot.

@jonesMeUp
Copy link
Author

jonesMeUp commented Nov 17, 2022

first success of testing:
/proc/cmdline gives me
mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=${T//_/$'\x20'}:::::T="(sleep_30&&/mnt/mmc01/initrun.sh&)"&&eval
but initrun.sh is not called yet.
I am on it...

@guino
Copy link
Owner

guino commented Nov 18, 2022

@jonesMeUp you're probably making it harder by mixing the two parts of the 'hack' command, you should be able to not use the single quote and just do something like:

hack=setenv bootargs mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=\\${T//_/\\$\\'"\\\\x20"\\'}:::::";T=\\"sleep_5;mkdir_-p_/mnt/mmc01;mount_-t_vfat_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&\\";eval"

I still don't know if there's enough space but the single and double quotes were carefully crafted in that command so if you start adding quotes anywhere 'around' the command things will break.

@jonesMeUp
Copy link
Author

@guino: Thx for your support. But that was my first try, and it didn't work.
/proc/cmdline =>
mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=${T//_/$'"\x20"'}:::::"

For testing reasons, i don't care about the length. I use the standard command sleep 30;/mnt/mmc01/initrun.sh& because this will work perfect on 4.0.7 (mjpeg, telnet, mqqt,..). If i get this to work, i will have a look on the mounting.

Here are 2 of my testings (i think the flash will die soon, because i tested alot):

hack=setenv bootargs 'mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg)
 - ip=\\${T//_/\\ }:::::T="(sleep_30&&/mnt/mmc01/initrun.sh&)"&&eval
ipaddr=0;run hack;bootm 0x81C08000;

/proc/cmdline =>

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg)
 - ip=${T//_/ }:::::T="(sleep_30&&/mnt/mmc01/initrun.sh&)"&&eval

##########################

hack=setenv bootargs 'mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg)' 
- ip=\\${T//_/\\$\\'\\\\x20\\'}:::::T="(sleep_30&&/mnt/mmc01/initrun.sh&)"&&eval
ipaddr=0;run hack;bootm 0x81C08000;

/proc/cmdline =>

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg)
 - ip=${T//_/$'\x20'}:::::T="(sleep_30&&/mnt/mmc01/initrun.sh&)"&&eval

##########################

When i get cmdline like:

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg)
 - ip=${T//_/$'\x20'}:::::T="(sleep_30;/mnt/mmc01/initrun.sh&)";eval

or

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg)
 - ip=${T//_/$'\x20'}:::::T="(sleep_30&&/mnt/mmc01/initrun.sh&)"&&eval

I was happy, becuase it looked right and worked in ash, but doorbell was still laughing.
Beer did this to my brain :(

@guino
Copy link
Owner

guino commented Nov 18, 2022

@jonesMeUp the flash chip on this devices is rated for at least 100k erase/write cycles -- if you wrote a different setting, tested, repeated 100 times every day, it would take you more than 2 years and 8 months to reach that (pretty sure this testing won't be the cause of death of your device).

Regarding the settings, this may actually be a difference in the uboot version on these devices -- I only have a device with 2.9.6 and another with 2.7.6 (no 4.0.x device) so I have no way of checking how the setenv command works on that uboot version -- the hint I gave you about not using quotes was based on the existing hack from here which adds the parameters without quotes (and works), but like I said the uboot version is likely different and may not be handling it the same way.

There's also a chance the S80network script has changes on that device compared to mine, I'd have to get a copy of that to compare (might be in the original thread)

@jonesMeUp
Copy link
Author

@guino: ok, so i still have 14days left for testing ;)
I used your instruction for the hack where it copies the /home folder to mmc, but i can't see a S80network script in init.d/
initS
S00config
S01loadpps
S20cmd_router
S23hostapd_conf
S24udhcpd
S25ppsdsry
S27wpa_supplicant
S60ppsapp

@guino
Copy link
Owner

guino commented Nov 18, 2022

@jonesMeUp that S80network is actually in the firmware under /etc/init.d -- the home folder in the SD card does have other scripts which also run (just not from the SD card).

You have to either look for the file in telnet under /etc/init.d or you can use this URL which works on older devices:
http://admin:056565099@IP/proc/self/root/etc/init.d/S80network

@guino
Copy link
Owner

guino commented Nov 18, 2022

@jonesMeUp that is the same file as my devices so similar ip= value should work on it (as long as it doesn't get cut off). What I'm seeing is that your hack line is missing some important \ to escape the " before the T= and before ;eval -- I would also use ; instead of && to both reduce size and to make sure that doesn't cause some other issue.

Not to discourage you but I remember I spent a very long time testing/tweaking to get this thing to work -- the mix between the uboot command escaping and processing, along with the shell script escaping and processing and the variable storage (both in uboot and in the shell script) make it for quite a messy solution, but that beats having to open the device and use a hardware programmer or serial adapter, so we use what we can.

@jonesMeUp
Copy link
Author

i used ; in some testings, because depending on ' using ; get some errors in ash (i tested proc/cmdline output in ash), && worked always. but i also tested with ;
what i don't understand is that the proc/cmdline looks good, but wasn't executed.
...but i still have 14days left of testing before flash will be destroyed

@jonesMeUp
Copy link
Author

So, if the S80network is still the same, it should work when the /proc/cmdline is the same, right?
Could you show me a /proc/cmdline output from another version with ash built in replacement function for "__" to " "?
Not the env file, the /proc/cmdline output. As shown above, the Orion SC008HA env file didn't work.
I am to much of a newbie to understand the whole project :(
(It tooks me several hours and the help from a friend to understand the ip= stuff, where the command was cut because of the needed space char)
But i promise to update this thread to a good guide for "after guinos and jandys patch" to "offline common code" as soon as the 4.0.7 runs without that "killing ppsapp" stuff that needs ~1min more booting time and an different initrun.sh file
I think the size of the cmdline could be enough for mounting mmc01, i don't see a reason for a new S90PPStrong as seen here
because deleting /home/app/ppsapp as seen above in [initrun.sh] for 2.10.5 in initrun.sh should be enough.

@guino
Copy link
Owner

guino commented Nov 18, 2022

@jonesMeUp yes, since S80network is the same it should work the same way IF we can get the /proc/cmdline to look the same. The issue I remember having was not only the size limit of cmdline but also that uboot was 'building' the bootargs parameter at boot time (so whatever I 'saved' as bootargs wasn't being used to boot). So if you look at the env file for 2.7.6 and 4.0.x you'll see that there's an 'ipaddr=' value being set which executes run hack right before the bootm command which is how we 'modify' the bootargs from uboot into what we need. More importantly, you'll notice there's a single quote ( ' ) lingering around in the hack command which was necessary to close the command started (internally in uboot) when using the ipaddr setting. Looking at the last 'hack' lines you provided above I think you moved the single quote to before the mem= and it should be right before the - ip= part -- my first suggestion is to try moving that to the right place so the only single quote is '- ip=.

Next, because of how we're setting the bootargs, there's possibly going to be an additional escaping necessary in the hack command in order for the cmdline to come out the way you want it -- and you'll still likely need to have that single quote in there as well to make sure it will work. I don't want to discourage you but this can be a complex endeavor... like I said: the main thing is getting the cmdline to look correct (just like it looks on 2.10.5 firmware).

Honestly I didn't think of 'removing' the useless parameters from the cmdline because I always try to maintain as much of the factory settings/files of the device as possible (or people end up making changes and not remembering how to revert them), so that's why I never researched trying to alter the cmdline -- but I also factored in how long it may take to get anything else working.

In regards to cmdline: Unfortunately I only have these 2 devices and neither uses the replacement from _ to ' ':

  • 2.7.6 firmware
mem=64M console=ttySAK0,115200n8 mtdparts=spi0.0:256k(bld)ro,64k(env)ro,64k(enc)ro,64k(sysflg)ro,2496k(sys),4608k(app),640k(cfg) ppsAppParts=5 ip=0 - ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack;(sleep

and

  • 2.9.6 firmware which was flash-hacked so it has the default cmdline
mem=37M console=ttyAMA0,115200n8 mtdparts=hi_sfc:192k(bld)ro,64k(env)ro,64k(enc)ro,64k(sysflg)ro,3136k(sys),4352k(app),320k(cfg) ppsAppParts=5 ppsWatchInitEnd

The 2.9.6 device is my doorbell which is installed outside (-4C right now) so if it wasn't such a pain to remove it I'd take it out and apply the hack so you could see the cmdline on it, that said: it should be exactly the same as on your 2.10.5 device.

@jonesMeUp
Copy link
Author

@guino
I thought you had the code at hand, i don't want you to go outside.

Telling me about S80network was the hint that saved my weekend!
After i put handmade cmdline code into S80network, if found my problem at another location: ash is evil!
The built-in replace function makes the trouble
NOT WORKING
ip=${T//_/$'\\t'}:::::;T="sleep_3;echo_123";eval
WORKING:
ip=${T//_/$S}:::::;S=$'\\x20';T="sleep_3;echo_123";eval
ip=${T//_/$S}:::::;S=$'\\t';T="sleep_3;echo_123";eval

So another few bytes of additional length...
But i am on it, more testing to win the fight against 4.0.7 ;)

@guino
Copy link
Owner

guino commented Nov 19, 2022

@jonesMeUp the thing with S80network is you can use it to see if your /proc/cmdline will work (good) but after that you still have to figure out the boot settings to result in the desired cmdline -- I remember this wasn't a fun job, but also remember it being rewarding when I finally had success... getting more functions out of thee devices is always a lot of trial and error, but it's fun if you like a challenge.

@jonesMeUp
Copy link
Author

@guino the env file is working right now. It worked the way i was hoping, no need for an expensive copy cmd in the bootargs, the 2.10.5 version from above can be the universal initrun.sh
I am too tired now for more testings with my single file solution (initrun.sh will eat up event.sh) on 2.10.5 and 4.0.7
Btw, i have some bytes left in the bootargs (244/255 used, e.g. mount doesn't need the vfat switch)
Perhaps we can run doom in 11 bytes ;)

I remember this wasn't a fun job

Yep, my tabletop holds a lot of tooth imprints
And of course in these times i hated you for making so much great progress in short time, while i was crying whitout any idea of the next step ;)

but also remember it being rewarding when I finally had success

Yep, but without your support i never had a chance to make this possible.
More then 1 time i was thinking of quitting the single file solution. but i wanted to give something back to your great project!

@guino
Copy link
Owner

guino commented Nov 24, 2022

@jonesMeUp nice job! I'm sure you learned a bunch! I hope you got some satisfaction one you saw it working.

@jonesMeUp
Copy link
Author

@guino thx. yep, i had to learn and test a lot, but in the end the Infinite-Monkey-Theorem was the solution.
I am proud that i can give back something to this project that freed my doorbell.
I also tried to find a solution for the problem with ppsapp that stopped reading tuya_config.json, but i failed the ghidra test.
So i had to drop the doorbell from the smartlife app and add it again (more than once).

I had even tried to solder some wires on a little chip of a broken remote control, but i lost the game.

You really made a great job in your work, guides and support!
I learned some new linux stuff and using ghidra.

When your hack is released, I will try to add the lsc outdoor camera to the supported list of this thread.

@xraive
Copy link

xraive commented Apr 2, 2023

Hi All

@guino thx. yep, i had to learn and test a lot, but in the end the Infinite-Monkey-Theorem was the solution. I am proud that i can give back something to this project that freed my doorbell. I also tried to find a solution for the problem with ppsapp that stopped reading tuya_config.json, but i failed the ghidra test. So i had to drop the doorbell from the smartlife app and add it again (more than once).

I had even tried to solder some wires on a little chip of a broken remote control, but i lost the game.

You really made a great job in your work, guides and support! I learned some new linux stuff and using ghidra.

When your hack is released, I will try to add the lsc outdoor camera to the supported list of this thread.

Thank for all your work on this guys, Would this work on my device?

devname":"Smart Home Camera",
"model":"Mini 11S",
"serialno":"XXXXXXXXXXXxx",
"softwareversion":"4.0.7",
"hardwareversion":"M11S_A2_V10_F37",
"firmwareversion":"ppstrong-a3-tuya2_merkury-4.0.7.20210624

I've tried following along and I can't get the script to start

@jonesMeUp
Copy link
Author

@xraive we need more info.
I've tried following along and I can't get the script to start
Did you read the requirements for this topic?
Is guino's hack already working?

@xraive
Copy link

xraive commented Apr 3, 2023

@xraive we need more info. I've tried following along and I can't get the script to start Did you read the requirements for this topic? Is guino's hack already working?

@jonesMeUp sorry about that, yes to both of your questions. I"ve tried changing the env to match what you mentioned works for 4.0.7 but I'm unable to get initrun.sh to load. The camera boots fine but initrun.sh isn't loaded.

/proc/cmdline =>

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ip=\${T//_/\$S}:::::;S=\$\'\\x20\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&";eval

this loads initrun.sh
/proc/cmdline =>

mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 - ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack;(sleep

Am I missing something? Let me know if there is additional info I can provide you.

Thanks for your assistance.

@jonesMeUp
Copy link
Author

@xraive thx for your feedback, lets try to find out the problem.

perhaps your device don't accept the length of the command-line (my cmdline seems to have a length of 4 more chars).
can you add some chars to the working cmdline to simulate the length of the not working one?
e.g replacing the substring ;date>/tmp/hack by ;date>/tmp/hack1234

if thats the problem:
rename /mnt/mmc01/initrun.sh to /mnt/mmc01/run.sh in the not working script.
(also change the filename in the script to the new one)
and try again.

@xraive
Copy link

xraive commented Apr 3, 2023

@jonesMeUp

Thanks for following up. Here is what I tried.

Works

hack=setenv bootargs mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 '- ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack;(sleep

/proc/cmdline =>

mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 - ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack;(sleep

Doesn't work when I add 4 characters.

hack=setenv bootargs mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 '- ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack1234;(sleep

/proc/cmdline =>

mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 - ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack1234;(sleep

Doesn't Work (I renamed initrun to inirun in the script and the file)

hack=setenv bootargs mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) '- ip=${T//_/$S}:::::;S=$'\\x20';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initru.sh&";eval

/proc/cmdline =>
mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=${T//_/$S}:::::;S=$x20;T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/inirun.sh&";eval

Let me know if you need anytning else.

@jonesMeUp
Copy link
Author

@xraive
we know that the length of the cmdline was reduced in 4.x, so the first test was to look on the length.
and your first test shows that the length was reduced on your device even more.

but you misunderstood me. i wanted you to make the cmdline 4 chars shorter for the 2. test.
'/mnt/mmc01/run.sh' instead of '/mnt/mmc01/initrun.sh', so we would keep the length that works for you.
instead you renamed it to 'initru.sh' which is only 1 char shorter.

so please try again with '/mnt/mmc01/run.sh' instead of '/mnt/mmc01/initrun.sh'
(wich is exactly 4 chars shorter and have the exact length of your working cmdline).

@xraive
Copy link

xraive commented Apr 3, 2023

@jonesMeUp
Here is what i tried. It's not working for me. I can't telnet into the device

hack=setenv bootargs mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) '- ip=${T//_/$S}:::::;S=$'\\x20';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run.sh&";eval

/proc/cmdline =>
mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=${T//_/$S}:::::;S=$x20;T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run.sh&";eval

@jonesMeUp
Copy link
Author

Just to be sure, you have the null byte at the end of your env file? On my device it looks like this (Notepad++)
grafik
And pressed reset on booting your device while powering on for >= 5sec ?
You have renamed your initrun.sh to run.sh?
If all this is true, we have to put a debug message into run.sh to be sure it is executed.
/mnt/mmc01/busybox touch /mnt/mmc01/test1 will write a file to the SD-Card which can be checked in your Card-Reader.

@xraive
Copy link

xraive commented Apr 3, 2023

@jonesMeUp

I'm using Notepad++ as well. Using the same env file as above I get the following.

image

hack=setenv bootargs mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) '- ip=${T//_/$S}:::::;S=$'\\x20';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run.sh&";eval

/proc/cmdline =>
mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=${T//_/$S}:::::;S=$x20;T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run.sh&";eval

I added the debug message in run.sh but I don't see the "test1" file created. It looks like run.sh isn't running yet.

#!/bin/sh
/mnt/mmc01/busybox touch /mnt/mmc01/test1

image

I also tried making changes to my env file to also match the one you posted above and I had the same result. See below.

image

/proc/cmdline =>

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) - ip=\${T//_/\$S}:::::;S=\$\'\\x20\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run.sh&";eval

@jonesMeUp
Copy link
Author

@xraive
I also tried making changes to my env file to also match the one you posted above and I had the same result.
nope, you didn't. Try again withe the correct env file and give me some good news ;)

Part 2 of the env file i posted in the instruction:
'ip=\\${T//_/\\$S}:::::;S=\\$\\'\\\\x20\\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&";eval

Part 2 of the env file in your last post:
'- ip=${T//_/$S}:::::;S=$'\\x20';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/run.sh&";eval

@ALL
don't just copy/paste an env file. as you can read in guinos tutorial is based in your hardware. in this case the working cmdline from xraive was identically.

@xraive
Copy link

xraive commented Apr 7, 2023

@jonesMeUp
Sorry for the late reply I was away for work and didn't have time to try it out. I tried the following and still no luck.

image

hack=setenv bootargs mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) 'ip=\\${T//_/\\$S}:::::;S=\\$\\'\\\\x20\\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&";eval
ipaddr=0;run hack;bootm 0x81C08000;

Output of /proc/cmdline

mem=64M mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ip=\${T//_/\$S}:::::;S=\$\'\\x20\';T="mkdir_-p_/mnt/mmc01;mount_/dev/mmcblk0p1_/mnt/mmc01;/mnt/mmc01/initrun.sh&";eval

So far I can only get this working with guino's original env file.

hack=setenv bootargs mem=64M console=ttySAK0,115200n8 loglevel=10 mtdparts=spi0.0:256k(bld),64k(env),64k(enc),64k(sysflg),3m(sys),4032k(app),640k(cfg) ppsAppParts=5 ip=0 '- ip=30;/mnt/mmc01/initrun.sh)&:::::;date>/tmp/hack;(sleep

What device do you have have? Is there anything else I can provide to further troubleshoot. I really want to get this to work.

I also wanted to let you know that I did make sure to check that the boot args were the same before I tried using your env. I must have made a mistake copying and pasting because I did try your initial solution. However I did spot an error in my previous tests. I always had '- ip= instead of 'ip= in my file.

Thank you for all your efforts so far.

@jonesMeUp
Copy link
Author

@xraive
i am on holiday, i will have a look when i am back home.
if you have linux skills, you can scroll up and have a look at guinos tip on S80network.
and you can shorten the line again (rename filename run.sh instead of initrun.sh)

@aladin2000
Copy link

Is there an explanation or my 'open connected port' to amazon ?
using the 'offline' procédure ..... ( see Image of Nmap in red )
image

@jonesMeUp
Copy link
Author

@aladin2000
I think you didn't cut the camera from the inet inside your router, but in the requirements on top of the page it says:
Your device was cut form inet in the router... That should do the trick.

@xraive
I didn't forget you, but i got a covid wich makes it hard for me to breathe and to concentrate.
Slowly it is getting better and i will make a guide about "coding" the input for S80network as soon as i am back
to nornal health.

@aladin2000
Copy link

page it says: Your device was cut form inet in the router... That should do the trick.

really how to do that ?
my device is connected to the main router of my isp. I do not see except ssid without dns or using vlan

would you like to explain me why we could not use the hosts file for amazon ?

@jonesMeUp
Copy link
Author

I'm an old man and in every line of code i have to invested tons of time,
so don't ask me about the host file or other linux thinks.
When i came in school, the pocket calculator had not yet been invented.
I try my best to help, but i am just putting the great stuff from guino into
a trial and error game which i play for as long as it takes to get my devices offline.
I think if you have no parental control to your router, you should do somethink about it.
Perhaps have a look here: isp router

@guino
Copy link
Owner

guino commented Jun 2, 2023

@aladin2000 I know tuya uses aws servers (for sure/at least to provide firmware update files), so I would expect to see connections to AWS from the device.

The only way to use the hosts file to block/modify the address being used by the device is if you know the DNS name the device is trying to access. For instance if you know the device is trying to use 'my.server.com' you could add 127.0.0.1 my.server.com to the hosts file which would basically block access to that server. If the device is trying to use an IP address (no DNS name) then the only way to block that would be in your router/firewall (IF AND ONLY IF your router/firewall supports such features).

A lot of basic/ISP routers do not have any 'advanced' settings/firewall features when it comes to outgoing traffic, so not only you need a decent router but you'll need to know how to configure the settings on the specific router which is usually different for each router. Some routers have parental control settings (as suggested by jonesMeUp) which may allow blocking IPs or DNS names, but again you'll need to look up the manual for your router to figure out how to use the settings (if possible at all).

@xraive
Copy link

xraive commented Jun 4, 2023

@jonesMeUp no worries whenever you're upto it and have the free time. I hope you get well soon.

Thanks for the update.

@jonesMeUp
Copy link
Author

Update
Show a test environment for getting the env file to work on strange systems.
Its a trial and error process to get the correct settings.
So you are on your own on this road, because i can only test on 2.10.5 and 4.0.7 bought on the german action store.

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