#!/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" set -e vid_to_number() { mmcli -m any -o "$1" -K | \ grep call.properties.number | \ cut -d ':' -f2 | \ tr -d ' ' } log_event() { EVT_HANDLE="$1" EVT_VID="$2" NUM="$(vid_to_number "$EVT_VID")" TIME="$(date +%FT%H:%M:%S%z)" mkdir -p "$SXMO_LOGDIR" printf %b "$TIME\t$EVT_HANDLE\t$NUM\n" >> "$SXMO_LOGDIR/modemlog.tsv" } pickup() { CALLID="$1" NUM="$(vid_to_number "$CALLID" 2>/dev/null || true)" DIRECTION="$( (mmcli -m any -o "$CALLID" -K 2>/dev/null || mmcli -o "$CALLID" -K 2>/dev/null || mmcli --voice-status -o "$CALLID" -K 2>/dev/null) | grep call.properties.direction | cut -d: -f2 | tr -d " " )" case "$DIRECTION" in outgoing) if ! sxmo_modemaudio.sh setup_audio; then sxmo_notify_user.sh --urgency=critical "We failed to setup call audio" return 1 fi if ! mmcli -m any -o "$CALLID" --start; then sxmo_notify_user.sh --urgency=critical "We failed to start the call" return 1 fi touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall" log_event "call_start" "$CALLID" if command -v xcallscreen >/dev/null 2>&1; then xcallscreen outgoing "$CALLID" "$NUM" >/dev/null 2>&1 || true else sxmo_notify_user.sh "Started call" fi ;; incoming) sxmo_log "Invoking pickup hook" sxmo_hook_pickup.sh if ! sxmo_modemaudio.sh setup_audio; then sxmo_notify_user.sh --urgency=critical "We failed to setup call audio" return 1 fi if ! mmcli -m any -o "$CALLID" --accept; then sxmo_notify_user.sh --urgency=critical "We failed to accept the call" return 1 fi touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall" log_event "call_pickup" "$CALLID" if command -v xcallscreen >/dev/null 2>&1; then xcallscreen active "$CALLID" "$NUM" >/dev/null 2>&1 || true else sxmo_notify_user.sh "Picked up call" fi ;; *) sxmo_notify_user.sh --urgency=critical "Couldn't initialize call with callid <$CALLID>; unknown direction <$DIRECTION>" rm "$XDG_RUNTIME_DIR/sxmo_calls/"* 2>/dev/null || true rm -f "$XDG_RUNTIME_DIR"/sxmo.ring.pid 2>/dev/null rm -f "$SXMO_NOTIFDIR"/incomingcall* 2>/dev/null if command -v xcallscreen >/dev/null 2>&1; then xcallscreen ended >/dev/null 2>&1 || true fi return 1 ;; esac } hangup() { CALLID="$1" if [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall" ] || \ [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall" ]; then rm -f "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall" \ "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall" touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.hangedupcall" log_event "call_hangup" "$CALLID" sxmo_log "sxmo_modemcall: Invoking hangup hook" sxmo_hook_hangup.sh else # this call was never picked up and hung up immediately, so it is a discarded call touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.discardedcall" log_event "call_discard" "$CALLID" sxmo_log "sxmo_modemcall: Invoking discard hook" sxmo_hook_discard.sh fi if ! mmcli -m any -o "$CALLID" --hangup; then # we ignore already closed calls if list_active_calls | grep -q "/$CALLID "; then sxmo_notify_user.sh --urgency=critical "We failed to hangup the call" return 1 fi fi } # We shallow muted/blocked and terminated calls 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/sxmo_calls/${CALLID}.mutedring" ]; then continue # we shallow muted calls fi printf "%s\n" "$line" done } incall_menu() { if command -v xcallscreen >/dev/null 2>&1; then ACTIVE_LINE="$(list_active_calls | head -n1)" if [ -n "$ACTIVE_LINE" ]; then CALLID="$(printf %s "$ACTIVE_LINE" | cut -d" " -f1 | xargs basename)" NUMBER="$(vid_to_number "$CALLID" 2>/dev/null || true)" case "$ACTIVE_LINE" in *"(ringing-in)"*) xcallscreen incoming "$CALLID" "$NUMBER" >/dev/null 2>&1 || true ;; *"(dialing)"*|*"(ringing-out)"*) xcallscreen outgoing "$CALLID" "$NUMBER" >/dev/null 2>&1 || true ;; *) xcallscreen active "$CALLID" "$NUMBER" >/dev/null 2>&1 || true ;; esac else xcallscreen >/dev/null 2>&1 || true fi return 0 fi } mute() { CALLID="$1" # this signals that we muted this ring touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.mutedring" sxmo_log "Invoking mute_ring hook" sxmo_hook_mute_ring.sh log_event "ring_mute" "$1" } incoming_call_menu() { NUMBER="$(vid_to_number "$1")" NUMBER="$(sxmo_modem.sh cleanupnumber "$NUMBER")" if command -v xcallscreen >/dev/null 2>&1; then xcallscreen incoming "$1" "$NUMBER" >/dev/null 2>&1 || true return 0 fi } killed() { sxmo_dmenu.sh close } if [ "$1" = "incall_menu" ] || [ "$1" = "incoming_call_menu" ]; then trap 'killed' TERM INT fi "$@"