- Deployed Yggdrasil on master (aarch64) and clone (x86_64) - Connected to 2 public peers + LAN multicast auto-discovery - Bidirectional ping6 and SSH over Yggdrasil working - Fixed firewall zones: device="ygg0" required for nftables - IPv6: master 201:e4d4:..., clone 201:a9d8:... - Marks v1.1+ Yggdrasil overlay as complete Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
346 lines
12 KiB
Bash
Executable File
346 lines
12 KiB
Bash
Executable File
#!/bin/sh
|
|
# RPCD backend for VoIP PBX
|
|
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
VOIPCTL="/usr/sbin/voipctl"
|
|
|
|
case "$1" in
|
|
list)
|
|
cat <<JSON
|
|
{
|
|
"status": {},
|
|
"extensions": {},
|
|
"calls": {},
|
|
"voicemails": {},
|
|
"trunk_status": {},
|
|
"install": {},
|
|
"start": {},
|
|
"stop": {},
|
|
"restart": {},
|
|
"reload": {},
|
|
"ext_add": {"number": "str", "name": "str", "password": "str"},
|
|
"ext_del": {"number": "str"},
|
|
"ext_passwd": {"number": "str", "password": "str"},
|
|
"call_originate": {"from_ext": "str", "to_number": "str"},
|
|
"call_hangup": {"channel": "str"},
|
|
"trunk_add": {"provider": "str"},
|
|
"trunk_test": {},
|
|
"vm_delete": {"extension": "str", "msg_id": "str"},
|
|
"rec_status": {},
|
|
"rec_enable": {},
|
|
"rec_disable": {},
|
|
"rec_list": {"date": "str"},
|
|
"rec_delete": {"filename": "str"},
|
|
"rec_download": {"filename": "str"},
|
|
"rec_cleanup": {"days": "int"}
|
|
}
|
|
JSON
|
|
;;
|
|
call)
|
|
case "$2" in
|
|
status)
|
|
$VOIPCTL status
|
|
;;
|
|
extensions)
|
|
. /lib/functions.sh
|
|
|
|
_add_ext() {
|
|
local section="$1"
|
|
local name context vm
|
|
config_get name "$section" name
|
|
config_get context "$section" context "internal"
|
|
config_get vm "$section" voicemail "0"
|
|
local number="${section#ext_}"
|
|
|
|
json_add_object
|
|
json_add_string "number" "$number"
|
|
json_add_string "name" "$name"
|
|
json_add_string "context" "$context"
|
|
json_add_boolean "voicemail" "$vm"
|
|
json_close_object
|
|
}
|
|
|
|
json_init
|
|
json_add_array "extensions"
|
|
config_load voip
|
|
config_foreach _add_ext extension
|
|
json_close_array
|
|
json_dump
|
|
;;
|
|
calls)
|
|
if lxc-info -n voip -s 2>/dev/null | grep -q "RUNNING"; then
|
|
output=$(lxc-attach -n voip -- asterisk -rx "core show channels concise" 2>/dev/null)
|
|
json_init
|
|
json_add_array "calls"
|
|
|
|
echo "$output" | while IFS='!' read -r channel context ext prio state app data caller connected duration; do
|
|
[ -z "$channel" ] && continue
|
|
json_add_object
|
|
json_add_string "channel" "$channel"
|
|
json_add_string "state" "$state"
|
|
json_add_string "caller" "$caller"
|
|
json_add_string "connected" "$connected"
|
|
json_add_string "duration" "$duration"
|
|
json_close_object
|
|
done
|
|
|
|
json_close_array
|
|
json_dump
|
|
else
|
|
echo '{"calls":[]}'
|
|
fi
|
|
;;
|
|
voicemails)
|
|
json_init
|
|
json_add_array "voicemails"
|
|
|
|
find /srv/voip/voicemail/default -name "msg*.txt" 2>/dev/null | while read -r txtfile; do
|
|
ext=$(echo "$txtfile" | sed -n 's|.*/\([0-9]*\)/msg.*|\1|p')
|
|
id=$(basename "$txtfile" .txt)
|
|
caller=$(grep "^callerid=" "$txtfile" 2>/dev/null | cut -d'=' -f2)
|
|
date=$(grep "^origdate=" "$txtfile" 2>/dev/null | cut -d'=' -f2)
|
|
duration=$(grep "^duration=" "$txtfile" 2>/dev/null | cut -d'=' -f2)
|
|
|
|
json_add_object
|
|
json_add_string "extension" "$ext"
|
|
json_add_string "id" "$id"
|
|
json_add_string "caller" "$caller"
|
|
json_add_string "date" "$date"
|
|
json_add_int "duration" "${duration:-0}"
|
|
json_close_object
|
|
done
|
|
|
|
json_close_array
|
|
json_dump
|
|
;;
|
|
trunk_status)
|
|
if lxc-info -n voip -s 2>/dev/null | grep -q "RUNNING"; then
|
|
output=$(lxc-attach -n voip -- asterisk -rx "pjsip show registrations" 2>/dev/null)
|
|
registered=0
|
|
echo "$output" | grep -q "Registered" && registered=1
|
|
|
|
json_init
|
|
json_add_boolean "registered" "$registered"
|
|
json_add_string "details" "$output"
|
|
json_dump
|
|
else
|
|
echo '{"registered":false,"details":"Container not running"}'
|
|
fi
|
|
;;
|
|
install)
|
|
output=$($VOIPCTL install 2>&1)
|
|
rc=$?
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
start)
|
|
output=$($VOIPCTL start 2>&1)
|
|
rc=$?
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
stop)
|
|
output=$($VOIPCTL stop 2>&1)
|
|
rc=$?
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
restart)
|
|
output=$($VOIPCTL restart 2>&1)
|
|
rc=$?
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
reload)
|
|
output=$($VOIPCTL reload 2>&1)
|
|
rc=$?
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
ext_add)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var number number
|
|
json_get_var name name
|
|
json_get_var password password
|
|
|
|
output=$($VOIPCTL ext add "$number" "$name" "$password" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
ext_del)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var number number
|
|
|
|
output=$($VOIPCTL ext del "$number" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
ext_passwd)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var number number
|
|
json_get_var password password
|
|
|
|
output=$($VOIPCTL ext passwd "$number" "$password" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
call_originate)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var from_ext from_ext
|
|
json_get_var to_number to_number
|
|
|
|
output=$($VOIPCTL call "$from_ext" "$to_number" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
call_hangup)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var channel channel
|
|
|
|
output=$($VOIPCTL hangup "$channel" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
trunk_test)
|
|
output=$($VOIPCTL trunk test 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
vm_delete)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var extension extension
|
|
json_get_var msg_id msg_id
|
|
|
|
output=$($VOIPCTL vm delete "$extension" "$msg_id" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
rec_status)
|
|
$VOIPCTL rec status
|
|
;;
|
|
rec_enable)
|
|
output=$($VOIPCTL rec enable 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
rec_disable)
|
|
output=$($VOIPCTL rec disable 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
rec_list)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var date date
|
|
|
|
$VOIPCTL rec list-json "$date"
|
|
;;
|
|
rec_delete)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var filename filename
|
|
|
|
output=$($VOIPCTL rec delete "$filename" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
rec_download)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var filename filename
|
|
|
|
path=$($VOIPCTL rec download "$filename" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "path" "$path"
|
|
# Also provide base64 content for small files
|
|
size=$(stat -c%s "$path" 2>/dev/null || echo 0)
|
|
if [ "$size" -lt 5000000 ]; then
|
|
# Base64 encode files under 5MB
|
|
b64=$(base64 -w 0 "$path" 2>/dev/null)
|
|
json_add_string "content" "$b64"
|
|
fi
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$path"
|
|
fi
|
|
json_dump
|
|
;;
|
|
rec_cleanup)
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var days days
|
|
|
|
[ -z "$days" ] && days=30
|
|
output=$($VOIPCTL rec cleanup "$days" 2>&1)
|
|
rc=$?
|
|
|
|
json_init
|
|
json_add_boolean "success" "$((rc == 0))"
|
|
json_add_string "output" "$output"
|
|
json_dump
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|