diff --git a/configs/default_hooks/discard b/configs/default_hooks/discard new file mode 100644 index 0000000..a8307c1 --- /dev/null +++ b/configs/default_hooks/discard @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# This script is executed (asynchronously) when you discard an incoming call + +exec "$(dirname "$0")/missed_call" "$@" diff --git a/configs/default_hooks/mute_ring b/configs/default_hooks/mute_ring new file mode 100644 index 0000000..85eb49f --- /dev/null +++ b/configs/default_hooks/mute_ring @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +# This script is executed (asynchronously) when you mute an incoming call + +exec "$(dirname "$0")/missed_call" "$@" diff --git a/scripts/core/sxmo_lock.sh b/scripts/core/sxmo_lock.sh index 791dd5c..c5f274f 100755 --- a/scripts/core/sxmo_lock.sh +++ b/scripts/core/sxmo_lock.sh @@ -4,11 +4,18 @@ # shellcheck source=scripts/core/sxmo_common.sh . "$(dirname "$0")/sxmo_common.sh" +finish() { + kill $LOCKPID +} +trap 'finish' TERM INT + if [ -x "$XDG_CONFIG_HOME/sxmo/hooks/lock" ]; then "$XDG_CONFIG_HOME/sxmo/hooks/lock" fi pkill -9 lisgd -sxmo_screenlock "$@" +sxmo_screenlock "$@" & +LOCKPID="$!" +wait $LOCKPID [ "$(xrandr | grep DSI-1 | cut -d ' ' -f 5)" = "right" ] && ORIENTATION=1 || ORIENTATION=0 sxmo_lisgdstart.sh -o $ORIENTATION & if [ -x "$XDG_CONFIG_HOME/sxmo/hooks/unlock" ]; then diff --git a/scripts/core/sxmo_movement.sh b/scripts/core/sxmo_movement.sh new file mode 100644 index 0000000..2c4b5ce --- /dev/null +++ b/scripts/core/sxmo_movement.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh + +anglevel_x_raw_bus="$(find /sys/ -name 'in_anglvel_x_raw')" +anglx() { + cat "$anglevel_x_raw_bus" +} + +waitmovement() { + initialpos="$(anglx)" + while true; do + pos="$(anglx)" + movement="$(echo "$initialpos" - "$pos" | bc)" + [ 0 -gt "$movement" ] && movement="$(echo "$movement * -1" | bc)" + [ 10 -lt "$movement" ] && return + sleep 0.5 + done +} + +"$@" diff --git a/scripts/core/sxmo_proximitylock.sh b/scripts/core/sxmo_proximitylock.sh new file mode 100644 index 0000000..3834873 --- /dev/null +++ b/scripts/core/sxmo_proximitylock.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env sh + +finish() { + kill $(jobs -p) + [ free = "$STATE" ] && [ true = "$WASLOCKED" ] && sxmo_lock.sh & + exit 0 +} + +trap 'finish' TERM INT + +proximity_raw_bus="$(find /sys/ -name 'in_proximity_raw')" +distance() { + cat "$proximity_raw_bus" +} + +TARGET=30 + +mainloop() { + while true; do + distance="$(distance)" + if [ locked = "$STATE" ] && [ "$distance" -lt "$TARGET" ]; then + pkill -f sxmo_lock.sh + STATE=free + elif [ free = "$STATE" ] && [ "$distance" -gt "$TARGET" ]; then + sxmo_lock.sh --screen-off & + STATE=locked + fi + sleep 0.5 + done +} + +pgrep -f sxmo_lock.sh > /dev/null && STATE=locked || STATE=free +if [ locked = "$STATE" ]; then + WASLOCKED=true + + # we dont want to loose the initial lock if the phone is forgotten somewhere + # without proximity as this will prevent going back to crust + sxmo_movement.sh waitmovement +fi + +mainloop diff --git a/scripts/modem/sxmo_modemcall.sh b/scripts/modem/sxmo_modemcall.sh index 49ef212..fd8e9b9 100755 --- a/scripts/modem/sxmo_modemcall.sh +++ b/scripts/modem/sxmo_modemcall.sh @@ -14,14 +14,7 @@ modem_n() { finish() { - # E.g. hangup all calls, switch back to default audio, notify user, and die sxmo_vibratepine 1000 & - mmcli -m "$(modem_n)" --voice-hangup-all - for CALLID in $( - mmcli -m "$(modem_n)" --voice-list-calls | grep -oE "Call\/[0-9]+" | cut -d'/' -f2 - ); do - mmcli -m "$(modem_n)" --voice-delete-call "$CALLID" - done if [ -f "$ALSASTATEFILE" ]; then alsactl --file "$ALSASTATEFILE" restore else @@ -32,12 +25,14 @@ finish() { echo "sxmo_modemcall: $1">&2 notify-send "$1" fi - kill -9 0 - pkill -9 dmenu #just in case the call menu survived somehow? + kill $LOCKPID + pkill -9 dmenu exit 1 } gracefulexit() { + kill $MAINPID + wait $MAINPID finish "Call ended" } @@ -57,6 +52,20 @@ vid_to_number() { tr -d ' ' } +number_to_contactname() { + NUMBER="$(echo "$1" | sed "s/^0\([0-9]\{9\}\)$/${DEFAULT_NUMBER_PREFIX:-0}\1/")" + CONTACT=$(sxmo_contacts.sh --all | + grep "^$NUMBER:" | + cut -d':' -f 2 | + sed 's/^[ \t]*//;s/[ \t]*$//' #strip leading/trailing whitespace + ) + if [ -n "$CONTACT" ]; then + echo "$CONTACT" + else + echo "Unknown ($NUMBER)" + fi +} + log_event() { EVT_HANDLE="$1" EVT_VID="$2" @@ -88,7 +97,6 @@ toggleflagset() { acceptcall() { CALLID="$1" - rm "$NOTIFDIR/incomingcall_${CALLID}_notification"* 2>dev/null #there can be multiple actionable notifications for one call (pickup/discard) echo "sxmo_modemcall: Attempting to initialize CALLID $CALLID">&2 DIRECTION="$( mmcli --voice-status -o "$CALLID" -K | @@ -118,14 +126,20 @@ acceptcall() { hangup() { CALLID="$1" - rm "$NOTIFDIR/incomingcall_${CALLID}_notification"* 2>dev/null #there can be multiple actionable notifications for one call (pickup/discard) - if [ ! -f "$CACHEDIR/${CALLID}.pickedupcall" ]; then + if [ -f "$CACHEDIR/${CALLID}.pickedupcall" ]; then + rm -f "$CACHEDIR/${CALLID}.pickedupcall" + touch "$CACHEDIR/${CALLID}.hangedupcall" #this signals that we hanged up this call to other asynchronously running processes + log_event "call_hangup" "$CALLID" + else #this call was never picked up and hung up immediately, so it is a discarded call touch "$CACHEDIR/${CALLID}.discardedcall" #this signals that we discarded this call to other asynchronously running processes + if [ -x "$XDG_CONFIG_HOME/sxmo/hooks/discard" ]; then + echo "sxmo_modemcall: Invoking discard hook (async)">&2 + "$XDG_CONFIG_HOME/sxmo/hooks/discard" & + fi + log_event "call_discard" "$CALLID" fi modem_cmd_errcheck -m "$(modem_n)" -o "$CALLID" --hangup - log_event "call_hangup" "$CALLID" - modem_cmd_errcheck -m "$(modem_n)" --voice-delete-call="$CALLID" finish "Call with $NUMBER terminated" exit 0 } @@ -153,23 +167,6 @@ incallsetup() { toggleflagset "-2" } -incallmonitor() { - CALLID="$1" - while true; do - sxmo_statusbarupdate.sh - if mmcli -m "$(modem_n)" -K -o "$CALLID" | grep -E "^call.properties.state.+terminated"; then - #note: deletion will be handled asynchronously by sxmo_modemmonitor's checkforfinishedcalls() - if [ "$NUMBER" = "--" ]; then - finish "Call with unknown number terminated" - else - finish "Call with $NUMBER terminated" - fi - fi - echo "sxmo_modemcall: Call still in progress">&2 - sleep 3 - done -} - incallmenuloop() { echo "sxmo_modemcall: Current flags are $FLAGS">&2 CHOICES=" @@ -225,9 +222,44 @@ dtmfmenu() { pickup() { acceptcall "$1" incallsetup "$1" - incallmonitor "$1" & incallmenuloop "$1" } +mute() { + touch "$CACHEDIR/$1.mutedring" #this signals that we muted this ring + if [ -x "$XDG_CONFIG_HOME/sxmo/hooks/mute_ring" ]; then + echo "sxmo_modemmonitor: Invoking mute_ring hook (async)">&2 + "$XDG_CONFIG_HOME/sxmo/hooks/mute_ring" "$CONTACTNAME" & + fi + log_event "ring_mute" "$1" + finish "Ringing with $NUMBER muted" +} + +incomingcallmenu() { + NUMBER=$(vid_to_number "$1") + CONTACTNAME=$(number_to_contactname "$NUMBER") + + # wait for sxmo to be unlocked to display menus + while pgrep sxmo_screenlock > /dev/null; do sleep 0.3; done + PICKED="$( + printf %b "$icon_phn Pickup\n$icon_phx Hangup\n$icon_mut Mute\n" | + dmenu -c -l 5 -p "$CONTACTNAME" + )" + + if echo "$PICKED" | grep -q "Pickup"; then + pickup "$1" + elif echo "$PICKED" | grep -q "Hangup"; then + hangup "$1" + elif echo "$PICKED" | grep -q "Mute"; then + mute "$1" + fi +} + modem_n || finish "Couldn't determine modem number - is modem online?" -"$@" + +sxmo_proximitylock.sh & +LOCKPID="$!" + +"$@" & +MAINPID="$!" +wait $MAINPID diff --git a/scripts/modem/sxmo_modemmonitor.sh b/scripts/modem/sxmo_modemmonitor.sh index bbac2fc..1f64631 100755 --- a/scripts/modem/sxmo_modemmonitor.sh +++ b/scripts/modem/sxmo_modemmonitor.sh @@ -72,31 +72,44 @@ checkforfinishedcalls() { ); do FINISHEDNUMBER="$(lookupnumberfromcallid "$FINISHEDCALLID")" mmcli -m "$(modem_n)" --voice-delete-call "$FINISHEDCALLID" - rm -f "$NOTIFDIR/incomingcall_${FINISHEDCALLID}_notification"* #there may be multiple actionable notification for one call - if [ -x "$XDG_CONFIG_HOME/sxmo/hooks/missed_call" ]; then - echo "sxmo_modemmonitor: Invoking missed call hook (async)">&2 - "$XDG_CONFIG_HOME/sxmo/hooks/missed_call" "$CONTACTNAME" & - fi + rm -f "$CACHEDIR/${FINISHEDCALLID}.monitoredcall" TIME="$(date --iso-8601=seconds)" mkdir -p "$LOGDIR" if [ -f "$CACHEDIR/${FINISHEDCALLID}.discardedcall" ]; then + #this call was discarded echo "sxmo_modemmonitor: Discarded call from $FINISHEDNUMBER">&2 rm -f "$CACHEDIR/${FINISHEDCALLID}.discardedcall" printf %b "$TIME\tcall_discarded\t$FINISHEDNUMBER\n" >> "$LOGDIR/modemlog.tsv" elif [ -f "$CACHEDIR/${FINISHEDCALLID}.pickedupcall" ]; then #this call was picked up - pkill -f sxmo_modemcall.sh #kill call (softly) in case it is still in progress (remote party hung up) + pkill -f sxmo_modemcall.sh echo "sxmo_modemmonitor: Finished call from $FINISHEDNUMBER">&2 rm -f "$CACHEDIR/${FINISHEDCALLID}.pickedupcall" printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$LOGDIR/modemlog.tsv" + elif [ -f "$CACHEDIR/${FINISHEDCALLID}.hangedupcall" ]; then + #this call was hanged up + echo "sxmo_modemmonitor: Finished call from $FINISHEDNUMBER">&2 + rm -f "$CACHEDIR/${FINISHEDCALLID}.hangedupcall" + printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$LOGDIR/modemlog.tsv" + elif [ -f "$CACHEDIR/${FINISHEDCALLID}.mutedring" ]; then + #this ring was muted up + echo "sxmo_modemmonitor: Muted ring from $FINISHEDNUMBER">&2 + rm -f "$CACHEDIR/${FINISHEDCALLID}.mutedring" + printf %b "$TIME\tring_muted\t$FINISHEDNUMBER\n" >> "$LOGDIR/modemlog.tsv" else #this is a missed call # Add a notification for every missed call + pkill -f sxmo_modemcall.sh echo "sxmo_modemmonitor: Missed call from $FINISHEDNUMBER">&2 printf %b "$TIME\tcall_missed\t$FINISHEDNUMBER\n" >> "$LOGDIR/modemlog.tsv" + if [ -x "$XDG_CONFIG_HOME/sxmo/hooks/missed_call" ]; then + echo "sxmo_modemmonitor: Invoking missed call hook (async)">&2 + "$XDG_CONFIG_HOME/sxmo/hooks/missed_call" "$CONTACTNAME" & + fi + CONTACT="$(lookupcontactname "$FINISHEDNUMBER")" sxmo_notificationwrite.sh \ random \ @@ -113,7 +126,10 @@ checkforincomingcalls() { grep -Eo '[0-9]+ incoming \(ringing-in\)' | grep -Eo '[0-9]+' )" - echo "$VOICECALLID" | grep -v . && rm -f "$NOTIFDIR/incomingcall*" && return + [ -z "$VOICECALLID" ] && return + + [ -f "$CACHEDIR/${VOICECALLID}.monitoredcall" ] && return # prevent multiple rings + touch "$CACHEDIR/${VOICECALLID}.monitoredcall" #this signals that we handled the call # Determine the incoming phone number echo "sxmo_modemmonitor: Incoming Call:">&2 @@ -131,16 +147,7 @@ checkforincomingcalls() { mkdir -p "$LOGDIR" printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$LOGDIR/modemlog.tsv" - sxmo_notificationwrite.sh \ - "$NOTIFDIR/incomingcall_${VOICECALLID}_notification" \ - "sxmo_modemcall.sh pickup '$VOICECALLID'" \ - none \ - "Pickup - $CONTACTNAME" & - sxmo_notificationwrite.sh \ - "$NOTIFDIR/incomingcall_${VOICECALLID}_notification_discard" \ - "sxmo_modemcall.sh hangup '$VOICECALLID'" \ - none \ - "Discard - $CONTACTNAME" & + sxmo_modemcall.sh incomingcallmenu "$VOICECALLID" & echo "sxmo_modemmonitor: Call from number: $INCOMINGNUMBER (VOICECALLID: $VOICECALLID)">&2 }