Rework calls

We need the recent -S (status) command to probe the real state of
callaudiod.

- Lot of cleanup and refactorisation

Most of the code has been moved to a better place. The call audio
setups, the pickup action and the incall menu now are three different
things we can call individually.

- Handle failures individually

Every important task as the mmcli command or volume settings should warn
a urgent message to the user if they failed.

If we failed to setup audio, or to pickup the call then we dont even try
to open the incall menu.

- Made the incall_menu closeable and re-opennable

You can close the incoming call menu and the incall menu and re-open
them from any menu.

To make this possible I moved some of the responsibilities to the
modem monitor that trigger action after modem manager signals. We then
check at this point if it was the last call and do some cleanup if so.

- Initial work for concurrent calls

Added some code to the hooks and the modem checkfinished and
checkincoming calls to handle those cased. If you are in a call and someone
else try to call you, we refresh the incall menu and new entries will allow
you to switch calls.

- The incall menu isnt sticked to one call

This menu itself doesnt need a CALLID argument. It allow us to
manage every active call. We should be able to hold and hangup and
switch calls as we want.
This commit is contained in:
Stacy Harper
2022-02-13 19:47:23 +01:00
parent 3fa74106e6
commit 73a2813d76
11 changed files with 355 additions and 217 deletions

View File

@@ -9,6 +9,8 @@
# $1 = Contact Name or Number (if not in contacts) # $1 = Contact Name or Number (if not in contacts)
# kill existing ring playback # kill existing ring playback
if [ -e "$XDG_RUNTIME_DIR/sxmo.ring.pid" ]; then
MPVID="$(cat "$XDG_RUNTIME_DIR/sxmo.ring.pid")" MPVID="$(cat "$XDG_RUNTIME_DIR/sxmo.ring.pid")"
kill $MPVID kill "$MPVID"
rm "$XDG_RUNTIME_DIR/sxmo.ring.pid" rm "$XDG_RUNTIME_DIR/sxmo.ring.pid"
fi

View File

@@ -5,7 +5,9 @@
# This script is executed (asynchronously) when you pick up an incoming call # This script is executed (asynchronously) when you pick up an incoming call
# kill existing ring playback # kill existing ring playback
if [ -e "$XDG_RUNTIME_DIR/sxmo.ring.pid" ]; then
MPVID="$(cat "$XDG_RUNTIME_DIR/sxmo.ring.pid")" MPVID="$(cat "$XDG_RUNTIME_DIR/sxmo.ring.pid")"
kill $MPVID kill "$MPVID"
rm "$XDG_RUNTIME_DIR/sxmo.ring.pid" rm "$XDG_RUNTIME_DIR/sxmo.ring.pid"
fi

View File

@@ -7,6 +7,21 @@
# $1 = Contact Name or Number (if not in contacts) # $1 = Contact Name or Number (if not in contacts)
# Only vibrate if you already got an active call
if sxmo_modemcall.sh list_active_calls \
| grep -v ringing-in \
| grep -q .; then
sxmo_vibrate 1500
exit
fi
# Shallow if you have more than one ringing call
if ! sxmo_modemcall.sh list_active_calls \
| grep -c ringing-in \
| grep -q 1; then
exit
fi
# Start the mpv ring until another hook kill it or the max (10) is reached # Start the mpv ring until another hook kill it or the max (10) is reached
mpv --quiet --no-video --loop=10 /usr/share/sxmo/ring.ogg & mpv --quiet --no-video --loop=10 /usr/share/sxmo/ring.ogg &
MPVID=$! MPVID=$!

View File

@@ -25,7 +25,10 @@ case "$SXMO_WM" in
dwm) dwm)
# dmenu will grab input focus (i.e. power button) so kill it before going to # dmenu will grab input focus (i.e. power button) so kill it before going to
# screenoff unless proximity lock is running (i.e. there's a phone call). # screenoff unless proximity lock is running (i.e. there's a phone call).
sxmo_daemons.sh running proximity_lock -q || sxmo_dmenu.sh close if ! (sxmo_daemons.sh running proximity_lock -q || \
sxmo_daemons.sh running calling_proximity_lock -q); then
sxmo_dmenu.sh close
fi
;; ;;
esac esac

View File

@@ -35,6 +35,29 @@ sxmo_type() {
sxmo_type.sh -s 200 "$@" # dunno why this is necessary but it sucks without sxmo_type.sh -s 200 "$@" # dunno why this is necessary but it sucks without
} }
call_entries() {
shown_incall_menu=
sxmo_modemcall.sh list_active_calls | while read -r line; do
case "$line" in
*"(ringing-in)")
CALLID="$(printf %s "$line" | cut -d" " -f1 | xargs basename)"
NUMBER="$(sxmo_modemcall.sh vid_to_number "$CALLID")"
CONTACT="$(sxmo_contacts.sh --name "$NUMBER")"
printf "%s Incoming call %s ^ 0 ^ sxmo_daemons.sh start incall_menu sxmo_modemcall.sh incoming_call_menu %s\n" \
"$icon_phn" "$CONTACT" "$CALLID"
;;
*)
[ -n "$shown_incall_menu" ] && continue
shown_incall_menu=1
printf "%s Incall Menu ^ 0 ^ sxmo_daemons.sh start incall_menu sxmo_modemcall.sh incall_menu\n" \
"$icon_phn"
;;
esac
done
}
getprogchoices() { getprogchoices() {
RES="$(sxmo_hook_contextmenu.sh "$1")" RES="$(sxmo_hook_contextmenu.sh "$1")"
if [ -n "$RES" ]; then if [ -n "$RES" ]; then
@@ -53,16 +76,10 @@ getprogchoices() {
fi fi
fi fi
#shellcheck disable=SC2044
for NOTIFFILE in $(find "$SXMO_NOTIFDIR" -name 'incomingcall*_notification'); do
NOTIFACTION="$(head -n1 "$NOTIFFILE")"
MESSAGE="$(tail -1 "$NOTIFFILE")"
CHOICES=" CHOICES="
$icon_phn $MESSAGE ^ 0 ^ $NOTIFACTION $(call_entries)
$CHOICES $CHOICES
" "
break
done
# Decorate menu at bottom w/ system menu entry if not system menu # Decorate menu at bottom w/ system menu entry if not system menu
echo "$WINNAME" | grep -qv Sys && CHOICES=" echo "$WINNAME" | grep -qv Sys && CHOICES="

View File

@@ -23,14 +23,16 @@ open() {
close() { close() {
if [ -n "$KEYBOARD" ]; then # avoid killing everything ! if [ -n "$KEYBOARD" ]; then # avoid killing everything !
pkill -f "$KEYBOARD" pkill "$KEYBOARD"
fi fi
} }
if [ "$1" = "toggle" ]; then if [ "$1" = "toggle" ]; then
close || open close || open
elif [ "$1" = "close" ]; then elif [ "$1" = "close" ]; then
if isopen; then
close close
fi
elif [ "$1" = "isopen" ]; then elif [ "$1" = "isopen" ]; then
isopen || exit 1 isopen || exit 1
else else

View File

@@ -27,14 +27,6 @@ cleanupnumber() {
echo "$1" echo "$1"
} }
lookupnumberfromcallid() {
VOICECALLID=$1
mmcli -m any --voice-list-calls -o "$VOICECALLID" -K |
grep call.properties.number |
cut -d ':' -f 2 |
tr -d ' '
}
checkforfinishedcalls() { checkforfinishedcalls() {
#find all finished calls #find all finished calls
for FINISHEDCALLID in $( for FINISHEDCALLID in $(
@@ -43,32 +35,36 @@ checkforfinishedcalls() {
grep -oE "Call\/[0-9]+" | grep -oE "Call\/[0-9]+" |
cut -d'/' -f2 cut -d'/' -f2
); do ); do
FINISHEDNUMBER="$(lookupnumberfromcallid "$FINISHEDCALLID")" FINISHEDNUMBER="$(sxmo_modemcall.sh vid_to_number "$FINISHEDCALLID")"
FINISHEDNUMBER="$(cleanupnumber "$FINISHEDNUMBER")" FINISHEDNUMBER="$(cleanupnumber "$FINISHEDNUMBER")"
mmcli -m any --voice-delete-call "$FINISHEDCALLID" mmcli -m any --voice-delete-call "$FINISHEDCALLID"
rm -f "$SXMO_NOTIFDIR/incomingcall_${FINISHEDCALLID}_notification"* #there may be multiple actionable notification for one call
rm -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.monitoredcall" rm -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.monitoredcall"
CONTACT="$(sxmo_contacts.sh --name "$FINISHEDNUMBER")"
[ "$CONTACT" = "???" ] && CONTACT="$FINISHEDNUMBER"
TIME="$(date +%FT%H:%M:%S%z)" TIME="$(date +%FT%H:%M:%S%z)"
mkdir -p "$SXMO_LOGDIR" mkdir -p "$SXMO_LOGDIR"
if [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.discardedcall" ]; then if [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.discardedcall" ]; then
#this call was discarded #this call was discarded
sxmo_notify_user.sh "Call with $CONTACT terminated"
stderr "Discarded call from $FINISHEDNUMBER" stderr "Discarded call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.pickedupcall" ]; then elif [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.pickedupcall" ]; then
#this call was picked up #this call was picked up
pkill -f sxmo_modemcall.sh sxmo_notify_user.sh "Call with $CONTACT terminated"
sxmo_hook_statusbar.sh volume sxmo_hook_statusbar.sh volume
stderr "Finished call from $FINISHEDNUMBER" stderr "Finished call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.hangedupcall" ]; then elif [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.hangedupcall" ]; then
#this call was hung up by the user #this call was hung up by the user
sxmo_notify_user.sh "Call with $CONTACT terminated"
stderr "Finished call from $FINISHEDNUMBER" stderr "Finished call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.initiatedcall" ]; then elif [ -f "$XDG_RUNTIME_DIR/${FINISHEDCALLID}.initiatedcall" ]; then
#this call was hung up by the contact #this call was hung up by the contact
pkill -f sxmo_modemcall.sh sxmo_notify_user.sh "Call with $CONTACT terminated"
sxmo_hook_statusbar.sh volume sxmo_hook_statusbar.sh volume
stderr "Finished call from $FINISHEDNUMBER" stderr "Finished call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
@@ -79,14 +75,11 @@ checkforfinishedcalls() {
else else
#this is a missed call #this is a missed call
# Add a notification for every missed call # Add a notification for every missed call
pkill -f sxmo_modemcall.sh
sxmo_hook_statusbar.sh volume sxmo_hook_statusbar.sh volume
stderr "Missed call from $FINISHEDNUMBER" stderr "Missed call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_missed\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\tcall_missed\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
CONTACT="$(sxmo_contacts.sh --name "$FINISHEDNUMBER")"
stderr "Invoking missed call hook (async)" stderr "Invoking missed call hook (async)"
[ "$CONTACT" = "???" ] && CONTACT="$FINISHEDNUMBER"
sxmo_hook_missed_call.sh "$CONTACT" & sxmo_hook_missed_call.sh "$CONTACT" &
sxmo_notificationwrite.sh \ sxmo_notificationwrite.sh \
@@ -95,6 +88,21 @@ checkforfinishedcalls() {
none \ none \
"Missed $icon_phn $CONTACT" "Missed $icon_phn $CONTACT"
fi fi
# If it was the last call
if ! sxmo_modemcall.sh list_active_calls | grep -q .; then
# Cleanup
sxmo_vibrate 1000 &
sxmo_daemons.sh stop incall_menu
sxmo_daemons.sh stop calling_proximity_lock
if ! sxmo_modemaudio.sh reset_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to reset call audio"
fi
setsid -f sh -c 'sleep 2; sxmo_hook_statusbar.sh call_duration'
else
# Or refresh the menu
sxmo_daemons.sh start incall_menu sxmo_modemcall.sh incall_menu
fi
done done
} }
@@ -112,7 +120,7 @@ checkforincomingcalls() {
# Determine the incoming phone number # Determine the incoming phone number
stderr "Incoming Call..." stderr "Incoming Call..."
INCOMINGNUMBER=$(lookupnumberfromcallid "$VOICECALLID") INCOMINGNUMBER=$(sxmo_modemcall.sh vid_to_number "$VOICECALLID")
INCOMINGNUMBER="$(cleanupnumber "$INCOMINGNUMBER")" INCOMINGNUMBER="$(cleanupnumber "$INCOMINGNUMBER")"
CONTACTNAME=$(sxmo_contacts.sh --name "$INCOMINGNUMBER") CONTACTNAME=$(sxmo_contacts.sh --name "$INCOMINGNUMBER")
@@ -121,7 +129,6 @@ checkforincomingcalls() {
stderr "BLOCKED call from number: $VOICECALLID" stderr "BLOCKED call from number: $VOICECALLID"
sxmo_modemcall.sh mute "$VOICECALLID" sxmo_modemcall.sh mute "$VOICECALLID"
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_BLOCKDIR/modemlog.tsv" printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_BLOCKDIR/modemlog.tsv"
rm -f "$SXMO_NOTIFDIR/incomingcall_${VOICECALLID}_notification"*
else else
stderr "Invoking ring hook (async)" stderr "Invoking ring hook (async)"
[ "$CONTACTNAME" = "???" ] && CONTACTNAME="$INCOMINGNUMBER" [ "$CONTACTNAME" = "???" ] && CONTACTNAME="$INCOMINGNUMBER"
@@ -130,12 +137,21 @@ checkforincomingcalls() {
mkdir -p "$SXMO_LOGDIR" mkdir -p "$SXMO_LOGDIR"
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
sxmo_notificationwrite.sh \ # do not duplicate proximity lock if already running
"$SXMO_NOTIFDIR/incomingcall_${VOICECALLID}_notification" \ if ! (sxmo_daemons.sh running proximity_lock -q || sxmo_daemons.sh running calling_proximity_lock -q); then
"sxmo_modemcall.sh incomingcallmenu '$VOICECALLID'" \ sxmo_daemons.sh start calling_proximity_lock sxmo_proximitylock.sh
none \ fi
"Incoming $icon_phn $CONTACTNAME" &
sxmo_modemcall.sh incomingcallmenu "$VOICECALLID" & # If we already got an active call
if sxmo_modemcall.sh list_active_calls \
| grep -v ringing-in \
| grep -q .; then
# Refresh the incall menu
sxmo_daemons.sh start incall_menu sxmo_modemcall.sh incall_menu
else
# Or fire the incomming call menu
sxmo_daemons.sh start incall_menu sxmo_modemcall.sh incoming_call_menu "$VOICECALLID"
fi
stderr "Call from number: $INCOMINGNUMBER (VOICECALLID: $VOICECALLID)" stderr "Call from number: $INCOMINGNUMBER (VOICECALLID: $VOICECALLID)"
fi fi

View File

@@ -0,0 +1,94 @@
#!/bin/sh
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
setup_audio() {
unmute_mic
enable_call_audio_mode
disable_speaker
i=0
while (! is_unmuted_mic) || (! is_call_audio_mode) || (! is_disabled_speaker); do
i=$((i+1))
if [ "$i" -gt 5 ]; then
return 1
fi
sleep 0.2
unmute_mic
enable_call_audio_mode
disable_speaker
done
}
reset_audio() {
mute_mic
disable_call_audio_mode
enable_speaker
i=0
while (! is_muted_mic) || (! is_default_audio_mode) || (! is_enabled_speaker); do
i=$((i+1))
if [ "$i" -gt 5 ]; then
return 1
fi
sleep 0.2
mute_mic
disable_call_audio_mode
enable_speaker
done
}
is_muted_mic() {
callaudiocli -S | grep -q "Mic muted: CALL_AUDIO_MIC_ON"
}
is_unmuted_mic() {
callaudiocli -S | grep -q "Mic muted: CALL_AUDIO_MIC_OFF"
}
mute_mic() {
callaudiocli -u 0
}
unmute_mic() {
callaudiocli -u 1
}
is_call_audio_mode() {
callaudiocli -S | grep -q "Selected mode: CALL_AUDIO_MODE_CALL"
}
is_default_audio_mode() {
callaudiocli -S | grep -q "Selected mode: CALL_AUDIO_MODE_DEFAULT"
}
enable_call_audio_mode() {
callaudiocli -m 1
}
disable_call_audio_mode() {
callaudiocli -m 0
}
is_enabled_speaker() {
callaudiocli -S | grep -q "Speaker enabled: CALL_AUDIO_SPEAKER_ON"
}
is_disabled_speaker() {
callaudiocli -S | grep -q "Speaker enabled: CALL_AUDIO_SPEAKER_OFF"
}
enable_speaker() {
callaudiocli -s 1
}
disable_speaker() {
callaudiocli -s 0
}
"$@"

View File

@@ -2,50 +2,13 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors # Copyright 2022 Sxmo Contributors
trap "gracefulexit" INT TERM
# include common definitions # include common definitions
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh # shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh . sxmo_hook_icons.sh
# shellcheck source=scripts/core/sxmo_common.sh # shellcheck source=scripts/core/sxmo_common.sh
. "$(dirname "$0")/sxmo_common.sh" . sxmo_common.sh
AUDIO_MODE= set -e
ENABLED_SPEAKER=
MUTED_MIC=
stderr() {
sxmo_log "$*"
}
finish() {
sxmo_vibrate 1000 &
setsid -f sh -c 'sleep 2; sxmo_hook_statusbar.sh call_duration'
if [ -n "$1" ]; then
stderr "$1"
notify-send Call "$1"
fi
if [ -z "$LOCKALREADYRUNNING" ]; then
sxmo_daemons.sh stop proximity_lock
fi
sxmo_dmenu.sh close
exit 1
}
gracefulexit() {
kill "$MAINPID"
wait "$MAINPID"
finish "Call ended"
}
modem_cmd_errcheck() {
RES="$(mmcli "$@" 2>&1)"
OK="$?"
stderr "Command: mmcli $*"
if [ "$OK" != 0 ]; then finish "Problem executing mmcli command!\n$RES"; fi
echo "$RES"
}
vid_to_number() { vid_to_number() {
mmcli -m any -o "$1" -K | \ mmcli -m any -o "$1" -K | \
@@ -57,15 +20,17 @@ vid_to_number() {
log_event() { log_event() {
EVT_HANDLE="$1" EVT_HANDLE="$1"
EVT_VID="$2" EVT_VID="$2"
NUM="$(vid_to_number "$EVT_VID")" NUM="$(vid_to_number "$EVT_VID")"
TIME="$(date +%FT%H:%M:%S%z)" TIME="$(date +%FT%H:%M:%S%z)"
mkdir -p "$SXMO_LOGDIR" mkdir -p "$SXMO_LOGDIR"
printf %b "$TIME\t$EVT_HANDLE\t$NUM\n" >> "$SXMO_LOGDIR/modemlog.tsv" printf %b "$TIME\t$EVT_HANDLE\t$NUM\n" >> "$SXMO_LOGDIR/modemlog.tsv"
} }
acceptcall() { pickup() {
CALLID="$1" CALLID="$1"
stderr "Attempting to initialize CALLID $CALLID"
DIRECTION="$( DIRECTION="$(
mmcli --voice-status -o "$CALLID" -K | mmcli --voice-status -o "$CALLID" -K |
grep call.properties.direction | grep call.properties.direction |
@@ -74,133 +39,131 @@ acceptcall() {
)" )"
case "$DIRECTION" in case "$DIRECTION" in
outgoing) outgoing)
modem_cmd_errcheck -m any -o "$CALLID" --start if ! mmcli -m any -o "$CALLID" --start; then
touch "$XDG_RUNTIME_DIR/${CALLID}.initiatedcall" #this signals that we started this call sxmo_notify_user.sh --urgency=critical "We failed to start the call"
return 1
fi
sxmo_notify_user.sh "Started call"
touch "$XDG_RUNTIME_DIR/${CALLID}.initiatedcall"
log_event "call_start" "$CALLID" log_event "call_start" "$CALLID"
stderr "Started call $CALLID"
;; ;;
incoming) incoming)
stderr "Invoking pickup hook (async)" sxmo_log "Invoking pickup hook (async)"
sxmo_hook_pickup.sh & sxmo_hook_pickup.sh &
touch "$XDG_RUNTIME_DIR/${CALLID}.pickedupcall" #this signals that we picked this call up
#to other asynchronously running processes if ! mmcli -m any -o "$CALLID" --accept; then
modem_cmd_errcheck -m any -o "$CALLID" --accept sxmo_notify_user.sh --urgency=critical "We failed to accept the call"
return 1
fi
sxmo_notify_user.sh "Picked up call"
touch "$XDG_RUNTIME_DIR/${CALLID}.pickedupcall"
log_event "call_pickup" "$CALLID" log_event "call_pickup" "$CALLID"
stderr "Picked up call $CALLID"
;; ;;
*) *)
finish "Couldn't initialize call with callid <$CALLID>; unknown direction <$DIRECTION>" sxmo_notify_user.sh --urgency=critical "Couldn't initialize call with callid <$CALLID>; unknown direction <$DIRECTION>"
;; ;;
esac esac
unmute_mic
enable_call_audio_mode
disable_speaker
} }
hangup() { hangup() {
CALLID="$1" CALLID="$1"
disable_call_audio_mode
enable_speaker
if [ -f "$XDG_RUNTIME_DIR/${CALLID}.pickedupcall" ]; then if [ -f "$XDG_RUNTIME_DIR/${CALLID}.pickedupcall" ]; then
rm -f "$XDG_RUNTIME_DIR/${CALLID}.pickedupcall" rm -f "$XDG_RUNTIME_DIR/${CALLID}.pickedupcall"
touch "$XDG_RUNTIME_DIR/${CALLID}.hangedupcall" #this signals that we hanged up this call to other asynchronously running processes touch "$XDG_RUNTIME_DIR/${CALLID}.hangedupcall"
log_event "call_hangup" "$CALLID" log_event "call_hangup" "$CALLID"
else else
#this call was never picked up and hung up immediately, so it is a discarded call #this call was never picked up and hung up immediately, so it is a discarded call
touch "$XDG_RUNTIME_DIR/${CALLID}.discardedcall" #this signals that we discarded this call to other asynchronously running processes touch "$XDG_RUNTIME_DIR/${CALLID}.discardedcall"
stderr "sxmo_modemcall: Invoking discard hook (async)"
sxmo_hook_discard.sh &
log_event "call_discard" "$CALLID" log_event "call_discard" "$CALLID"
sxmo_log "sxmo_modemcall: Invoking discard hook (async)"
sxmo_hook_discard.sh &
fi
if ! mmcli -m any -o "$CALLID" --hangup; then
sxmo_notify_user.sh --urgency=critical "We failed to hangup the call"
return 1
fi fi
modem_cmd_errcheck -m any -o "$CALLID" --hangup
finish "Call with $NUMBER terminated"
exit 0
} }
muted_mic() { # We shallow muted/blocked and terminated calls
[ "$MUTED_MIC" -eq 1 ] list_active_calls() {
mmcli -m any --voice-list-calls | \
awk '$1=$1' | \
grep -v terminated | \
grep -v "No calls were found" | while read -r line; do
CALLID="$(printf "%s\n" "$line" | awk '$1=$1' | cut -d" " -f1 | xargs basename)"
if [ -e "$XDG_RUNTIME_DIR/${CALLID}.mutedring" ]; then
continue # we shallow muted calls
fi
printf "%s\n" "$line"
done
} }
mute_mic() { incall_menu() {
callaudiocli -u 0 # We have an active call
MUTED_MIC=1 while list_active_calls | grep -q . ; do
}
unmute_mic() {
callaudiocli -u 1
MUTED_MIC=0
}
is_call_audio_mode() {
[ call = "$AUDIO_MODE" ]
}
enable_call_audio_mode() {
callaudiocli -m 1
AUDIO_MODE=call
}
disable_call_audio_mode() {
callaudiocli -m 0
AUDIO_MODE=default
}
enabled_speaker() {
[ "$ENABLED_SPEAKER" -eq 1 ]
}
enable_speaker() {
callaudiocli -s 1
ENABLED_SPEAKER=1
}
disable_speaker() {
callaudiocli -s 0
ENABLED_SPEAKER=0
}
incallmenuloop() {
DMENUIDX=0
NUMBER="$(vid_to_number "$1")"
export AUDIO_BACKEND=alsa # We cant control volume with pulse
while : ; do
CHOICES="$(cat <<EOF CHOICES="$(cat <<EOF
$icon_aru Volume up ^ sxmo_audio.sh vol up $icon_cls Close menu ^ exit
$icon_ard Volume down ^ sxmo_audio.sh vol down $icon_aru Volume up ^ sxmo_audio.sh vol up 20
$(enabled_speaker \ $icon_ard Volume down ^ sxmo_audio.sh vol down 20
&& printf "%s Earpiece ^ disable_speaker" "$icon_phn" \ $icon_spk Speaker $(sxmo_modemaudio.sh is_enabled_speaker \
|| printf "%s Speakerphone ^ enable_speaker" "$icon_spk" && printf "%s ^ sxmo_modemaudio.sh disable_speaker" "$icon_ton" \
|| printf "%s ^ sxmo_modemaudio.sh enable_speaker" "$icon_tof"
)
$(
list_active_calls | while read -r line; do
CALLID="$(printf %s "$line" | cut -d" " -f1 | xargs basename)"
NUMBER="$(vid_to_number "$CALLID")"
CONTACT="$(sxmo_contacts.sh --name "$NUMBER")"
[ "$CONTACT" = "???" ] && CONTACT="$NUMBER"
case "$line" in
*"(ringing-in)")
# TODO switch to this call
printf "%s Hangup %s ^ hangup %s\n" "$icon_phx" "$CONTACT" "$CALLID"
printf "%s Mute %s ^ mute %s\n" "$icon_phx" "$CONTACT" "$CALLID"
;;
*"(held)")
# TODO switch to this call
printf "%s Hangup %s ^ hangup %s\n" "$icon_phx" "$CONTACT" "$CALLID"
;;
*)
printf "%s DTMF Tones %s ^ dtmf_menu %s\n" "$icon_mus" "$CONTACT" "$CALLID"
printf "%s Hangup %s ^ hangup %s\n" "$icon_phx" "$CONTACT" "$CALLID"
;;
esac
done
) )
$icon_mus DTMF Tones ^ dtmfmenu $CALLID
$icon_phx Hangup ^ hangup $CALLID
EOF EOF
)" )"
# Disable cause doesnt have effect o_O # Disabled cause no effect on pinephone
# $(muted_mic \ # https://gitlab.com/mobian1/callaudiod/-/merge_requests/10
# && printf "%s Unmute mic ^ unmute_mic" "$icon_spk" \ # $icon_mic Mic $(sxmo_modemaudio.sh is_muted_mic \
# || printf "%s Mute mic ^ mute_mic" "$icon_phn" # && printf "%s ^ sxmo_modemaudio.sh unmute_mic " "$icon_tof" \
# || printf "%s ^ sxmo_modemaudio.sh mute_mic" "$icon_ton"
# ) # )
PICKED="$( PICKED="$(
printf "%s\n" "$CHOICES" | printf "%s\n" "$CHOICES" |
cut -d'^' -f1 | cut -d'^' -f1 |
dmenu --index "$DMENUIDX" -p "$NUMBER" sxmo_dmenu.sh -i -p "Incall Menu"
)" || hangup "$CALLID" # in case the menu is closed )" || exit
stderr "Picked is $PICKED" sxmo_log "Picked is $PICKED"
CMD="$(printf "%s\n" "$CHOICES" | grep "$PICKED" | cut -d'^' -f2)" CMD="$(printf "%s\n" "$CHOICES" | grep "$PICKED" | cut -d'^' -f2)"
DMENUIDX="$(($(printf "%s\n" "$CHOICES" | grep -n "^$PICKED" | head -n+1 | cut -d: -f1) -1))"
stderr "Eval in call context: $CMD" sxmo_log "Eval in call context: $CMD"
eval "$CMD" eval "$CMD" || exit 1
done done & # To be killeable
wait
} }
dtmfmenu() { dtmf_menu() {
CALLID="$1" CALLID="$1"
sxmo_keyboard.sh close sxmo_keyboard.sh close
@@ -208,26 +171,23 @@ dtmfmenu() {
sxmo_splitchar | xargs -n1 printf "%s\n" | stdbuf -o0 grep '[0-9A-D*#]' | \ sxmo_splitchar | xargs -n1 printf "%s\n" | stdbuf -o0 grep '[0-9A-D*#]' | \
xargs -r -I{} -n1 mmcli -m any -o "$CALLID" --send-dtmf="{}" & xargs -r -I{} -n1 mmcli -m any -o "$CALLID" --send-dtmf="{}" &
printf "Close Menu\n" | sxmo_dmenu.sh -p "DTMF Tone" # Closed return to default menu
if ! printf "Close Menu\n" | sxmo_dmenu.sh -i -p "DTMF Tone"; then
sxmo_keyboard.sh close
fi
sxmo_keyboard.sh close sxmo_keyboard.sh close
} }
pickup() {
acceptcall "$1"
incallmenuloop "$1"
}
mute() { mute() {
CALLID="$1" CALLID="$1"
touch "$XDG_RUNTIME_DIR/${CALLID}.mutedring" #this signals that we muted this ring touch "$XDG_RUNTIME_DIR/${CALLID}.mutedring" #this signals that we muted this ring
stderr "Invoking mute_ring hook (async)" sxmo_log "Invoking mute_ring hook (async)"
sxmo_hook_mute_ring.sh "$CONTACTNAME" & sxmo_hook_mute_ring.sh "$CONTACTNAME" &
log_event "ring_mute" "$1" log_event "ring_mute" "$1"
finish "Ringing with $NUMBER muted"
} }
incomingcallmenu() { incoming_call_menu() {
NUMBER="$(vid_to_number "$1")" NUMBER="$(vid_to_number "$1")"
CONTACTNAME="$(sxmo_contacts.sh --name "$NUMBER")" CONTACTNAME="$(sxmo_contacts.sh --name "$NUMBER")"
[ "$CONTACTNAME" = "???" ] && CONTACTNAME="$NUMBER" [ "$CONTACTNAME" = "???" ] && CONTACTNAME="$NUMBER"
@@ -238,8 +198,9 @@ incomingcallmenu() {
pickup_height="100" pickup_height="100"
fi fi
(
PICKED="$( PICKED="$(
cat <<EOF | dmenu -H "$pickup_height" -p "$CONTACTNAME" cat <<EOF | sxmo_dmenu.sh -i -H "$pickup_height" -p "$CONTACTNAME"
$icon_phn Pickup $icon_phn Pickup
$icon_phx Hangup $icon_phx Hangup
$icon_mut Mute $icon_mut Mute
@@ -248,7 +209,18 @@ EOF
case "$PICKED" in case "$PICKED" in
"$icon_phn Pickup") "$icon_phn Pickup")
pickup "$1" if ! sxmo_modemaudio.sh setup_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to setup call audio"
return 1
fi
if ! pickup "$1"; then
sxmo_notify_user.sh --urgency=critical "We failed to pickup the call"
sxmo_modemaudio.sh reset_audio
return 1
fi
incall_menu
;; ;;
"$icon_phx Hangup") "$icon_phx Hangup")
hangup "$1" hangup "$1"
@@ -257,16 +229,15 @@ EOF
mute "$1" mute "$1"
;; ;;
esac esac
rm -f "$SXMO_NOTIFDIR/incomingcall_${1}_notification"* #there may be multiple actionable notification for one call ) & # To be killeable
wait
} }
# do not duplicate proximity lock if already running killed() {
if sxmo_daemons.sh running proximity_lock -q; then sxmo_dmenu.sh close
LOCKALREADYRUNNING=1 }
else if [ "$1" = "incall_menu" ] || [ "$1" = "incoming_call_menu" ]; then
sxmo_daemons.sh start proximity_lock sxmo_proximitylock.sh trap 'killed' TERM INT
fi fi
"$@" & "$@"
MAINPID="$!"
wait $MAINPID

View File

@@ -4,16 +4,11 @@
# include common definitions # include common definitions
# shellcheck source=scripts/core/sxmo_common.sh # shellcheck source=scripts/core/sxmo_common.sh
. "$(dirname "$0")/sxmo_common.sh" . sxmo_common.sh
set -e set -e
err() { dial_number() {
sxmo_notify_user.sh "$1"
exit 1
}
dialnumber() {
NUMBER="$1" NUMBER="$1"
CLEANEDNUMBER="$(pn find ${DEFAULT_COUNTRY:+-c "$DEFAULT_COUNTRY"} "$1")" CLEANEDNUMBER="$(pn find ${DEFAULT_COUNTRY:+-c "$DEFAULT_COUNTRY"} "$1")"
@@ -26,18 +21,39 @@ EOF
fi fi
sxmo_log "Attempting to dial: $NUMBER" sxmo_log "Attempting to dial: $NUMBER"
CALLID="$(
if ! CALLID="$(
mmcli -m any --voice-create-call "number=$NUMBER" | mmcli -m any --voice-create-call "number=$NUMBER" |
grep -Eo "Call/[0-9]+" | grep -Eo "Call/[0-9]+" |
grep -oE "[0-9]+" grep -oE "[0-9]+"
)" || err "Unable to initiate call, is your modem working?" )"; then
sxmo_notify_user.sh --urgency=critical "We failed to initiate call"
return 1
fi
find "$XDG_RUNTIME_DIR" -name "$CALLID.*" -delete 2>/dev/null # we cleanup all dangling event files find "$XDG_RUNTIME_DIR" -name "$CALLID.*" -delete 2>/dev/null # we cleanup all dangling event files
sxmo_log "Starting call with CALLID: $CALLID" sxmo_log "Starting call with CALLID: $CALLID"
exec sxmo_modemcall.sh pickup "$CALLID"
if ! sxmo_modemaudio.sh setup_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to setup call audio"
return 1
fi
if ! sxmo_modemcall.sh pickup "$CALLID"; then
sxmo_modemaudio.sh reset_audio
return 1
fi
# do not duplicate proximity lock if already running
if ! sxmo_daemons.sh running proximity_lock -q; then
sxmo_daemons.sh start calling_proximity_lock sxmo_proximitylock.sh
fi
sxmo_daemons.sh start incall_menu sxmo_modemcall.sh incall_menu
} }
dialmenu() { dial_menu() {
# Initial menu with recently contacted people # Initial menu with recently contacted people
NUMBER="$( NUMBER="$(
cat <<EOF | sxmo_dmenu_with_kb.sh -p Number -i cat <<EOF | sxmo_dmenu_with_kb.sh -p Number -i
@@ -62,11 +78,11 @@ EOF
exit 0 exit 0
fi fi
dialnumber "$NUMBER" dial_number "$NUMBER"
} }
if [ -n "$1" ]; then if [ -n "$1" ]; then
dialnumber "$1" dial_number "$1"
else else
dialmenu dial_menu
fi fi

View File

@@ -204,7 +204,7 @@ readtextmenu() {
fi fi
} }
if [ "2" != "$#" ]; then if [ -z "$*" ]; then
readtextmenu readtextmenu
else else
"$@" "$@"