Files
sxmo-utils/scripts/modem/sxmo_modem.sh
Roberto Castagnola ae8c63508a Add hook for blocking numbers
Signed-off-by: Roberto Castagnola <roberto.castagnola@gmail.com>
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2024-10-25 18:49:37 +02:00

287 lines
9.6 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# include common definitions
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
# We use this directory to store states, so it must exist
mkdir -p "$XDG_RUNTIME_DIR/sxmo_calls"
stderr() {
sxmo_log "$*"
}
cleanupnumber() {
if pnc valid "$1"; then
echo "$1"
return
fi
REFORMATTED="$(pnc find ${DEFAULT_COUNTRY:+-c "$DEFAULT_COUNTRY"} "$1")"
if [ -n "$REFORMATTED" ]; then
echo "$REFORMATTED"
return
fi
echo "$1"
}
checkforfinishedcalls() {
exec 3<> "${XDG_RUNTIME_DIR:-HOME}/sxmo_modem.checkforfinishedcalls.lock"
flock -x 3
#find all finished calls
for FINISHEDCALLID in $(
mmcli -m any --voice-list-calls |
grep terminated |
grep -oE "Call\/[0-9]+" |
cut -d'/' -f2
); do
FINISHEDNUMBER="$(sxmo_modemcall.sh vid_to_number "$FINISHEDCALLID")"
FINISHEDNUMBER="$(cleanupnumber "$FINISHEDNUMBER")"
mmcli -m any --voice-delete-call "$FINISHEDCALLID"
rm -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.monitoredcall"
CONTACT="$(sxmo_contacts.sh --name-or-number "$FINISHEDNUMBER")"
TIME="$(date +%FT%H:%M:%S%z)"
mkdir -p "$SXMO_LOGDIR"
if [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.discardedcall" ]; then
#this call was discarded
STATE=discarded
sxmo_notify_user.sh "Call with $CONTACT terminated"
stderr "Discarded call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.pickedupcall" ]; then
#this call was picked up
STATE=pickedup
sxmo_notify_user.sh "Call with $CONTACT terminated"
stderr "Finished call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.hangedupcall" ]; then
#this call was hung up by the user
STATE=wehangedup
sxmo_notify_user.sh "Call with $CONTACT terminated"
stderr "Finished call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.initiatedcall" ]; then
STATE=theyhangedup
#this call was hung up by the contact
sxmo_notify_user.sh "Call with $CONTACT terminated"
stderr "Finished call from $FINISHEDNUMBER"
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.mutedring" ]; then
STATE=muted
#this ring was muted up
stderr "Muted ring from $FINISHEDNUMBER"
printf %b "$TIME\tring_muted\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
else
#this is a missed call
# Add a notification for every missed call
STATE=missed
NOTIFMSG="Missed call from $CONTACT ($FINISHEDNUMBER)"
stderr "$NOTIFMSG"
printf %b "$TIME\tcall_missed\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
stderr "Invoking missed call hook (async)"
sxmo_hook_missed_call.sh "$CONTACT" &
sxmo_notifs.sh new \
-g "incoming-call-$FINISHEDNUMBER" \
"TERMNAME='$NOTIFMSG' sxmo_terminal.sh sh -c \"echo '$NOTIFMSG at $(date)' && read\"" \
"Missed $icon_phn $CONTACT ($FINISHEDNUMBER)"
fi
# If it was the last call
if ! sxmo_modemcall.sh list_active_calls | grep -q .; then
# Cleanup
if [ "$STATE" != muted ]; then
sxmo_vibrate 1000 "${SXMO_VIBRATE_STRENGTH:-1}" &
fi
sxmo_jobs.sh stop incall_menu
sxmo_jobs.sh stop proximity_lock
sxmo_hook_statusbar.sh state &
if sxmo_modemaudio.sh is_call_audio_mode; then
if ! sxmo_modemaudio.sh reset_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to reset call audio"
fi
fi
sxmo_hook_after_call.sh
else
# Or refresh the menu
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu
fi
done
}
checkforincomingcalls() {
VOICECALLID="$(
mmcli -m any --voice-list-calls -a |
grep -Eo '[0-9]+ incoming \(ringing-in\)' |
grep -Eo '[0-9]+'
)"
[ -z "$VOICECALLID" ] && return
[ -f "$XDG_RUNTIME_DIR/sxmo_calls/${VOICECALLID}.monitoredcall" ] && return # prevent multiple rings
rm "$XDG_RUNTIME_DIR/sxmo_calls/$VOICECALLID."* 2>/dev/null # we cleanup all dangling event files
touch "$XDG_RUNTIME_DIR/sxmo_calls/${VOICECALLID}.monitoredcall" #this signals that we handled the call
# Determine the incoming phone number
stderr "Incoming Call..."
INCOMINGNUMBER=$(sxmo_modemcall.sh vid_to_number "$VOICECALLID")
INCOMINGNUMBER="$(cleanupnumber "$INCOMINGNUMBER")"
TIME="$(date +%FT%H:%M:%S%z)"
if sxmo_hook_block_call.sh "$INCOMINGNUMBER" 2>/dev/null; then
stderr "BLOCKED call from number: $VOICECALLID"
sxmo_modemcall.sh mute "$VOICECALLID"
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_BLOCKDIR/modemlog.tsv"
else
stderr "Invoking ring hook (async)"
CONTACTNAME=$(sxmo_contacts.sh --name-or-number "$INCOMINGNUMBER")
sxmo_jobs.sh start ringing sxmo_hook_ring.sh "$CONTACTNAME"
mkdir -p "$SXMO_LOGDIR"
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
sxmo_jobs.sh start proximity_lock sxmo_proximitylock.sh
sxmo_hook_statusbar.sh state &
# 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_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu
else
# Or fire the incomming call menu
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incoming_call_menu "$VOICECALLID"
fi
stderr "Call from number: $INCOMINGNUMBER (VOICECALLID: $VOICECALLID)"
fi
}
# this function is called in the modem hook when the modem registers
checkforstucksms() {
stuck_messages="$(mmcli -m any --messaging-list-sms)"
if ! echo "$stuck_messages" | grep -q "^No sms messages were found"; then
sxmo_notify_user.sh "WARNING: $(echo "$stuck_messages" | wc -l) stuck sms found. Run sxmo_modem.sh checkforstucksms view to view or delete to delete."
case "$1" in
"delete")
mmcli -m any --messaging-list-sms | while read -r line; do
sms_number="$(echo "$line" | cut -d'/' -f6 | cut -d' ' -f1)"
sxmo_log "Deleting sms $sms_number"
mmcli -m any --messaging-delete-sms="$sms_number"
done
;;
"view")
mmcli -m any --messaging-list-sms | while read -r line; do
sms_number="$(echo "$line" | cut -d'/' -f6 | cut -d' ' -f1)"
mmcli -m any -s "$sms_number" -K
done
;;
esac
fi
}
checkfornewtexts() {
exec 3<> "${XDG_RUNTIME_DIR:-HOME}/sxmo_modem.checkfornewtexts.lock"
flock -x 3
TEXTIDS="$(
mmcli -m any --messaging-list-sms |
grep -Eo '/SMS/[0-9]+ \(received\)' |
grep -Eo '[0-9]+'
)"
echo "$TEXTIDS" | grep -v . && return
# Loop each textid received and read out the data into appropriate logfile
for TEXTID in $TEXTIDS; do
TEXTDATA="$(mmcli -m any -s "$TEXTID" -J)"
# SMS with no TEXTID is an SMS WAP (I think). So skip.
if [ -z "$TEXTDATA" ]; then
stderr "Received an empty SMS (TEXTID: $TEXTID). I will assume this is an MMS."
printf %b "$(date +%FT%H:%M:%S%z)\tdebug_mms\tNULL\tEMPTY (TEXTID: $TEXTID)\n" >> "$SXMO_LOGDIR/modemlog.tsv"
if [ -f "${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}/mms" ]; then
continue
else
stderr "WARNING: mmsdtng not found or unconfigured, treating as normal sms."
fi
fi
TEXT="$(printf %s "$TEXTDATA" | jq -r .sms.content.text)"
NUM="$(printf %s "$TEXTDATA" | jq -r .sms.content.number)"
NUM="$(cleanupnumber "$NUM")"
TIME="$(printf %s "$TEXTDATA" | jq -r .sms.properties.timestamp)"
TIME="$(date +%FT%H:%M:%S%z -d "$TIME")"
# Note: this will *not* block MMS, since we have to unpack the phone numbers for an MMS
# later.
#
# TODO: a user *could* block the sms wap number (which would be user error). But then
# the mms would not be processed. So probably give a warning here if the user has blocked
# the sms wap number?
if cut -f1 "$SXMO_BLOCKFILE" 2>/dev/null | grep -q "^$NUM$"; then
mkdir -p "$SXMO_BLOCKDIR/$NUM"
stderr "BLOCKED text from number: $NUM (TEXTID: $TEXTID)"
sxmo_hook_smslog.sh "recv" "$NUM" "$NUM" "$TIME" "$TEXT" >> "$SXMO_BLOCKDIR/$NUM/sms.txt"
printf %b "$TIME\trecv_txt\t$NUM\t${#TEXT} chars\n" >> "$SXMO_BLOCKDIR/modemlog.tsv"
mmcli -m any --messaging-delete-sms="$TEXTID"
continue
fi
if [ "$TEXT" = "--" ] && [ ! "$NUM" = "+223344556678" ]; then
stderr "Text from $NUM (TEXTID: $TEXTID) with '--'. I will assume this is an MMS."
printf %b "$TIME\tdebug_mms\t$NUM\t$TEXT\n" >> "$SXMO_LOGDIR/modemlog.tsv"
if [ -f "${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}/mms" ]; then
continue
else
stderr "WARNING: mmsdtng not found or unconfigured, treating as normal sms."
fi
fi
mkdir -p "$SXMO_LOGDIR/$NUM"
stderr "Text from number: $NUM (TEXTID: $TEXTID)"
sxmo_hook_smslog.sh "recv" "$NUM" "$NUM" "$TIME" "$TEXT" >> "$SXMO_LOGDIR/$NUM/sms.txt"
printf %b "$TIME\trecv_txt\t$NUM\t${#TEXT} chars\n" >> "$SXMO_LOGDIR/modemlog.tsv"
tries=1
while ! mmcli -m any --messaging-delete-sms="$TEXTID";
do
if [ $tries -gt 5 ];
then
break
fi
echo "Failed to delete text $TEXTID. Will retry"
sleep 3
tries=$((tries+1))
done
CONTACTNAME=$(sxmo_contacts.sh --name-or-number "$NUM")
if [ -z "$SXMO_DISABLE_SMS_NOTIFS" ]; then
sxmo_notifs.sh new \
-g "incoming-message-$NUM" \
"sxmo_hook_tailtextlog.sh '$NUM'" \
"$CONTACTNAME: $TEXT"
fi
if sxmo_state.sh get | grep -q screenoff; then
sxmo_state.sh set lock
fi
sxmo_hook_sms.sh "$CONTACTNAME" "$TEXT"
done
}
sxmo_wakelock.sh lock sxmo_modem_used 30s
"$@"
sxmo_wakelock.sh unlock sxmo_modem_used