Files
sxmo-utils/scripts/modem/sxmo_mms.sh
Willow Barraco ef8254681c Unify sxmo state switch and ensure consistency
If two power handler trigger at the same time, the current behavior is
that we switch two time to the same target state.

This move the flock to a central script that make sure only one switch
is ocurring at the same time. Concurrent switch will wait for the
previous one to finish before guessing the new target state.

This also refactorise the sxmo_proximitylock.sh to make it simple,
stripping the two related proximitylock and proximityunlock states.

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
Signed-off-by: Anjandev Momi <anjan@momi.ca>
2023-09-09 12:47:04 -07:00

218 lines
7.2 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# This handles most of the mms-related tasks. Note that some functions, e.g.,
# checkforlostmms() can be run from the commandline.
# 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
info() {
sxmo_log "$*"
printf "%s\n" "$*" # some functions run from commandline
}
# We attempt to delete all objects from mmsd-tng after we receive/send them.
# However, sometimes (e.g., a crash) there are stuck or "lost" mms, i.e.,
# mmsd-tng still has objects in its database. Often mmsd-tng will resolve this
# issue itself, given enough time. If you pass --force to this function, it will
# process/delete them.
checkforlostmms() {
# generate a list of all messages on the server
if ! RES="$(dbus-send --dest=org.ofono.mms --print-reply /org/ofono/mms/modemmanager org.ofono.mms.Service.GetMessages)"; then
info "mmsdtng is busy or something is broken."
return 1
fi
ALL_MMS_TEMP="$(mktemp)"
printf "%s\n" "$RES" | grep "object path" | cut -d'"' -f2 | rev | cut -d'/' -f1 | rev | sort -u > "$ALL_MMS_TEMP"
count="$(wc -l < "$ALL_MMS_TEMP")"
# loop through messages and report (or process if --force) them we
# delete messages with status draft, and process those with sent and
# received
if [ "$count" -gt 0 ]; then
sxmo_notify_user.sh "WARNING: Found $count unprocessed mms. Run $0 checkforlostmms --force to process them."
info "Found the following $count unprocessed mms:"
while read -r line; do
MESSAGE_STATUS="$(mmsctl -M -o "/org/ofono/mms/modemmanager/$line" | jq -r '.attrs.Status')"
case "$MESSAGE_STATUS" in
sent|received)
info "* $line (status:$MESSAGE_STATUS)."
if [ "$1" = "--force" ]; then
info "Processing."
processmms "/org/ofono/mms/modemmanager/$line"
fi
;;
draft|expired)
info "* $line (status:$MESSAGE_STATUS)."
if [ "$1" = "--force" ]; then
info "Deleting."
dbus-send --dest=org.ofono.mms --print-reply "/org/ofono/mms/modemmanager/$line" org.ofono.mms.Message.Delete
fi
;;
*)
info "* $line (status:$MESSAGE_STATUS). WARNING: UNKNOWN STATUS!"
;;
esac
done < "$ALL_MMS_TEMP"
if [ "$1" = "--force" ]; then
info "Finished."
else
info "Run $0 checkforlostmms --force to process (if sent or received) or delete (if expired or draft)."
fi
fi
rm "$ALL_MMS_TEMP"
}
# extract mms payload
extractmmsattachement() {
jq -r '.attrs.Attachments[] | join(",")' | while read -r aline; do
ACTYPE="$(printf %s "$aline" | cut -d',' -f2 | cut -d';' -f1 | sed 's|^Content-Type: "\(.*\)"$|\1|')"
AOFFSET="$(printf %s "$aline" | cut -d',' -f4)"
ASIZE="$(printf %s "$aline" | cut -d',' -f5)"
case "$ACTYPE" in
text/plain)
DATA_EXT="txt"
;;
image/gif)
DATA_EXT="gif"
;;
image/png)
DATA_EXT="png"
;;
image/jpeg)
DATA_EXT="jpeg"
;;
video/*)
DATA_EXT="video"
;;
*)
DATA_EXT="bin"
;;
esac
MMS_BASE_DIR="${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}"
if [ -f "$MMS_BASE_DIR/$MMS_FILE" ]; then
OUTFILE="$MMS_FILE.$DATA_EXT"
count=0
while [ -f "$SXMO_LOGDIR/$LOGDIRNUM/attachments/$OUTFILE" ]; do
OUTFILE="$MMS_FILE-$count.$DATA_EXT"
count="$((count+1))"
done
dd skip="$AOFFSET" count="$ASIZE" \
if="$MMS_BASE_DIR/$MMS_FILE" \
of="$SXMO_LOGDIR/$LOGDIRNUM/attachments/$OUTFILE" \
bs=1 >/dev/null 2>&1
fi
done
}
# We process both sent and received mms here.
processmms() {
MESSAGE_PATH="$1"
MESSAGE="$(mmsctl -M -o "$MESSAGE_PATH")"
MMS_FILE="$(printf %s "$MESSAGE_PATH" | rev | cut -d'/' -f1 | rev)"
STATUS="$(printf %s "$MESSAGE" | jq -r '.attrs.Status')" # sent or received
if [ "$STATUS" = "received" ]; then
STATUS="recv"
elif [ "$STATUS" = "sent" ]; then
STATUS="sent"
else
sxmo_log "Warning: unknown status: $STATUS on $MESSAGE_PATH."
return
fi
sxmo_log "Processing $STATUS mms ($MESSAGE_PATH)."
DATE="$(printf %s "$MESSAGE" | jq -r '.attrs.Date')"
DATE="$(date +%FT%H:%M:%S%z -d "$DATE")"
# everyone to whom the message was sent (including you). This will be a
# string e.g. +12345678+123455+39898988
RECIPIENTS="$(printf %s "$MESSAGE" | jq -r '.attrs.Recipients | join("")')"
MYNUM="$(printf %s "$MESSAGE" | jq -r '.attrs."Modem Number"')"
if [ -z "$MYNUM" ]; then
sxmo_log "The mms file does not have a 'Modem Number'. Falling back to Me contact."
MYNUM="$(sxmo_contacts.sh --me)"
if [ -z "$MYNUM" ]; then
sxmo_log "You do not have a Me contact. Falling back to fake number: +12345670000"
MYNUM="+12345670000"
fi
fi
SENDER="$(printf %s "$MESSAGE" | jq -r '.attrs.Sender')" # note this will be null if I am the sender
sxmo_debug "SENDER: $SENDER MYNUM: $MYNUM RECIPIENTS: $RECIPIENTS"
sxmo_debug "MESSAGE: $MESSAGE"
[ "$SENDER" = "null" ] && SENDER="$MYNUM"
# Generates a unique LOGDIRNUM: all the recipients, plus the sender, minus you
LOGDIRNUM="$(printf %s%s "$RECIPIENTS" "$SENDER" | xargs pnc find | grep -v "^$MYNUM$" | sort -u | grep . | xargs printf %s)"
# check if blocked
if cut -f1 "$SXMO_BLOCKFILE" 2>/dev/null | grep -q "^$LOGDIRNUM$"; then
sxmo_log "BLOCKED mms $LOGDIRNUM ($MMS_FILE)."
SXMO_LOGDIR="$SXMO_BLOCKDIR"
fi
mkdir -p "$SXMO_LOGDIR/$LOGDIRNUM/attachments"
printf "%s" "$MESSAGE" | extractmmsattachement
if [ -f "$SXMO_LOGDIR/$LOGDIRNUM/attachments/$MMS_FILE.txt" ]; then
TEXT="$(cat "$SXMO_LOGDIR/$LOGDIRNUM/attachments/$MMS_FILE.txt")"
rm -f "$SXMO_LOGDIR/$LOGDIRNUM/attachments/$MMS_FILE.txt"
else
TEXT="<Empty>"
fi
dbus-send --dest=org.ofono.mms --print-reply "$MESSAGE_PATH" org.ofono.mms.Message.Delete
sxmo_log "Finished processing $MMS_FILE. Deleting it."
printf "%s\t%s_mms\t%s\t%s\n" "$DATE" "$STATUS" "$LOGDIRNUM" "$MMS_FILE" >> "$SXMO_LOGDIR/modemlog.tsv"
sxmo_hook_smslog.sh "$STATUS" "$LOGDIRNUM" "$SENDER" "$DATE" "$TEXT" "$MMS_FILE" >> "$SXMO_LOGDIR/$LOGDIRNUM/sms.txt"
if [ "$STATUS" = "recv" ] && [ ! "$SXMO_LOGDIR" = "$SXMO_BLOCKDIR" ]; then
SENDER_NAME="$(sxmo_contacts.sh --name-or-number "$SENDER")"
# Determine if this is a GroupMMS
NUM_RECIPIENTS="$(printf "%s" "$RECIPIENTS" | xargs pnc find | wc -l)"
if [ -z "$SXMO_DISABLE_SMS_NOTIFS" ]; then
OPEN_ATTACHMENTS_CMD=
for attachment in "$SXMO_LOGDIR/$LOGDIRNUM/attachments/${MMS_FILE}".*; do
[ -f "$attachment" ] && OPEN_ATTACHMENTS_CMD="$(printf "sxmo_open.sh '%s'; %s" "$attachment" "$OPEN_ATTACHMENTS_CMD")"
done
sxmo_log "OPEN_ATTACHMENTS_CMD: $OPEN_ATTACHMENTS_CMD"
[ -n "$OPEN_ATTACHMENTS_CMD" ] && TEXT="$icon_att $TEXT"
[ "$NUM_RECIPIENTS" -gt 1 ] && TEXT="$icon_grp $TEXT"
sxmo_notificationwrite.sh \
random \
"${OPEN_ATTACHMENTS_CMD}sxmo_hook_tailtextlog.sh \"$LOGDIRNUM\"" \
"$SXMO_LOGDIR/$LOGDIRNUM/sms.txt" \
"$SENDER_NAME: $TEXT"
fi
if grep -q screenoff "$SXMO_STATE"; then
sxmo_state_switch.sh set lock
fi
if [ "$NUM_RECIPIENTS" -gt 1 ]; then
GROUP_NAME="$(sxmo_contacts.sh --name-or-number "$LOGDIRNUM")"
sxmo_hook_sms.sh "$SENDER_NAME" "$TEXT" "$MMS_FILE" "$GROUP_NAME"
else
sxmo_hook_sms.sh "$SENDER_NAME" "$TEXT" "$MMS_FILE"
fi
fi
}
sxmo_wakelock.sh lock sxmo_mms_processing 30s
"$@"
sxmo_wakelock.sh unlock sxmo_mms_processing