::call slot [system recovery fastboot auto] set [a b cur cur_oth]
::          [system recovery fastboot auto] chk

@ECHO OFF
set var1=%1& set var2=%2& set var3=%3& set var4=%4& set var5=%5& set var6=%6& set var7=%7& set var8=%8& set var9=%9
SETLOCAL
set logger=slot.bat
set devmode=%var1%& set func=%var2%& set target=%var3%
call log %logger% I 接收变量:devmode:%devmode%.func:%func%.target:%target%
:START
if "%devmode%"=="system" goto CHK-ADB
if "%devmode%"=="recovery" goto CHK-ADB
if "%devmode%"=="fastboot" goto CHK-FASTBOOT
call log %logger% I 检查设备所在模式
call chkdev all
if not "%chkdev__all__mode%"=="system" (if not "%chkdev__all__mode%"=="recovery" (if not "%chkdev__all__mode%"=="fastboot" ECHOC {%c_e%}模式错误, 请进入系统, Recovery或Fastboot模式. {%c_h%}按任意键重试...{%c_i%}{\n}& pause>nul & ECHO.重试...))
set devmode=%chkdev__all__mode%
goto START


:CHK-ADB
if "%devmode%"=="system" echo.su>tmp\cmd.txt& echo.cat /proc/cmdline>>tmp\cmd.txt
if "%devmode%"=="recovery" echo.cat /proc/cmdline>tmp\cmd.txt
call log %logger% I 开始ADB读取/proc/cmdline
adb.exe shell < tmp\cmd.txt 1>tmp\output.txt 2>&1 || ECHOC {%c_e%}ADB读取/proc/cmdline失败. {%c_h%}按任意键重试...{%c_i%}{\n}&& type tmp\output.txt>>%logfile%&& call log %logger% E ADB读取/proc/cmdline失败&& pause>nul && ECHO.重试... && goto CHK-ADB
type tmp\output.txt>>%logfile%
set slot_cur=
find "androidboot.slot_suffix=_a" "tmp\output.txt" 1>nul 2>nul && set slot_cur=a
find "androidboot.slot_suffix=_b" "tmp\output.txt" 1>nul 2>nul && set slot_cur=b
find "androidboot.slot_suffix=a" "tmp\output.txt" 1>nul 2>nul && set slot_cur=a
find "androidboot.slot_suffix=b" "tmp\output.txt" 1>nul 2>nul && set slot_cur=b
if "%slot_cur%"=="" ECHOC {%c_e%}查找槽位信息失败. {%c_h%}按任意键重试...{%c_i%}{\n}& call log %logger% E 查找槽位信息失败& pause>nul & ECHO.重试... & goto CHK-ADB
if "%slot_cur%"=="a" set slot_cur_oth=b
if "%slot_cur%"=="b" set slot_cur_oth=a
call log %logger% I ADB读取到槽位信息:slot_cur:%slot_cur%.slot_cur_oth:%slot_cur_oth%
::读取完成
if not "%func%"=="set" ENDLOCAL & set slot__cur=%slot_cur%& set slot__cur_oth=%slot_cur_oth%& goto :eof
goto SET-ADB
:SET-ADB
if "%target%"=="cur" set target=%slot_cur%
if "%target%"=="cur_oth" set target=%slot_cur_oth%
if "%target%"=="a" set var=0
if "%target%"=="b" set var=1
call framwork adbpre bootctl
if "%devmode%"=="system" echo.su>tmp\cmd.txt& echo.bootctl set-active-boot-slot %var% >>tmp\cmd.txt
if "%devmode%"=="recovery" echo.bootctl set-active-boot-slot %var% >tmp\cmd.txt
call log %logger% I 开始ADB设置槽位为%target%(%var%)
adb.exe shell < tmp\cmd.txt 1>>%logfile% 2>&1 || ECHOC {%c_e%}ADB设置槽位为%target%(%var%)失败. {%c_h%}按任意键重试...{%c_i%}{\n}&& call log %logger% E ADB设置槽位为%target%(%var%)失败&& pause>nul && ECHO.重试... && goto SET-ADB
call log %logger% I ADB成功设置槽位为%target%(%var%)
ECHO.成功设置槽位为%target%
ENDLOCAL
goto :eof


:CHK-FASTBOOT
call log %logger% I 开始Fastboot读取槽位信息
fastboot.exe getvar current-slot 1>tmp\output.txt 2>&1 || ECHOC {%c_e%}Fastboot读取槽位信息失败. {%c_h%}按任意键重试...{%c_i%}{\n}&& type tmp\output.txt>>%logfile%&& call log %logger% E Fastboot读取槽位信息失败&& pause>nul && ECHO.重试... && goto CHK-FASTBOOT
type tmp\output.txt>>%logfile%
set slot_cur=
for /f "tokens=2 delims=_ " %%i in ('type tmp\output.txt ^| find "slot"') do set slot_cur=%%i
if "%slot_cur%"=="" ECHOC {%c_e%}查找槽位信息失败. {%c_h%}按任意键重试...{%c_i%}{\n}& call log %logger% E 查找槽位信息失败& pause>nul & ECHO.重试... & goto CHK-FASTBOOT
if "%slot_cur%"=="a" set slot_cur_oth=b
if "%slot_cur%"=="b" set slot_cur_oth=a
::读取能否启动信息
fastboot.exe getvar all 1>tmp\output.txt 2>&1 || ECHOC {%c_e%}Fastboot读取槽位信息失败. {%c_h%}按任意键重试...{%c_i%}{\n}&& type tmp\output.txt>>%logfile%&& call log %logger% E Fastboot读取槽位信息失败&& pause>nul && ECHO.重试... && goto CHK-FASTBOOT
type tmp\output.txt>>%logfile%
set slot_a_unbootable=
for /f "tokens=2 delims= " %%i in ('type tmp\output.txt ^| find "slot-unbootable:a"') do set slot_a_unbootable=%%i
if "%slot_a_unbootable%"=="" ECHOC {%c_e%}查找槽位信息失败. {%c_h%}按任意键重试...{%c_i%}{\n}& call log %logger% E 查找槽位信息失败& pause>nul & ECHO.重试... & goto CHK-FASTBOOT
set slot_b_unbootable=
for /f "tokens=2 delims= " %%i in ('type tmp\output.txt ^| find "slot-unbootable:b"') do set slot_b_unbootable=%%i
if "%slot_b_unbootable%"=="" ECHOC {%c_e%}查找槽位信息失败. {%c_h%}按任意键重试...{%c_i%}{\n}& call log %logger% E 查找槽位信息失败& pause>nul & ECHO.重试... & goto CHK-FASTBOOT
if "%slot_cur%"=="a" set slot_cur_unbootable=%slot_a_unbootable%& set slot_cur_oth_unbootable=%slot_b_unbootable%
if "%slot_cur%"=="b" set slot_cur_unbootable=%slot_b_unbootable%& set slot_cur_oth_unbootable=%slot_a_unbootable%
call log %logger% I Fastboot读取到槽位信息:slot_cur:%slot_cur%.slot_cur_oth:%slot_cur_oth%.slot_cur_unbootable:%slot_cur_unbootable%.slot_cur_oth_unbootable:%slot_cur_oth_unbootable%.slot_a_unbootable:%slot_a_unbootable%.slot_b_unbootable:%slot_b_unbootable%.
::读取完成
if not "%func%"=="set" ENDLOCAL & set slot__cur=%slot_cur%& set slot__cur_oth=%slot_cur_oth%& set slot__cur_unbootable=%slot_cur_unbootable%& set slot__cur_oth_unbootable=%slot_cur_oth_unbootable%& set slot__a_unbootable=%slot_a_unbootable%& set slot__b_unbootable=%slot_b_unbootable%& goto :eof
goto SET-FASTBOOT
:SET-FASTBOOT
if "%target%"=="cur" set target=%slot_cur%
if "%target%"=="cur_oth" set target=%slot_cur_oth%
if "%target%"=="a" (if "%slot_a_unbootable%"=="yes" ECHOC {%c_w%}警告: 目标槽位%target%被标记为不可启动, 切换后可能出现无法启动等问题. {%c_h%}按任意键继续...{%c_i%}{\n}& call log %logger% W 目标槽位%target%被标记为不可启动& pause>nul)
if "%target%"=="b" (if "%slot_b_unbootable%"=="yes" ECHOC {%c_w%}警告: 目标槽位%target%被标记为不可启动, 切换后可能出现无法启动等问题. {%c_h%}按任意键继续...{%c_i%}{\n}& call log %logger% W 目标槽位%target%被标记为不可启动& pause>nul)
call log %logger% I 开始Fastboot设置槽位为%target%
fastboot.exe set_active %target% 1>>%logfile% 2>&1 || ECHOC {%c_e%}Fastboot设置槽位为%target%失败. {%c_h%}按任意键重试...{%c_i%}{\n}&& call log %logger% E Fastboot设置槽位为%target%失败&& pause>nul && ECHO.重试... && goto SET-FASTBOOT
call log %logger% I Fastboot成功设置槽位为%target%
ECHO.成功设置槽位为%target%
ENDLOCAL
goto :eof





:SLOT-START
if "%1"=="" ECHOC {0C}slot.bat缺少参数1！{%c_i%}{\N}& pause>nul & EXIT
if "%2"=="" ECHOC {0C}slot.bat缺少参数2！{%c_i%}{\N}& pause>nul & EXIT
if "%1"=="auto" call chk CNCT all 1>nul
if "%1"=="auto" (
	if "%chk_cnct_devst%"=="recovery" goto SLOT-ADB
	if "%chk_cnct_devst%"=="fastboot" goto SLOT-FB
	ECHOC {0C}模式错误！不支持在%chk_cnct_devst%模式切换槽位。按任意键重试...{%c_i%}{\n}& pause>nul & ECHO.重试... & goto SLOT-START)
goto SLOT-%1

:SLOT-ADB
adb push tools\bootctl /tmp/bootctl 1>nul || ECHOC {0C}推送bootctl失败！按任意键重试...{%c_i%}{\n}&& pause>nul && ECHO.重试... && goto SLOT-ADB
echo.cd tmp>tmp\slot.txt
echo.chmod +x bootctl>>tmp\slot.txt
adb shell < tmp\slot.txt 1>nul || ECHOC {0C}授权bootctl失败！按任意键重试...{%c_i%}{\n}&& pause>nul && ECHO.重试... && goto SLOT-ADB
::读取当前槽位
:SLOT-ADB-1
adb shell cat /proc/cmdline 1>tmp\slot.txt || ECHOC {0C}读取cmdline失败！按任意键重试...{%c_i%}{\n}&& pause>nul && ECHO.重试... && goto SLOT-ADB-1
set slot_cur=unknown
find "androidboot.slot_suffix=_a" "tmp\slot.txt" 1>nul 2>nul && set slot_cur=a
find "androidboot.slot_suffix=_b" "tmp\slot.txt" 1>nul 2>nul && set slot_cur=b
find "androidboot.slot_suffix=a" "tmp\slot.txt" 1>nul 2>nul && set slot_cur=a
find "androidboot.slot_suffix=b" "tmp\slot.txt" 1>nul 2>nul && set slot_cur=b
if "%slot_cur%"=="unknown" start tmp\slot.txt & ECHOC {0C}查找当前槽位信息失败！按任意键重试...{%c_i%}{\n}& pause>nul & ECHO.重试... & goto SLOT-ADB-1
::读取另一槽位
if "%slot_cur%"=="a" set slot_cur_other=b
if "%slot_cur%"=="b" set slot_cur_other=a
::读取完成
if "%2"=="chk" goto :eof
if "%2"=="set" goto SLOT-ADB-SET
ECHOC {0C}输入参数不全！{%c_i%}{\n}& pause>nul & EXIT
:SLOT-ADB-SET
if "%3"=="a" set target=0
if "%3"=="b" set target=1
if "%3"=="cur" (
    if "%slot_cur%"=="a" set target=0
    if "%slot_cur%"=="b" set target=1)
if "%3"=="cur_other" (
    if "%slot_cur_other%"=="a" set target=0
    if "%slot_cur_other%"=="b" set target=1)
echo.cd tmp>tmp\slot.txt
echo.bootctl set-active-boot-slot %target%|findstr "bootctl" 1>>tmp\slot.txt
adb shell < tmp\slot.txt 1>nul || ECHOC {0C}切换槽位%3（%target%）出错！尝试Fastboot切换...{%c_i%}{\n}&& goto SLOT-ADB-SET-PLANB
if "%target%"=="0" ECHO.成功切换到槽位a。
if "%target%"=="1" ECHO.成功切换到槽位b。
goto :eof

:SLOT-ADB-SET-PLANB
if "%target%"=="0" set target=a
if "%target%"=="1" set target=b
call chk CNCT recovery
call reboot ADB BL chk
call slot fb set %target%
call reboot FB REC chk
goto :eof


:SLOT-FB
for /f "tokens=2 delims=_ " %%i in ('fastboot getvar current-slot 2^>^&1^| findstr "slot"') do set slot_cur=%%i
if "%slot_cur%"=="a" set slot_cur_other=b
if "%slot_cur%"=="b" set slot_cur_other=a
for /f "tokens=2 delims= " %%i in ('fastboot getvar slot-unbootable:%slot_cur% 2^>^&1^| findstr "slot"') do set slot_cur_unbootable_fb=%%i
for /f "tokens=2 delims= " %%i in ('fastboot getvar slot-unbootable:%slot_cur_other% 2^>^&1^| findstr "slot"') do set slot_cur_other_unbootable_fb=%%i
for /f "tokens=2 delims= " %%i in ('fastboot getvar slot-unbootable:a 2^>^&1^| findstr "slot"') do set slot_a_unbootable_fb=%%i
for /f "tokens=2 delims= " %%i in ('fastboot getvar slot-unbootable:b 2^>^&1^| findstr "slot"') do set slot_b_unbootable_fb=%%i
if "%2"=="chk" goto :eof
if "%2"=="set" goto SLOT-FB-SET
ECHOC {0C}输入参数不全！{%c_i%}{\n}& pause>nul & EXIT
:SLOT-FB-SET
if "%3"=="a" set target=a
if "%3"=="b" set target=b
if "%3"=="cur" (
    if "%slot_cur%"=="a" set target=a
    if "%slot_cur%"=="b" set target=b)
if "%3"=="cur_other" (
    if "%slot_cur_other%"=="a" set target=a
    if "%slot_cur_other%"=="b" set target=b)
if "%target%"=="a" (if "%slot_a_unbootable_fb%"=="yes" ECHOC {0C}警告：检查到目标槽位 %target% 被标记为不可启动状态。切换后可能出现无法启动等问题。如有疑问请QQ联系1330250642。按任意键继续...{%c_i%}{\n}& pause>nul)
if "%target%"=="b" (if "%slot_b_unbootable_fb%"=="yes" ECHOC {0C}警告：检查到目标槽位 %target% 被标记为不可启动状态。切换后可能出现无法启动等问题。如有疑问请QQ联系1330250642。按任意键继续...{%c_i%}{\n}& pause>nul)
fastboot set_active %target% 2>&1| find "OKAY" 1>nul 2>nul || ECHOC {0C}切换槽位%target%出错！按任意键重试...{%c_i%}{\n}&& pause>nul && ECHO.重试... && goto SLOT-FB-SET
::重启以避免某些问题
call reboot fb bl chk
ECHO.成功切换到槽位%target%。
goto :eof


