Files
sxmo-utils/scripts/modem/sxmo_modem.sh
Peter John Hartman cd394d3875 Previously sms messages were not guaranteed to be formatted with the
country code if the carrier didn't provide it. This forces it to use the
DEFAULT_COUNTRY variable if set.

(Thanks to Kyle Eveleth.)
2023-04-02 23:05:01 -05:00

268 lines
9.2 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
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
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
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
#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
#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
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_notificationwrite.sh \
random \
"TERMNAME='$NOTIFMSG' sxmo_terminal.sh sh -c \"echo '$NOTIFMSG at $(date)' && read\"" \
none \
"Missed $icon_phn $CONTACT ($FINISHEDNUMBER)"
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 proximity_lock
if ! sxmo_modemaudio.sh reset_audio; then
sxmo_notify_user.sh --urgency=critical "We failed to reset call audio"
fi
else
# Or refresh the menu
sxmo_daemons.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 cut -f1 "$SXMO_BLOCKFILE" 2>/dev/null | grep -q "^$INCOMINGNUMBER$"; 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_hook_ring.sh "$CONTACTNAME" &
mkdir -p "$SXMO_LOGDIR"
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
sxmo_daemons.sh start proximity_lock sxmo_proximitylock.sh
# 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)"
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" -K)"
# 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="$(echo "$TEXTDATA" | grep sms.content.text | sed -E 's/^sms\.content\.text\s+:\s+//')"
NUM="$(
echo "$TEXTDATA" |
grep sms.content.number |
sed -E 's/^sms\.content\.number\s+:\s+//'
)"
NUM="$(cleanupnumber "$NUM")"
TIME="$(echo "$TEXTDATA" | grep sms.properties.timestamp | sed -E 's/^sms\.properties\.timestamp\s+:\s+//')"
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"
mmcli -m any --messaging-delete-sms="$TEXTID"
CONTACTNAME=$(sxmo_contacts.sh --name-or-number "$NUM")
if [ -z "$SXMO_DISABLE_SMS_NOTIFS" ]; then
sxmo_notificationwrite.sh \
random \
"sxmo_hook_tailtextlog.sh '$NUM'" \
"$SXMO_LOGDIR/$NUM/sms.txt" \
"$CONTACTNAME: $TEXT"
fi
if grep -q screenoff "$SXMO_STATE"; then
sxmo_hook_lock.sh
fi
sxmo_hook_sms.sh "$CONTACTNAME" "$TEXT"
done
}
sxmo_wakelock.sh lock modem_used 30s
"$@"
sxmo_wakelock.sh unlock modem_used