Add Fastboot/EDL reboot modes and SIM contact import/export
This commit is contained in:
@@ -30,5 +30,8 @@ permit nopass :wheel as root cmd rtcwake
|
||||
permit nopass :wheel as root cmd tee args -a /sys/power/wake_lock
|
||||
permit nopass :wheel as root cmd tee args -a /sys/power/wake_unlock
|
||||
permit nopass :wheel as root cmd tee args /sys/power/wakeup_count
|
||||
permit nopass :wheel as root cmd tee args /sys/module/leds_msm8905_torch/parameters/next_reboot_mode
|
||||
permit nopass :wheel as root cmd /usr/bin/sxmo_power.sh
|
||||
permit nopass :wheel as root cmd sxmo_power.sh
|
||||
permit nopass :wheel as root cmd rc-service args hexagonrpcd-adsp-sensorspd stop
|
||||
permit nopass :wheel as root cmd systemctl args stop hexagonrpcd-adsp-sensorspd
|
||||
|
||||
@@ -210,6 +210,8 @@ getprogchoices() {
|
||||
$icon_lck Lock (Screen off)^0^sxmo_state.sh set screenoff
|
||||
$icon_out Logout^0^confirm Logout && sxmo_power.sh logout
|
||||
$icon_rld Reboot^0^confirm Reboot && sxmo_power.sh reboot
|
||||
$icon_rld Reboot to Fastboot^0^confirm Fastboot && sxmo_power.sh fastboot
|
||||
$icon_rld Reboot to EDL^0^confirm EDL && sxmo_power.sh edl
|
||||
$icon_pwr Poweroff^0^confirm Poweroff && sxmo_power.sh poweroff"
|
||||
;;
|
||||
modem)
|
||||
|
||||
@@ -8,7 +8,7 @@ export PATH="/sbin:/usr/sbin:$PATH"
|
||||
. sxmo_common.sh
|
||||
|
||||
usage() {
|
||||
printf "usage: %s [reboot|poweroff|logout|togglewm]\n" "$(basename "$0")"
|
||||
printf "usage: %s [reboot|fastboot|bootloader|edl|poweroff|logout|togglewm]\n" "$(basename "$0")"
|
||||
}
|
||||
|
||||
run_polkit_login1() {
|
||||
@@ -89,9 +89,29 @@ run_priv_power() {
|
||||
return 1
|
||||
}
|
||||
|
||||
set_kernel_reboot_mode() {
|
||||
rmode="$1"
|
||||
param_path="/sys/module/leds_msm8905_torch/parameters/next_reboot_mode"
|
||||
if [ -e "$param_path" ]; then
|
||||
printf "%s\n" "$rmode" | /usr/bin/doas tee "$param_path" >/dev/null 2>&1 || \
|
||||
printf "%s\n" "$rmode" > "$param_path" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
force_reboot_cmd() {
|
||||
rmode="$1"
|
||||
/usr/bin/doas python3 -c "
|
||||
import ctypes, os
|
||||
os.sync()
|
||||
libc = ctypes.CDLL(None)
|
||||
libc.syscall(88, 0xfee1dead, 672274793, 0xa1b2c3d4, b'$rmode')
|
||||
" >/dev/null 2>&1 || /usr/bin/doas /sbin/reboot -f >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
reboot)
|
||||
sync
|
||||
set_kernel_reboot_mode ""
|
||||
sxmo_hook_power.sh reboot || true
|
||||
(sleep 4; [ -u /usr/bin/doas ] && /usr/bin/doas /sbin/reboot -f >/dev/null 2>&1 || [ -u /usr/bin/sudo ] && /usr/bin/sudo -n /sbin/reboot -f >/dev/null 2>&1) &
|
||||
if ! run_priv_power reboot; then
|
||||
@@ -102,6 +122,26 @@ case "$1" in
|
||||
fi
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
;;
|
||||
fastboot|bootloader)
|
||||
sync
|
||||
set_kernel_reboot_mode "bootloader"
|
||||
sxmo_hook_power.sh reboot || true
|
||||
(sleep 4; force_reboot_cmd "bootloader") &
|
||||
if ! run_priv_power reboot; then
|
||||
force_reboot_cmd "bootloader"
|
||||
fi
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
;;
|
||||
edl)
|
||||
sync
|
||||
set_kernel_reboot_mode "edl"
|
||||
sxmo_hook_power.sh reboot || true
|
||||
(sleep 4; force_reboot_cmd "edl") &
|
||||
if ! run_priv_power reboot; then
|
||||
force_reboot_cmd "edl"
|
||||
fi
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
;;
|
||||
poweroff)
|
||||
sync
|
||||
sxmo_hook_power.sh poweroff || true
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -558,8 +558,331 @@ case "$cmd" in
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sim-contacts-import)
|
||||
req_slot="${2:-auto}"
|
||||
if ! wait_for_qmicli_modem 3; then
|
||||
echo "ERROR: No modem available"
|
||||
exit 1
|
||||
fi
|
||||
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
if [ -z "$QMI_CARDS" ]; then
|
||||
echo "ERROR: Cannot read SIM card status"
|
||||
exit 1
|
||||
fi
|
||||
eval "$(parse_uim_card_status "$QMI_CARDS" "$PREFERRED_SIM_SLOT")"
|
||||
|
||||
target_slot=""
|
||||
target_aid=""
|
||||
if [ "$req_slot" = "1" ]; then
|
||||
if [ "$SLOT1_STATE" != "present" ]; then
|
||||
echo "ERROR: SIM 1 is not inserted"
|
||||
exit 1
|
||||
fi
|
||||
target_slot="1"
|
||||
target_aid="$SLOT1_AID"
|
||||
elif [ "$req_slot" = "2" ]; then
|
||||
if [ "$SLOT2_STATE" != "present" ]; then
|
||||
echo "ERROR: SIM 2 is not inserted"
|
||||
exit 1
|
||||
fi
|
||||
target_slot="2"
|
||||
target_aid="$SLOT2_AID"
|
||||
else
|
||||
if [ "$PRIMARY_GW_SLOT" = "1" ] && [ "$SLOT1_STATE" = "present" ]; then
|
||||
target_slot="1"
|
||||
target_aid="$SLOT1_AID"
|
||||
elif [ "$PRIMARY_GW_SLOT" = "2" ] && [ "$SLOT2_STATE" = "present" ]; then
|
||||
target_slot="2"
|
||||
target_aid="$SLOT2_AID"
|
||||
elif [ "$SLOT1_STATE" = "present" ]; then
|
||||
target_slot="1"
|
||||
target_aid="$SLOT1_AID"
|
||||
elif [ "$SLOT2_STATE" = "present" ]; then
|
||||
target_slot="2"
|
||||
target_aid="$SLOT2_AID"
|
||||
else
|
||||
echo "ERROR: No SIM card detected"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
orig_gw_slot="$PRIMARY_GW_SLOT"
|
||||
orig_gw_aid=""
|
||||
if [ "$orig_gw_slot" = "1" ]; then
|
||||
orig_gw_aid="$SLOT1_AID"
|
||||
elif [ "$orig_gw_slot" = "2" ]; then
|
||||
orig_gw_aid="$SLOT2_AID"
|
||||
fi
|
||||
switched_gw=0
|
||||
restore_gw_slot() {
|
||||
if [ "$switched_gw" = "1" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
|
||||
if [ -n "$orig_gw_slot" ] && [ "$orig_gw_slot" != "0" ] && [ -n "$orig_gw_aid" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session="slot=$orig_gw_slot,activate=yes,session-type=primary-gw-provisioning,aid=$orig_gw_aid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
switched_gw=0
|
||||
fi
|
||||
}
|
||||
trap restore_gw_slot EXIT INT TERM
|
||||
|
||||
if [ "$PRIMARY_GW_SLOT" != "$target_slot" ] && [ -n "$target_aid" ]; then
|
||||
if [ "$PRIMARY_GW_SLOT" != "0" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
|
||||
fi
|
||||
if $QMICLI_MODEM --uim-change-provisioning-session="slot=$target_slot,activate=yes,session-type=primary-gw-provisioning,aid=$target_aid" >/dev/null 2>&1; then
|
||||
switched_gw=1
|
||||
sleep 1
|
||||
fi
|
||||
fi
|
||||
|
||||
tmp_contacts="/tmp/sim_import_$$.tsv"
|
||||
rm -f "$tmp_contacts"
|
||||
: > "$tmp_contacts"
|
||||
|
||||
# Method 1: Standard 3GPP AT+CPBS="SM" / AT+CPBR
|
||||
at_info="$("$0" at auto 'AT+CMEE=2;+CSCS="GSM";+CPBS="SM";+CPBR=?' 2>/dev/null || true)"
|
||||
max_idx="$(printf "%s\n" "$at_info" | sed -n 's/.*+CPBR:[[:space:]]*([0-9]*-\([0-9]*\)).*/\1/p' | head -n1)"
|
||||
if [ -n "$max_idx" ] && [ "$max_idx" -gt 0 ] 2>/dev/null; then
|
||||
if [ "$max_idx" -gt 500 ]; then
|
||||
max_idx=500
|
||||
fi
|
||||
start_idx=1
|
||||
while [ "$start_idx" -le "$max_idx" ]; do
|
||||
end_idx=$((start_idx + 49))
|
||||
if [ "$end_idx" -gt "$max_idx" ]; then
|
||||
end_idx="$max_idx"
|
||||
fi
|
||||
chunk="$("$0" at auto "AT+CPBR=${start_idx},${end_idx}" 2>/dev/null || true)"
|
||||
if [ -n "$chunk" ]; then
|
||||
printf "%s\n" "$chunk" | awk '
|
||||
/^\+CPBR:[[:space:]]*[0-9]+,/ {
|
||||
line = $0
|
||||
sub(/^\+CPBR:[[:space:]]*[0-9]+,[[:space:]]*"/, "", line)
|
||||
q1 = index(line, "\"")
|
||||
if (q1 <= 0) next
|
||||
num = substr(line, 1, q1 - 1)
|
||||
rest = substr(line, q1 + 1)
|
||||
sub(/^[[:space:]]*,[[:space:]]*/, "", rest)
|
||||
c2 = index(rest, ",")
|
||||
if (c2 <= 0) next
|
||||
ton = substr(rest, 1, c2 - 1) + 0
|
||||
name = substr(rest, c2 + 1)
|
||||
sub(/^[[:space:]]*"/, "", name)
|
||||
sub(/"[[:space:]]*$/, "", name)
|
||||
gsub(/[\t\r\n]/, " ", name)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", num)
|
||||
if (num == "") next
|
||||
if (ton == 145 && substr(num, 1, 1) != "+") {
|
||||
num = "+" num
|
||||
}
|
||||
if (name == "") name = num
|
||||
printf "%s\t%s\n", num, name
|
||||
}
|
||||
' >> "$tmp_contacts"
|
||||
fi
|
||||
start_idx=$((end_idx + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
# Method 2: Direct QMI UIM EF_ADN (3F00:7F10:6F3A) record fallback
|
||||
if [ ! -s "$tmp_contacts" ]; then
|
||||
adn_attr="$($QMICLI_MODEM --uim-get-file-attributes=0x3F00,0x7F10,0x6F3A 2>/dev/null || true)"
|
||||
reclen="$(printf "%s\n" "$adn_attr" | awk -F"'" '/Record length:/ {print $2 + 0; exit}')"
|
||||
reccount="$(printf "%s\n" "$adn_attr" | awk -F"'" '/Record count:/ {print $2 + 0; exit}')"
|
||||
if [ -n "$reclen" ] && [ -n "$reccount" ] && [ "$reclen" -ge 14 ] 2>/dev/null && [ "$reccount" -ge 1 ] 2>/dev/null; then
|
||||
if [ "$reccount" -gt 250 ]; then
|
||||
reccount=250
|
||||
fi
|
||||
rec=1
|
||||
while [ "$rec" -le "$reccount" ]; do
|
||||
raw_rec="$($QMICLI_MODEM --uim-read-record="file=0x3F00,0x7F10,0x6F3A,record-number=${rec},record-length=${reclen}" 2>/dev/null || true)"
|
||||
if [ -n "$raw_rec" ]; then
|
||||
printf "%s\n" "$raw_rec" | awk -v rlen="$reclen" '
|
||||
function hex2val(h, i, c, v, res) {
|
||||
res = 0
|
||||
h = toupper(h)
|
||||
for (i = 1; i <= length(h); i++) {
|
||||
c = substr(h, i, 1)
|
||||
v = index("0123456789ABCDEF", c) - 1
|
||||
if (v < 0) return -1
|
||||
res = res * 16 + v
|
||||
}
|
||||
return res
|
||||
}
|
||||
function bcd_digit(n) {
|
||||
if (n >= 0 && n <= 9) return "" n
|
||||
if (n == 10) return "*"
|
||||
if (n == 11) return "#"
|
||||
return ""
|
||||
}
|
||||
/^[[:space:]]*([0-9A-Fa-f]{2}:)+[0-9A-Fa-f]{2}[[:space:]]*$/ {
|
||||
line = $0
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
|
||||
n = split(line, hex, ":")
|
||||
if (n < 14) next
|
||||
alpha_len = n - 14
|
||||
bcd_len = hex2val(hex[alpha_len + 1])
|
||||
ton_npi = hex2val(hex[alpha_len + 2])
|
||||
if (bcd_len <= 0 || bcd_len > 11 || bcd_len == 255) next
|
||||
num = ""
|
||||
if (int(ton_npi / 16) % 8 == 1) {
|
||||
num = "+"
|
||||
}
|
||||
bcd_bytes = bcd_len - 1
|
||||
if (bcd_bytes > 10) bcd_bytes = 10
|
||||
for (i = 1; i <= bcd_bytes; i++) {
|
||||
b = hex2val(hex[alpha_len + 2 + i])
|
||||
if (b < 0 || b == 255) break
|
||||
lo = b % 16
|
||||
hi = int(b / 16)
|
||||
d1 = bcd_digit(lo)
|
||||
if (d1 == "") break
|
||||
num = num d1
|
||||
d2 = bcd_digit(hi)
|
||||
if (d2 == "") break
|
||||
num = num d2
|
||||
}
|
||||
if (num == "" || num == "+") next
|
||||
name = ""
|
||||
for (i = 1; i <= alpha_len; i++) {
|
||||
b = hex2val(hex[i])
|
||||
if (b < 0 || b == 255) break
|
||||
if (b >= 32 && b < 127 && b != 9) {
|
||||
name = name sprintf("%c", b)
|
||||
}
|
||||
}
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
||||
if (name == "") name = num
|
||||
printf "%s\t%s\n", num, name
|
||||
}
|
||||
' >> "$tmp_contacts"
|
||||
fi
|
||||
rec=$((rec + 1))
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
cat "$tmp_contacts"
|
||||
rm -f "$tmp_contacts"
|
||||
exit 0
|
||||
;;
|
||||
|
||||
sim-contacts-export)
|
||||
req_slot="${2:-auto}"
|
||||
src_tsv="${3:-/home/user/.config/sxmo/contacts.tsv}"
|
||||
if [ ! -r "$src_tsv" ]; then
|
||||
echo "ERROR: Contacts file not found"
|
||||
exit 1
|
||||
fi
|
||||
if ! wait_for_qmicli_modem 3; then
|
||||
echo "ERROR: No modem available"
|
||||
exit 1
|
||||
fi
|
||||
QMI_CARDS="$($QMICLI_MODEM --uim-get-card-status 2>/dev/null || true)"
|
||||
if [ -z "$QMI_CARDS" ]; then
|
||||
echo "ERROR: Cannot read SIM card status"
|
||||
exit 1
|
||||
fi
|
||||
eval "$(parse_uim_card_status "$QMI_CARDS" "$PREFERRED_SIM_SLOT")"
|
||||
|
||||
target_slot=""
|
||||
target_aid=""
|
||||
if [ "$req_slot" = "1" ]; then
|
||||
if [ "$SLOT1_STATE" != "present" ]; then
|
||||
echo "ERROR: SIM 1 is not inserted"
|
||||
exit 1
|
||||
fi
|
||||
target_slot="1"
|
||||
target_aid="$SLOT1_AID"
|
||||
elif [ "$req_slot" = "2" ]; then
|
||||
if [ "$SLOT2_STATE" != "present" ]; then
|
||||
echo "ERROR: SIM 2 is not inserted"
|
||||
exit 1
|
||||
fi
|
||||
target_slot="2"
|
||||
target_aid="$SLOT2_AID"
|
||||
else
|
||||
if [ "$PRIMARY_GW_SLOT" = "1" ] && [ "$SLOT1_STATE" = "present" ]; then
|
||||
target_slot="1"
|
||||
target_aid="$SLOT1_AID"
|
||||
elif [ "$PRIMARY_GW_SLOT" = "2" ] && [ "$SLOT2_STATE" = "present" ]; then
|
||||
target_slot="2"
|
||||
target_aid="$SLOT2_AID"
|
||||
elif [ "$SLOT1_STATE" = "present" ]; then
|
||||
target_slot="1"
|
||||
target_aid="$SLOT1_AID"
|
||||
elif [ "$SLOT2_STATE" = "present" ]; then
|
||||
target_slot="2"
|
||||
target_aid="$SLOT2_AID"
|
||||
else
|
||||
echo "ERROR: No SIM card detected"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
orig_gw_slot="$PRIMARY_GW_SLOT"
|
||||
orig_gw_aid=""
|
||||
if [ "$orig_gw_slot" = "1" ]; then
|
||||
orig_gw_aid="$SLOT1_AID"
|
||||
elif [ "$orig_gw_slot" = "2" ]; then
|
||||
orig_gw_aid="$SLOT2_AID"
|
||||
fi
|
||||
switched_gw=0
|
||||
restore_gw_slot_exp() {
|
||||
if [ "$switched_gw" = "1" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
|
||||
if [ -n "$orig_gw_slot" ] && [ "$orig_gw_slot" != "0" ] && [ -n "$orig_gw_aid" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session="slot=$orig_gw_slot,activate=yes,session-type=primary-gw-provisioning,aid=$orig_gw_aid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
switched_gw=0
|
||||
fi
|
||||
}
|
||||
trap restore_gw_slot_exp EXIT INT TERM
|
||||
|
||||
if [ "$PRIMARY_GW_SLOT" != "$target_slot" ] && [ -n "$target_aid" ]; then
|
||||
if [ "$PRIMARY_GW_SLOT" != "0" ]; then
|
||||
$QMICLI_MODEM --uim-change-provisioning-session='activate=no,session-type=primary-gw-provisioning' >/dev/null 2>&1 || true
|
||||
fi
|
||||
if $QMICLI_MODEM --uim-change-provisioning-session="slot=$target_slot,activate=yes,session-type=primary-gw-provisioning,aid=$target_aid" >/dev/null 2>&1; then
|
||||
switched_gw=1
|
||||
sleep 1
|
||||
fi
|
||||
fi
|
||||
|
||||
at_info="$("$0" at auto 'AT+CMEE=2;+CSCS="GSM";+CPBS="SM";+CPBR=?' 2>/dev/null || true)"
|
||||
if printf "%s\n" "$at_info" | grep -qE "ERROR"; then
|
||||
echo "ERROR: SIM $target_slot phonebook not ready"
|
||||
exit 1
|
||||
fi
|
||||
tlen="$(printf "%s\n" "$at_info" | sed -n 's/.*+CPBR:[[:space:]]*([0-9]*-[0-9]*),[0-9]*,\([0-9]*\).*/\1/p' | head -n1)"
|
||||
if [ -z "$tlen" ] || [ "$tlen" -le 0 ] 2>/dev/null; then
|
||||
tlen=14
|
||||
fi
|
||||
|
||||
exported=0
|
||||
while IFS="$(printf '\t')" read -r raw_num raw_name; do
|
||||
num="$(printf "%s" "$raw_num" | tr -cd '+0-9*#')"
|
||||
name="$(printf "%s" "$raw_name" | tr -d '"\r\n\t\\' | cut -c1-"$tlen")"
|
||||
[ -n "$num" ] || continue
|
||||
[ -n "$name" ] || name="$(printf "%s" "$num" | cut -c1-"$tlen")"
|
||||
ton=129
|
||||
case "$num" in
|
||||
+*) ton=145 ;;
|
||||
esac
|
||||
res="$("$0" at auto "AT+CPBW=,\"${num}\",${ton},\"${name}\"" 2>/dev/null || true)"
|
||||
if printf "%s\n" "$res" | grep -q "OK"; then
|
||||
exported=$((exported + 1))
|
||||
fi
|
||||
done < "$src_tsv"
|
||||
|
||||
echo "EXPORTED=${exported}"
|
||||
echo "SLOT=${target_slot}"
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 [boot|status|switch <1|2>|verify-pin <slot> <pin>|unblock-puk <slot> <puk> <newpin>|set-pin-lock <slot> <enable|disable> <pin>|change-pin <slot> <oldpin> <newpin>|imei|usb-tether <on|off|status>|at <port> <cmd>]" >&2
|
||||
echo "Usage: $0 [boot|status|switch <1|2>|verify-pin <slot> <pin>|unblock-puk <slot> <puk> <newpin>|set-pin-lock <slot> <enable|disable> <pin>|change-pin <slot> <oldpin> <newpin>|imei|usb-tether <on|off|status>|at <port> <cmd>|sim-contacts-import [1|2|auto]|sim-contacts-export [1|2|auto] [tsv_file]]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -91,6 +91,8 @@ case "$WMCLASS" in
|
||||
$icon_lck Lock (Screen off) ^ 0 ^ sxmo_state.sh set screenoff
|
||||
$icon_out Logout ^ 0 ^ confirm Logout && sxmo_power.sh logout
|
||||
$icon_rld Reboot ^ 0 ^ confirm Reboot && sxmo_power.sh reboot
|
||||
$icon_rld Reboot to Fastboot ^ 0 ^ confirm Fastboot && sxmo_power.sh fastboot
|
||||
$icon_rld Reboot to EDL ^ 0 ^ confirm EDL && sxmo_power.sh edl
|
||||
$icon_pwr Poweroff ^ 0 ^ confirm Poweroff && sxmo_power.sh poweroff
|
||||
"
|
||||
WINNAME=Power
|
||||
|
||||
Reference in New Issue
Block a user