mirror of
https://github.com/tuya-cloudcutter/tuya-cloudcutter.git
synced 2026-02-19 21:51:18 +01:00
Add -o option to override device AP name
clean up .sh formatting/lint
This commit is contained in:
66
common.sh
66
common.sh
@@ -5,75 +5,83 @@ AP_CONNECTED_ENDING=""
|
||||
FIRST_WIFI=$(nmcli device status | grep " wifi " | head -n1 | awk -F ' ' '{print $1}')
|
||||
|
||||
if [ "${WIFI_ADAPTER}" == "" ]; then
|
||||
WIFI_ADAPTER="${FIRST_WIFI}"
|
||||
WIFI_ADAPTER="${FIRST_WIFI}"
|
||||
fi
|
||||
|
||||
if [ "${WIFI_ADAPTER}" == "" ]; then
|
||||
echo "[!] Unable to auto-detect wifi adapter. Please use the '-w' argument to pass in a wifi adapter."
|
||||
echo "See '$0 -h' for more information."
|
||||
exit 1
|
||||
echo "[!] Unable to auto-detect wifi adapter. Please use the '-w' argument to pass in a wifi adapter."
|
||||
echo "See '$0 -h' for more information."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SUPPORTS_AP=$(nmcli -f wifi-properties device show ${WIFI_ADAPTER} | grep WIFI-PROPERTIES.AP | awk -F ' ' '{print $2}')
|
||||
|
||||
# We don't want to hard stop here because localization could lead to false positives, but warn if AP mode does not appear supported.
|
||||
if [ "${SUPPORTS_AP}" != "yes" ]; then
|
||||
echo "[!] WARNING: Selected wifi AP support: ${SUPPORTS_AP}"
|
||||
echo "AP support is manditory for tuya-cloudcutter to work. If this is blank or 'no' your adapter doesn't support this feature."
|
||||
read -n 1 -s -r -p "Press any key to continue, or CTRL+C to exit"
|
||||
echo "[!] WARNING: Selected wifi AP support: ${SUPPORTS_AP}"
|
||||
echo "AP support is manditory for tuya-cloudcutter to work. If this is blank or 'no' your adapter doesn't support this feature."
|
||||
read -n 1 -s -r -p "Press any key to continue, or CTRL+C to exit"
|
||||
fi
|
||||
|
||||
function run_helper_script () {
|
||||
function run_helper_script() {
|
||||
if [ -f "scripts/${1}.sh" ]; then
|
||||
echo "Running helper script '${1}'"
|
||||
source "scripts/${1}.sh"
|
||||
fi
|
||||
}
|
||||
|
||||
reset_nm () {
|
||||
reset_nm() {
|
||||
|
||||
if [ -z ${RESETNM+x} ]; then
|
||||
return 0
|
||||
else
|
||||
echo "Wiping NetworkManager configs"
|
||||
rm -f /etc/NetworkManager/system-connections/*.nmconnection*
|
||||
service NetworkManager restart
|
||||
return 0
|
||||
fi
|
||||
if [ -z ${RESETNM+x} ]; then
|
||||
return 0
|
||||
else
|
||||
echo "Wiping NetworkManager configs"
|
||||
rm -f /etc/NetworkManager/system-connections/*.nmconnection*
|
||||
service NetworkManager restart
|
||||
return 0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
wifi_connect () {
|
||||
wifi_connect() {
|
||||
FIRST_RUN=true
|
||||
|
||||
for i in {1..5}
|
||||
do
|
||||
for i in {1..5}; do
|
||||
AP_MATCHED_NAME=""
|
||||
|
||||
# Turn on WiFi, and wait for SSID to show up
|
||||
reset_nm
|
||||
sleep 1
|
||||
|
||||
service NetworkManager start; nmcli device set ${WIFI_ADAPTER} managed yes # Make sure we turn on managed mode again in case we didn't recover it in the trap below
|
||||
service NetworkManager start
|
||||
nmcli device set ${WIFI_ADAPTER} managed yes # Make sure we turn on managed mode again in case we didn't recover it in the trap below
|
||||
nmcli radio wifi off
|
||||
sleep 1
|
||||
nmcli radio wifi on
|
||||
while [ "${AP_MATCHED_NAME}" == "" ]
|
||||
do
|
||||
while [ "${AP_MATCHED_NAME}" == "" ]; do
|
||||
if [ ${FIRST_RUN} == true ]; then
|
||||
echo "Scanning for open Tuya SmartLife AP"
|
||||
SCAN_MESSAGE="Scanning for open Tuya SmartLife AP"
|
||||
if [ "${OVERRIDE_SSID}" != "" ]; then
|
||||
SCAN_MESSAGE="${SCAN_MESSAGE} ${OVERRIDE_SSID}"
|
||||
fi
|
||||
echo ${SCAN_MESSAGE}
|
||||
FIRST_RUN=false
|
||||
else
|
||||
echo -n "."
|
||||
fi
|
||||
|
||||
|
||||
RESCAN_ARG="--rescan yes"
|
||||
if [ "${DISABLE_RESCAN}" == "true" ]; then
|
||||
RESCAN_ARG=""
|
||||
fi
|
||||
|
||||
# Search for an AP ending with - and 4 hexidecimal characters that has no security mode, unless we've already connected to one, in which case we look for that specific one
|
||||
SSID_REGEX="-[A-F0-9]{4}"
|
||||
if [ "${OVERRIDE_SSID}" != "" ]; then
|
||||
SSID_REGEX="${OVERRIDE_SSID}"
|
||||
else
|
||||
# Search for an AP ending with - and 4 hexidecimal characters that has no security mode, unless we've already connected to one, in which case we look for that specific one
|
||||
SSID_REGEX="-[A-F0-9]{4}"
|
||||
fi
|
||||
|
||||
if [ "${AP_CONNECTED_ENDING}" != "" ]; then
|
||||
SSID_REGEX="${AP_CONNECTED_ENDING}"
|
||||
fi
|
||||
@@ -109,7 +117,7 @@ wifi_connect () {
|
||||
return 0
|
||||
}
|
||||
|
||||
build_docker () {
|
||||
build_docker() {
|
||||
export NO_COLOR=1
|
||||
docker build --network=host -t cloudcutter .
|
||||
if [ ! $? -eq 0 ]; then
|
||||
@@ -118,7 +126,7 @@ build_docker () {
|
||||
fi
|
||||
}
|
||||
|
||||
run_in_docker () {
|
||||
run_in_docker() {
|
||||
docker rm cloudcutter >/dev/null 2>&1
|
||||
docker run --rm --name cloudcutter --network=host -ti --privileged -v "$(pwd):/work" cloudcutter "${@}"
|
||||
}
|
||||
|
||||
132
common_run.sh
132
common_run.sh
@@ -2,17 +2,17 @@
|
||||
|
||||
# Select the right device
|
||||
if [ "${PROFILE}" == "" ]; then
|
||||
if [ $METHOD_FLASH ]; then
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/profile.txt choose-profile -f
|
||||
else
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/profile.txt choose-profile
|
||||
fi
|
||||
if [ $METHOD_FLASH ]; then
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/profile.txt choose-profile -f
|
||||
else
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/profile.txt choose-profile
|
||||
fi
|
||||
else
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/profile.txt write-profile $PROFILE
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/profile.txt write-profile $PROFILE
|
||||
fi
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Failed to choose a profile, please run this script again"
|
||||
exit 1
|
||||
echo "Failed to choose a profile, please run this script again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROFILE=$(cat profile.txt)
|
||||
@@ -20,13 +20,13 @@ rm -f profile.txt
|
||||
LOCAL_PROFILE=$(echo "${PROFILE}" | sed 's/\/work\///g')
|
||||
SLUGS=($(cat ${LOCAL_PROFILE} | grep -oP '(?<="slug": ")[^"]*'))
|
||||
if ! [ -z "${SLUGS}" ]; then
|
||||
DEVICESLUG="${SLUGS[0]}"
|
||||
if [ "${#SLUGS[@]}" -eq 1 ]; then
|
||||
PROFILES_GREP=($(cat ${LOCAL_PROFILE} | grep -A1 '"profiles": \[' | tr -d "\t" | tr -d "\"" | tr -d " " | tr -d "["))
|
||||
PROFILESLUG="${PROFILES_GREP[1]}"
|
||||
else
|
||||
PROFILESLUG="${SLUGS[1]}"
|
||||
fi
|
||||
DEVICESLUG="${SLUGS[0]}"
|
||||
if [ "${#SLUGS[@]}" -eq 1 ]; then
|
||||
PROFILES_GREP=($(cat ${LOCAL_PROFILE} | grep -A1 '"profiles": \[' | tr -d "\t" | tr -d "\"" | tr -d " " | tr -d "["))
|
||||
PROFILESLUG="${PROFILES_GREP[1]}"
|
||||
else
|
||||
PROFILESLUG="${SLUGS[1]}"
|
||||
fi
|
||||
fi
|
||||
CHIP=$(cat "${LOCAL_PROFILE}" | grep -o '"chip": "[^"]*' | grep -o '[^"]*$')
|
||||
|
||||
@@ -34,64 +34,64 @@ run_helper_script "pre-safety-checks"
|
||||
source safety_checks.sh
|
||||
|
||||
if [ $METHOD_FLASH ]; then
|
||||
# Select the right firmware
|
||||
if [ "${FIRMWARE}" == "" ]; then
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/firmware.txt choose-firmware -c "${CHIP}"
|
||||
else
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/firmware.txt validate-firmware-file "${FIRMWARE}" -c "${CHIP}"
|
||||
fi
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
FIRMWARE=$(cat firmware.txt)
|
||||
rm -f firmware.txt
|
||||
# Select the right firmware
|
||||
if [ "${FIRMWARE}" == "" ]; then
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/firmware.txt choose-firmware -c "${CHIP}"
|
||||
else
|
||||
run_in_docker pipenv run python3 get_input.py -w /work -o /work/firmware.txt validate-firmware-file "${FIRMWARE}" -c "${CHIP}"
|
||||
fi
|
||||
if [ ! $? -eq 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
FIRMWARE=$(cat firmware.txt)
|
||||
rm -f firmware.txt
|
||||
fi
|
||||
|
||||
echo "Selected Device Slug: ${DEVICESLUG}"
|
||||
echo "Selected Profile: ${PROFILESLUG}"
|
||||
if ! [ -z "${FIRMWARE}" ]; then
|
||||
echo "Selected Firmware: ${FIRMWARE}"
|
||||
echo "Selected Firmware: ${FIRMWARE}"
|
||||
fi
|
||||
|
||||
if ! [ -z "${AUTHKEY}" ] && ! [ -z "${UUID}" ] && ! [ -z "${PSKKEY}" ]; then
|
||||
echo "Using AuthKey ${AUTHKEY} , UUID ${UUID} , and PSKKey ${PSKKEY}"
|
||||
if ! [ -z "${DEVICEID}" ] && ! [ -z "${LOCALKEY}" ]; then
|
||||
echo "Using DeviceId ${DEVICEID} and LocalKey ${LOCALKEY}"
|
||||
fi
|
||||
echo "Writing deviceconfig file..."
|
||||
OUTPUT=$(run_in_docker pipenv run python3 -m cloudcutter write_deviceconfig "${PROFILE}" "${VERBOSE_OUTPUT}" --deviceid "${DEVICEID}" --localkey "${LOCALKEY}" --authkey "${AUTHKEY}" --uuid "${UUID}" --pskkey "${PSKKEY}")
|
||||
echo "Using AuthKey ${AUTHKEY} , UUID ${UUID} , and PSKKey ${PSKKEY}"
|
||||
if ! [ -z "${DEVICEID}" ] && ! [ -z "${LOCALKEY}" ]; then
|
||||
echo "Using DeviceId ${DEVICEID} and LocalKey ${LOCALKEY}"
|
||||
fi
|
||||
echo "Writing deviceconfig file..."
|
||||
OUTPUT=$(run_in_docker pipenv run python3 -m cloudcutter write_deviceconfig "${PROFILE}" "${VERBOSE_OUTPUT}" --deviceid "${DEVICEID}" --localkey "${LOCALKEY}" --authkey "${AUTHKEY}" --uuid "${UUID}" --pskkey "${PSKKEY}")
|
||||
else
|
||||
# Connect to Tuya device's WiFi
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Place your device in AP (slow blink) mode. This can usually be accomplished by either:"
|
||||
echo "Power cycling off/on - 3 times and wait for the device to fast-blink, then repeat 3 more times. Some devices need 4 or 5 times on each side of the pause"
|
||||
echo "Long press the power/reset button on the device until it starts fast-blinking, then releasing, and then holding the power/reset button again until the device starts slow-blinking."
|
||||
echo "See https://support.tuya.com/en/help/_detail/K9hut3w10nby8 for more information."
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
run_helper_script "pre-wifi-exploit"
|
||||
wifi_connect
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Failed to connect, please run this script again"
|
||||
exit 1
|
||||
fi
|
||||
# Connect to Tuya device's WiFi
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Place your device in AP (slow blink) mode. This can usually be accomplished by either:"
|
||||
echo "Power cycling off/on - 3 times and wait for the device to fast-blink, then repeat 3 more times. Some devices need 4 or 5 times on each side of the pause"
|
||||
echo "Long press the power/reset button on the device until it starts fast-blinking, then releasing, and then holding the power/reset button again until the device starts slow-blinking."
|
||||
echo "See https://support.tuya.com/en/help/_detail/K9hut3w10nby8 for more information."
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
run_helper_script "pre-wifi-exploit"
|
||||
wifi_connect
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Failed to connect, please run this script again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Exploit chain
|
||||
echo "Waiting 1 sec to allow device to set itself up..."
|
||||
sleep 1
|
||||
echo "Running initial exploit toolchain..."
|
||||
if ! [ -z "${DEVICEID}" ] && ! [ -z "${LOCALKEY}" ]; then
|
||||
echo "Using DeviceId ${DEVICEID} and LocalKey ${LOCALKEY}"
|
||||
fi
|
||||
OUTPUT=$(run_in_docker pipenv run python3 -m cloudcutter exploit_device "${PROFILE}" "${VERBOSE_OUTPUT}" --deviceid "${DEVICEID}" --localkey "${LOCALKEY}")
|
||||
# Exploit chain
|
||||
echo "Waiting 1 sec to allow device to set itself up..."
|
||||
sleep 1
|
||||
echo "Running initial exploit toolchain..."
|
||||
if ! [ -z "${DEVICEID}" ] && ! [ -z "${LOCALKEY}" ]; then
|
||||
echo "Using DeviceId ${DEVICEID} and LocalKey ${LOCALKEY}"
|
||||
fi
|
||||
OUTPUT=$(run_in_docker pipenv run python3 -m cloudcutter exploit_device "${PROFILE}" "${VERBOSE_OUTPUT}" --deviceid "${DEVICEID}" --localkey "${LOCALKEY}")
|
||||
fi
|
||||
|
||||
RESULT=$?
|
||||
echo "${OUTPUT}"
|
||||
if [ ! $RESULT -eq 0 ]; then
|
||||
echo "Oh no, something went wrong with running the exploit! Try again I guess..."
|
||||
exit 1
|
||||
echo "Oh no, something went wrong with running the exploit! Try again I guess..."
|
||||
exit 1
|
||||
fi
|
||||
CONFIG_DIR=$(echo "${OUTPUT}" | grep "output=" | awk -F '=' '{print $2}' | sed -e 's/\r//')
|
||||
echo "Saved device config in ${CONFIG_DIR}"
|
||||
@@ -109,17 +109,17 @@ sleep 5
|
||||
run_helper_script "pre-wifi-config"
|
||||
wifi_connect
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Failed to connect, please run this script again"
|
||||
exit 1
|
||||
echo "Failed to connect, please run this script again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If the AP prefix did not change, the exploit was not successful
|
||||
# End the process now to end further confusion
|
||||
if [[ $AP_MATCHED_NAME != A-* ]] && [ -z "${AUTHKEY}" ]; then
|
||||
echo "================================================================================"
|
||||
echo "[!] The profile you selected did not result in a successful exploit."
|
||||
echo "================================================================================"
|
||||
exit 1
|
||||
echo "================================================================================"
|
||||
echo "[!] The profile you selected did not result in a successful exploit."
|
||||
echo "================================================================================"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add a minor delay to stabilize after connection
|
||||
@@ -128,7 +128,7 @@ OUTPUT=$(run_in_docker pipenv run python3 -m cloudcutter configure_wifi "cloudcu
|
||||
RESULT=$?
|
||||
echo "${OUTPUT}"
|
||||
if [ ! $RESULT -eq 0 ]; then
|
||||
echo "Oh no, something went wrong with making the device connect to our hostapd AP! Try again I guess..."
|
||||
exit 1
|
||||
echo "Oh no, something went wrong with making the device connect to our hostapd AP! Try again I guess..."
|
||||
exit 1
|
||||
fi
|
||||
echo "Device is connecting to 'cloudcutterflash' access point. Passphrase for the AP is 'abcdabcd' (without ')"
|
||||
|
||||
112
safety_checks.sh
112
safety_checks.sh
@@ -1,67 +1,67 @@
|
||||
#!/bin/bash
|
||||
|
||||
check_port () {
|
||||
protocol="$1"
|
||||
port="$2"
|
||||
reason="$3"
|
||||
echo -n "Checking ${protocol^^} port $port... "
|
||||
process_pid=$(sudo ss -lnp -A "$protocol" "sport = :$port" | grep -Po "(?<=pid=)(\d+)" | head -n1)
|
||||
if [ -n "$process_pid" ]; then
|
||||
process_name=$(ps -p "$process_pid" -o comm=)
|
||||
echo "Occupied by $process_name with PID $process_pid."
|
||||
echo "Port $port is needed to $reason"
|
||||
read -p "Do you wish to terminate $process_name? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ "$REPLY" =~ ^[Ss]$ ]]; then
|
||||
echo "Skipping..."
|
||||
return
|
||||
fi
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Aborting due to occupied port"
|
||||
exit 1
|
||||
else
|
||||
service=$(ps -p "$process_pid" -o unit= | grep .service | grep -Ev ^user)
|
||||
if [ -n "$service" ]; then
|
||||
echo "Attempting to stop $service"
|
||||
sudo systemctl stop "$service"
|
||||
else
|
||||
echo "Attempting to terminate $process_name"
|
||||
sudo kill "$process_pid"
|
||||
if ! sudo timeout 10 tail --pid="$process_pid" -f /dev/null; then
|
||||
echo "$process_name is still running after 10 seconds, sending SIGKILL"
|
||||
sudo kill -9 "$process_pid"
|
||||
sudo tail --pid="$process_pid" -f /dev/null
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
fi
|
||||
else
|
||||
echo "Available."
|
||||
fi
|
||||
protocol="$1"
|
||||
port="$2"
|
||||
reason="$3"
|
||||
echo -n "Checking ${protocol^^} port $port... "
|
||||
process_pid=$(sudo ss -lnp -A "$protocol" "sport = :$port" | grep -Po "(?<=pid=)(\d+)" | head -n1)
|
||||
if [ -n "$process_pid" ]; then
|
||||
process_name=$(ps -p "$process_pid" -o comm=)
|
||||
echo "Occupied by $process_name with PID $process_pid."
|
||||
echo "Port $port is needed to $reason"
|
||||
read -p "Do you wish to terminate $process_name? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ "$REPLY" =~ ^[Ss]$ ]]; then
|
||||
echo "Skipping..."
|
||||
return
|
||||
fi
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Aborting due to occupied port"
|
||||
exit 1
|
||||
else
|
||||
service=$(ps -p "$process_pid" -o unit= | grep .service | grep -Ev ^user)
|
||||
if [ -n "$service" ]; then
|
||||
echo "Attempting to stop $service"
|
||||
sudo systemctl stop "$service"
|
||||
else
|
||||
echo "Attempting to terminate $process_name"
|
||||
sudo kill "$process_pid"
|
||||
if ! sudo timeout 10 tail --pid="$process_pid" -f /dev/null; then
|
||||
echo "$process_name is still running after 10 seconds, sending SIGKILL"
|
||||
sudo kill -9 "$process_pid"
|
||||
sudo tail --pid="$process_pid" -f /dev/null
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
fi
|
||||
else
|
||||
echo "Available."
|
||||
fi
|
||||
}
|
||||
|
||||
check_firewall () {
|
||||
if sudo systemctl stop firewalld.service &>/dev/null; then
|
||||
echo "Attempting to stop firewalld.service"
|
||||
echo "When done, enable with: ${bold}sudo systemctl start firewalld.service${normal}"
|
||||
fi
|
||||
if command -v ufw >/dev/null && sudo ufw status | grep -qw active; then
|
||||
sudo ufw disable
|
||||
echo "When done, enable with: ${bold}sudo ufw enable${normal}"
|
||||
fi
|
||||
if sudo systemctl stop firewalld.service &>/dev/null; then
|
||||
echo "Attempting to stop firewalld.service"
|
||||
echo "When done, enable with: ${bold}sudo systemctl start firewalld.service${normal}"
|
||||
fi
|
||||
if command -v ufw >/dev/null && sudo ufw status | grep -qw active; then
|
||||
sudo ufw disable
|
||||
echo "When done, enable with: ${bold}sudo ufw enable${normal}"
|
||||
fi
|
||||
}
|
||||
|
||||
check_blacklist () {
|
||||
if [ -e /etc/modprobe.d/blacklist-rtl8192cu.conf ]; then
|
||||
echo "Detected /etc/modprobe.d/blacklist-rtl8192cu.conf"
|
||||
echo "This has been known to cause kernel panic in hostapd"
|
||||
echo "See https://github.com/ct-Open-Source/tuya-convert/issues/373"
|
||||
read -p "Do you wish to remove this file? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
sudo rm /etc/modprobe.d/blacklist-rtl8192cu.conf
|
||||
fi
|
||||
fi
|
||||
if [ -e /etc/modprobe.d/blacklist-rtl8192cu.conf ]; then
|
||||
echo "Detected /etc/modprobe.d/blacklist-rtl8192cu.conf"
|
||||
echo "This has been known to cause kernel panic in hostapd"
|
||||
echo "See https://github.com/ct-Open-Source/tuya-convert/issues/373"
|
||||
read -p "Do you wish to remove this file? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
sudo rm /etc/modprobe.d/blacklist-rtl8192cu.conf
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
echo ""
|
||||
@@ -77,4 +77,4 @@ check_port tcp 8886 "run MQTTS"
|
||||
check_firewall
|
||||
check_blacklist
|
||||
echo "Safety checks complete."
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
@@ -12,52 +12,54 @@ function getopts-extra () {
|
||||
done
|
||||
}
|
||||
|
||||
while getopts "hrntvw:p:f:d:l:s::a:k:u:" flag; do
|
||||
case "$flag" in
|
||||
r) RESETNM="true";;
|
||||
n) DISABLE_RESCAN="true";;
|
||||
v) VERBOSE_OUTPUT="true";;
|
||||
w) WIFI_ADAPTER=${OPTARG};;
|
||||
p) PROFILE=${OPTARG};;
|
||||
f) FIRMWARE=${OPTARG}
|
||||
while getopts "hrntvw:p:f:d:l:s::a:k:u:o:" flag; do
|
||||
case "$flag" in
|
||||
r) RESETNM="true";;
|
||||
n) DISABLE_RESCAN="true";;
|
||||
v) VERBOSE_OUTPUT="true";;
|
||||
w) WIFI_ADAPTER=${OPTARG};;
|
||||
p) PROFILE=${OPTARG};;
|
||||
f) FIRMWARE=${OPTARG}
|
||||
METHOD_FLASH="true"
|
||||
;;
|
||||
t) FLASH_TIMEOUT=${OPTARG};;
|
||||
d) DEVICEID=${OPTARG};;
|
||||
l) LOCALKEY=${OPTARG};;
|
||||
a) AUTHKEY=${OPTARG};;
|
||||
k) PSKKEY=${OPTARG};;
|
||||
u) UUID=${OPTARG};;
|
||||
s) getopts-extra "$@"
|
||||
;;
|
||||
t) FLASH_TIMEOUT=${OPTARG};;
|
||||
d) DEVICEID=${OPTARG};;
|
||||
l) LOCALKEY=${OPTARG};;
|
||||
a) AUTHKEY=${OPTARG};;
|
||||
k) PSKKEY=${OPTARG};;
|
||||
u) UUID=${OPTARG};;
|
||||
o) OVERRIDE_SSID=${OPTARG};;
|
||||
s) getopts-extra "$@"
|
||||
METHOD_DETACH="true"
|
||||
HAVE_SSID="true"
|
||||
SSID_ARGS=( "${OPTARG[@]}" )
|
||||
SSID=${SSID_ARGS[0]}
|
||||
SSID_PASS=${SSID_ARGS[1]}
|
||||
;;
|
||||
h)
|
||||
echo "usage: $0 [OPTION]..."
|
||||
HAVE_SSID="true"
|
||||
SSID_ARGS=( "${OPTARG[@]}" )
|
||||
SSID=${SSID_ARGS[0]}
|
||||
SSID_PASS=${SSID_ARGS[1]}
|
||||
;;
|
||||
h)
|
||||
echo "usage: $0 [OPTION]..."
|
||||
echo " -h Show this message"
|
||||
echo " -r Reset NetworkManager"
|
||||
echo " -n No Rescan (for older versions of nmcli that don't support it)"
|
||||
echo " -v Verbose log output"
|
||||
echo " -n No Rescan (for older versions of nmcli that don't support it)"
|
||||
echo " -o TEXT Override specific device AP name to connect to"
|
||||
echo " -v Verbose log output"
|
||||
echo " -w TEXT WiFi adapter name (optional, auto-selected if not supplied)"
|
||||
echo " -p TEXT Device profile name, AKA Device Slug (optional)"
|
||||
echo " -a TEXT AuthKey of the device (optional, requires UUID and PSKKey accompanied with it)"
|
||||
echo " -k TEXT PSKKey of the device (optinal, requires AuthKey and UUID accompanied with it)"
|
||||
echo " -u TEXT UUID of the device (optional, requires AuthKey and PSKKey accompanied with it)"
|
||||
echo ""
|
||||
echo " -a TEXT AuthKey of the device (optional, requires UUID and PSKKey accompanied with it)"
|
||||
echo " -k TEXT PSKKey of the device (optinal, requires AuthKey and UUID accompanied with it)"
|
||||
echo " -u TEXT UUID of the device (optional, requires AuthKey and PSKKey accompanied with it)"
|
||||
echo ""
|
||||
echo "==== Detaching Only: ===="
|
||||
echo " -s SSID PASSWORD Wifi SSID and Password to use for detaching. Use quotes if either value contains spaces. Certain special characters may need to be escaped with '\\'"
|
||||
echo " -d TEXT New device id (optional)"
|
||||
echo " -l TEXT New local key (optional)"
|
||||
echo ""
|
||||
echo " -l TEXT New local key (optional)"
|
||||
echo ""
|
||||
echo "==== 3rd Party Firmware Flashing Only: ===="
|
||||
echo " -f TEXT Firmware file name without path as it exists in /custom-firmware/ (optional)"
|
||||
echo " -t SECONDS Timeout in seconds for how long to wait before exiting after receiving firmware update information. Default is 15"
|
||||
|
||||
exit 0
|
||||
esac
|
||||
echo " -t SECONDS Timeout in seconds for how long to wait before exiting after receiving firmware update information. Default is 15"
|
||||
|
||||
exit 0
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $METHOD_DETACH ] && [ $METHOD_FLASH ]; then
|
||||
@@ -75,20 +77,20 @@ if [ ! $METHOD_DETACH ] && [ ! $METHOD_FLASH ]; then
|
||||
select method in "Detach from the cloud and run Tuya firmware locally" "Flash 3rd Party Firmware"; do
|
||||
case $REPLY in
|
||||
1) METHOD_DETACH="true"
|
||||
break
|
||||
;;
|
||||
break
|
||||
;;
|
||||
2) METHOD_FLASH="true"
|
||||
break
|
||||
;;
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $METHOD_DETACH ] && [ ! $HAVE_SSID ]; then
|
||||
echo "Detaching requires an SSID and Password, please enter each at the following prompt"
|
||||
echo "In order to provide secure logging, the values you type for your password will not show on screen"
|
||||
echo "If you make a mistake, you can run the detach process again"
|
||||
echo "You can also pass credentials via the -s command line option, see '${0} -h' for more information'"
|
||||
echo "In order to provide secure logging, the values you type for your password will not show on screen"
|
||||
echo "If you make a mistake, you can run the detach process again"
|
||||
echo "You can also pass credentials via the -s command line option, see '${0} -h' for more information'"
|
||||
read -p "Please enter your SSID: " SSID
|
||||
read -p "Please enter your Password: "$'\n' -s SSID_PASS
|
||||
fi
|
||||
@@ -98,55 +100,55 @@ echo "Loading options, please wait..."
|
||||
source common_run.sh
|
||||
|
||||
if [ $METHOD_DETACH ]; then
|
||||
# Cutting device from cloud, allowing local-tuya access still
|
||||
echo "Cutting device off from cloud..."
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Wait for up to 10-120 seconds for the device to connect to 'cloudcutterflash'. This script will then show the activation requests sent by the device, and tell you whether local activation was successful."
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
# Cutting device from cloud, allowing local-tuya access still
|
||||
echo "Cutting device off from cloud..."
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Wait for up to 10-120 seconds for the device to connect to 'cloudcutterflash'. This script will then show the activation requests sent by the device, and tell you whether local activation was successful."
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
|
||||
nmcli device set ${WIFI_ADAPTER} managed no; service NetworkManager stop;
|
||||
trap "service NetworkManager start; nmcli device set ${WIFI_ADAPTER} managed yes" EXIT # Set WiFi adapter back to managed when the script exits
|
||||
INNER_SCRIPT=$(xargs -0 <<- EOF
|
||||
# This janky looking string substitution is because of double evaluation.
|
||||
# Once in the parent shell script, and once in this heredoc used as a shell script.
|
||||
# First evaluate the value from the parent shell script while escaping ' chars
|
||||
# with this janky substitutions so that it doesn't break this heredoc script.
|
||||
SSID='${SSID/\'/\'\"\'\"\'}'
|
||||
SSID_PASS='${SSID_PASS/\'/\'\"\'\"\'}'
|
||||
bash /src/setup_apmode.sh ${WIFI_ADAPTER} ${VERBOSE_OUTPUT}
|
||||
pipenv run python3 -m cloudcutter configure_local_device --ssid "\${SSID}" --password "\${SSID_PASS}" "${PROFILE}" "/work/device-profiles/schema" "${CONFIG_DIR}" ${FLASH_TIMEOUT} "${VERBOSE_OUTPUT}"
|
||||
EOF
|
||||
)
|
||||
run_in_docker bash -c "$INNER_SCRIPT"
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Oh no, something went wrong with detaching from the cloud! Try again I guess..."
|
||||
if [ ! $VERBOSE_OUTPUT ]; then
|
||||
echo "If you need to report an issue, please run with the -v flag and supply the full log of that attempt."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
nmcli device set ${WIFI_ADAPTER} managed no; service NetworkManager stop;
|
||||
trap "service NetworkManager start; nmcli device set ${WIFI_ADAPTER} managed yes" EXIT # Set WiFi adapter back to managed when the script exits
|
||||
INNER_SCRIPT=$(xargs -0 <<- EOF
|
||||
# This janky looking string substitution is because of double evaluation.
|
||||
# Once in the parent shell script, and once in this heredoc used as a shell script.
|
||||
# First evaluate the value from the parent shell script while escaping ' chars
|
||||
# with this janky substitutions so that it doesn't break this heredoc script.
|
||||
SSID='${SSID/\'/\'\"\'\"\'}'
|
||||
SSID_PASS='${SSID_PASS/\'/\'\"\'\"\'}'
|
||||
bash /src/setup_apmode.sh ${WIFI_ADAPTER} ${VERBOSE_OUTPUT}
|
||||
pipenv run python3 -m cloudcutter configure_local_device --ssid "\${SSID}" --password "\${SSID_PASS}" "${PROFILE}" "/work/device-profiles/schema" "${CONFIG_DIR}" ${FLASH_TIMEOUT} "${VERBOSE_OUTPUT}"
|
||||
EOF
|
||||
)
|
||||
run_in_docker bash -c "$INNER_SCRIPT"
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Oh no, something went wrong with detaching from the cloud! Try again I guess..."
|
||||
if [ ! $VERBOSE_OUTPUT ]; then
|
||||
echo "If you need to report an issue, please run with the -v flag and supply the full log of that attempt."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $METHOD_FLASH ]; then
|
||||
# Flash custom firmware to device
|
||||
echo "Flashing custom firmware..."
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Wait for up to 10-120 seconds for the device to connect to 'cloudcutterflash'. This script will then show the firmware upgrade requests sent by the device."
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
nmcli device set "${WIFI_ADAPTER}" managed no
|
||||
trap "nmcli device set ${WIFI_ADAPTER} managed yes" EXIT # Set WiFi adapter back to managed when the script exits
|
||||
run_in_docker bash -c "bash /src/setup_apmode.sh ${WIFI_ADAPTER} ${VERBOSE_OUTPUT} && pipenv run python3 -m cloudcutter update_firmware \"${PROFILE}\" \"/work/device-profiles/schema\" \"${CONFIG_DIR}\" \"/work/custom-firmware/\" \"${FIRMWARE}\" \"${FLASH_TIMEOUT}\" \"${VERBOSE_OUTPUT}\""
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Oh no, something went wrong with updating firmware! Try again I guess..."
|
||||
if [ ! $VERBOSE_OUTPUT ]; then
|
||||
echo "If you need to report an issue, please run with the -v flag and supply the full log of that attempt."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
# Flash custom firmware to device
|
||||
echo "Flashing custom firmware..."
|
||||
echo ""
|
||||
echo "================================================================================"
|
||||
echo "Wait for up to 10-120 seconds for the device to connect to 'cloudcutterflash'. This script will then show the firmware upgrade requests sent by the device."
|
||||
echo "================================================================================"
|
||||
echo ""
|
||||
nmcli device set "${WIFI_ADAPTER}" managed no
|
||||
trap "nmcli device set ${WIFI_ADAPTER} managed yes" EXIT # Set WiFi adapter back to managed when the script exits
|
||||
run_in_docker bash -c "bash /src/setup_apmode.sh ${WIFI_ADAPTER} ${VERBOSE_OUTPUT} && pipenv run python3 -m cloudcutter update_firmware \"${PROFILE}\" \"/work/device-profiles/schema\" \"${CONFIG_DIR}\" \"/work/custom-firmware/\" \"${FIRMWARE}\" \"${FLASH_TIMEOUT}\" \"${VERBOSE_OUTPUT}\""
|
||||
if [ ! $? -eq 0 ]; then
|
||||
echo "Oh no, something went wrong with updating firmware! Try again I guess..."
|
||||
if [ ! $VERBOSE_OUTPUT ]; then
|
||||
echo "If you need to report an issue, please run with the -v flag and supply the full log of that attempt."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
run_helper_script "post-flash"
|
||||
Reference in New Issue
Block a user