commit 4a0f2d370b15c6355bd7147864bcfe775ca3b823 Author: Pali Rohár Date: Tue Oct 1 19:01:56 2019 +0200 Initial commit diff --git a/admin_scripts/auto_answer.pl b/admin_scripts/auto_answer.pl new file mode 100755 index 0000000..3c078f9 --- /dev/null +++ b/admin_scripts/auto_answer.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::Telnet; +use Time::HiRes qw(usleep); + +die "Usage: $0 host pass line 0|1\n" unless @ARGV == 4; +my $host = $ARGV[0]; +my $pass = $ARGV[1]; +my $line = $ARGV[2]; +my $enable = $ARGV[3]; + +die "Line $line is not valid line number [1-6]\n" unless $line =~ /^[1-6]$/; + +my $t = Net::Telnet->new(Timeout => 3, Prompt => '/[^\n]*> $/'); + +$t->open($host); +$t->waitfor('/Password :$/'); +$t->print($pass); +$t->waitfor($t->prompt); + +my $failed; +my $skip; +my $auto_answer; + +for (1..10) { + if ($_ == 10) { + $failed = 1; + last; + } + + ($auto_answer) = map { /^auto_answer : ([0-9]+)$/ ? $1 : () } $t->cmd('show config'); + if ($enable and ($auto_answer & (1 << ($line - 1)))) { + do { print "auto_answer on $host is already enabled\n"; $skip = 1 } if $_ == 1; + last; + } elsif (not $enable and not ($auto_answer & (1 << ($line - 1)))) { + do { print "auto_answer on $host is already disabled\n"; $skip = 1 } if $_ == 1; + last; + } + + foreach ('open', 'key dir', 'key set', 'key set', 'key soft4', 'key set', 'key 6', 'key 8', "key $line", 'key soft1', 'key soft2', 'key set', 'close') { + $t->cmd("test $_"); + usleep 200_000; + } +} + +$t->print("exit"); +$t->close(); + +if ($failed) { + warn (($enable ? "enabling" : "disabling") . " auto_answer on $host failed\n"); + exit 1; +} else { + print ("auto_answer on $host is now " . ($enable ? "enabled" : "disabled") . "\n") unless $skip; + exit 0; +} diff --git a/admin_scripts/erase_config.pl b/admin_scripts/erase_config.pl new file mode 100755 index 0000000..008e8de --- /dev/null +++ b/admin_scripts/erase_config.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::Telnet; + +die "Usage: $0 host pass\n" unless @ARGV == 2; +my $host = $ARGV[0]; +my $pass = $ARGV[1]; + +my $t = Net::Telnet->new(Timeout => 3, Prompt => '/[^\n]*> $/'); + +$t->open($host); +$t->waitfor('/Password :$/'); +$t->print($pass); +$t->waitfor($t->prompt); + +$t->cmd('erase protflash'); + +# TODO: check if erase was allowed + +$t->print('exit'); +$t->close(); diff --git a/admin_scripts/force_reboot.pl b/admin_scripts/force_reboot.pl new file mode 100755 index 0000000..17a0bca --- /dev/null +++ b/admin_scripts/force_reboot.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::Telnet; + +die "Usage: $0 host pass\n" unless @ARGV == 2; +my $host = $ARGV[0]; +my $pass = $ARGV[1]; + +my $t = Net::Telnet->new(Timeout => 3, Prompt => '/[^\n]*> $/'); + +$t->open($host); +$t->waitfor('/Password :$/'); +$t->print($pass); +$t->waitfor($t->prompt); + +$t->print('reset'); + +# TODO: check if reset was allowed + +$t->close(); diff --git a/admin_scripts/list_errors.pl b/admin_scripts/list_errors.pl new file mode 100755 index 0000000..91b0483 --- /dev/null +++ b/admin_scripts/list_errors.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::Telnet; + +die "Usage: $0 host pass\n" unless @ARGV == 2; +my $host = $ARGV[0]; +my $pass = $ARGV[1]; + +my $t = Net::Telnet->new(Timeout => 3, Prompt => '/[^\n]*> $/'); + +$t->open($host); +$t->waitfor('/Password :$/'); +$t->print($pass); +$t->waitfor($t->prompt); + +print "$_\n" foreach grep !/^(?:Current Phone Status|--------------------|I100 No errors|)$/, map { /^[\x00-\x31\s]*(.*?)\s*$/s; $1 } $t->cmd('show status'); + +$t->print("exit"); +$t->close(); diff --git a/admin_scripts/normalize_volume.pl b/admin_scripts/normalize_volume.pl new file mode 100755 index 0000000..13d26a9 --- /dev/null +++ b/admin_scripts/normalize_volume.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::Telnet; +use Time::HiRes qw(usleep); + +die "Usage: $0 host pass volume\n" unless @ARGV == 3; +my $host = $ARGV[0]; +my $pass = $ARGV[1]; +my $vol = $ARGV[2]; + +my $t = Net::Telnet->new(Timeout => 3, Prompt => '/[^\n]*> $/'); + +$t->open($host); +$t->waitfor('/Password :$/'); +$t->print($pass); +$t->waitfor($t->prompt); + +foreach ('open', ('key voldn') x 16, ('key volup') x $vol, 'close') { + $t->cmd("test $_"); + usleep 200_000; +} + +$t->print("exit"); +$t->close(); + diff --git a/admin_scripts/send_reboot.pl b/admin_scripts/send_reboot.pl new file mode 100755 index 0000000..46ca65a --- /dev/null +++ b/admin_scripts/send_reboot.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::SIP; +use Net::SIP::Util qw(laddr4dst INETSOCK ip_sockaddr2parts); +use Socket; + +die "Usage: $0 host line\n" unless @ARGV == 2; +my $host = $ARGV[0]; +my $line = $ARGV[1]; + +my $ip = inet_aton($host); +die "ERROR: Cannot resolve host\n" unless defined $ip; +my $addr = inet_ntoa($ip); + +my $laddr = laddr4dst($addr); +die "ERROR: No route to host\n" unless $laddr; + +my $sock = INETSOCK(Proto => 'udp', LocalAddr => $laddr, LocalPort => 0); +die "ERROR: Cannot create socket: $!\n" unless $sock; + +my $lport = (ip_sockaddr2parts(getsockname($sock)))[1]; + +my $leg = Net::SIP::Leg->new(sock => $sock); +die "ERROR: Cannot create leg: $!\n" unless $leg; + +my $ua = Net::SIP::Simple->new(from => "", leg => $leg); +die "ERROR: Cannot create SIP user agent: $!\n" unless $ua; + +my ($stop, $code, $text); + +$ua->{endpoint}->new_request( + 'NOTIFY', + { from => $ua->{from}, to => "" }, + sub { + (undef, undef, undef, $code, my $packet) = @_; + (undef, $text) = $packet ? $packet->as_parts : (); + $stop = 1; + }, + '', + uri => "sip:$line\@$addr", + Event => 'check-sync', + Contact => $ua->{from}, +); + +$ua->loop(3, \$stop); +$ua->cleanup(); + +die "ERROR: Timeout\n" unless $stop; +die "ERROR: Invalid response\n" unless $code and $text; +die "ERROR: SIP response: $code $text\n" unless $code eq '200'; diff --git a/admin_scripts/volume_up.pl b/admin_scripts/volume_up.pl new file mode 100755 index 0000000..b81a264 --- /dev/null +++ b/admin_scripts/volume_up.pl @@ -0,0 +1,33 @@ +#!/usr/bin/perl +# (c) Pali 2019, Perl license + +use strict; +use warnings; + +use Net::Telnet; +use Time::HiRes qw(usleep); + +die "Usage: $0 host pass ast_user\n" unless @ARGV == 3; +my $host = $ARGV[0]; +my $pass = $ARGV[1]; +my $user = $ARGV[2]; + +my $t = Net::Telnet->new(Timeout => 3, Prompt => '/[^\n]*> $/'); + +$t->open($host); +$t->waitfor('/Password :$/'); +$t->print($pass); +$t->waitfor($t->prompt); + +foreach ('open', ('key volup') x 16, 'close') { + if (system('sh', '-c', qq[asterisk -rx "core show channels" |grep -q "$user"]) != 0) { + print STDERR "Call ended, exiting"; + last; + } + $t->cmd("test $_"); + usleep 200_000; +} + +$t->print("exit"); +$t->close(); + diff --git a/all_reboot.sh b/all_reboot.sh new file mode 100755 index 0000000..269f467 --- /dev/null +++ b/all_reboot.sh @@ -0,0 +1,6 @@ +#!/bin/sh +pass=`sed -n 's/telnet_pass=//p' config.txt` +ip=`sed -n 's/server_ip=//p' config.txt | sed 's/\.[0-9]*$//'` +for i in `cat phones.txt | grep -v \- | sed -n 's/^\([0-9][0-9]\).*/\1/p'`; do + { admin_scripts/send_reboot.pl "$ip.$i" "$i" 2>&1 || admin_scripts/force_reboot.pl "$ip.$i" "$pass" 2>&1 ; } | sed "s/^/$i: /" +done diff --git a/ann_end.sh b/ann_end.sh new file mode 100755 index 0000000..8e0c8ba --- /dev/null +++ b/ann_end.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +line="$1" +[[ -n "$line" ]] || { echo >&2 "usage: $0 "; exit 1; } + +echo "Action: login +username: admin +secret: admin +events: off + +Action: hangup +Channel: /PJSIP/emerg$line-.*/ +" | socat - TCP:localhost:5038 + diff --git a/ann_end_all.sh b/ann_end_all.sh new file mode 100755 index 0000000..494ce9e --- /dev/null +++ b/ann_end_all.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +cd "$(dirname "$0")" +echo "Action: login +username: admin +secret: admin +events: off + +Action: hangup +Channel: /.*emerg.*/ +" | socat - TCP:localhost:5038 diff --git a/ann_listen.sh b/ann_listen.sh new file mode 100755 index 0000000..f06ea6d --- /dev/null +++ b/ann_listen.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +cd "$(dirname "$0")" +line="$1" +. config.txt + +./ann_end.sh "$line" # and any existing calls to prevent our call ending up in "call waiting" state (and thus not autoanswered) +sleep 0.5 +./autoanswer_line.sh "$line" 1 || { echo >&2 "failed to enable autoanswer, exiting."; exit 1; } + +fn=/var/spool/asterisk/tmp/ann_$line.call +echo " +Channel: PJSIP/emerg$line +Context: emerg_listen +Extension: 120 +Priority: 1 +" >$fn + +mv "$fn" /var/spool/asterisk/outgoing/ + +./ann_volup.sh "$line" & diff --git a/ann_listen_all.sh b/ann_listen_all.sh new file mode 100755 index 0000000..02abb96 --- /dev/null +++ b/ann_listen_all.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cd "$(dirname "$0")" +cat phones.txt | awk '{print $1}' | grep '^[3-5]' | xargs -n1 -P0 ./ann_listen.sh + diff --git a/ann_play.sh b/ann_play.sh new file mode 100755 index 0000000..a4fe130 --- /dev/null +++ b/ann_play.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# By default, we operate in bracketed mode: initiate listening calls, play announcement and terminate them +# With -n, we do not do bracketing, you have to initiate and terminate listening calls yourself +# with ann_listen[_all].sh and ann_end[_all].sh. Useful if you want to combine playback and speech in +# one announcement (call 121 to speak without bracketing). + +if [[ "$1" == -n ]]; then num=121; shift; else num=122; fi + + +playstring="silence/1" +i=0 +for arg in "$@"; do + if [[ "$arg" =~ ^silence ]]; then + playitem="$arg" + else + ffmpeg -i "$arg" -ar 8000 -ac 1 -y /tmp/ann$i.wav + playitem=/tmp/ann$i + fi + playstring="$playstring&$playitem" + i=$((i+1)) +done + +fn=/var/spool/asterisk/tmp/ann_play.call +echo " +Channel: Local/$num@orgs +Application: Playback +Data: $playstring +" >$fn +mv $fn /var/spool/asterisk/outgoing/ diff --git a/ann_play_unicast.sh b/ann_play_unicast.sh new file mode 100755 index 0000000..16d278a --- /dev/null +++ b/ann_play_unicast.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +cd "$(dirname "$0")" +line="$1" +snd="$2" +. config.txt + +./ann_end.sh "$line" # and any existing calls to prevent our call ending up in "call waiting" state (and thus not autoanswered) +sleep 0.5 +./autoanswer_line.sh "$line" 1 || { echo >&2 "failed to enable autoanswer, exiting."; exit 1; } + +playstring="silence/1" +i=0 +for arg in "$@"; do + if [[ "$arg" =~ ^silence ]]; then + playitem="$arg" + else + ffmpeg -i "$arg" -ar 8000 -ac 1 -y /tmp/ann${line}_$i.wav + playitem=/tmp/ann${line}_$i + fi + playstring="$playstring&$playitem" + i=$((i+1)) +done + +fn=/var/spool/asterisk/tmp/ann_$line.call +echo " +Channel: PJSIP/emerg$line +Application: Playback +Data: $playstring +Priority: 1 +" >$fn + +mv "$fn" /var/spool/asterisk/outgoing/ + +./ann_volup.sh "$line" & + diff --git a/ann_stop.sh b/ann_stop.sh new file mode 100755 index 0000000..bc5e62d --- /dev/null +++ b/ann_stop.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +cd "$(dirname "$0")" +./ann_end_all.sh +echo "Action: login +username: admin +secret: admin +events: off + +Action: hangup +Channel: /.*emerg.*/ + +Action: ConfbridgeKick +Conference: 120 +Channel: all + +" | socat - TCP:localhost:5038 + diff --git a/ann_volup.sh b/ann_volup.sh new file mode 100755 index 0000000..def2c67 --- /dev/null +++ b/ann_volup.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +cd "$(dirname "$0")" +line="$1" +[[ "$line" =~ ^[0-9]+$ ]] || { echo >&2 "usage: $0 "; exit 1; } +. config.txt +ip_prefix=${server_ip%.*} +ip="$ip_prefix.$line" + +for i in $(seq 1 10); do + if asterisk -rx "core show channels" |grep -q "emerg$line"; then + ./admin_scripts/volume_up.pl "$ip" "$telnet_pass" "emerg$line" + break + else + sleep 1 + fi +done + diff --git a/autoanswer_all.sh b/autoanswer_all.sh new file mode 100755 index 0000000..c9d85de --- /dev/null +++ b/autoanswer_all.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +state="$1" + +case $state in + 1) + gr=enabled + ;; + 0) + gr=disabled + ;; +esac + +cd /opt/ksp +cat phones.txt | awk '{print $1}' | grep '^[3-5]' | xargs -i -n1 -P0 ./autoanswer_line.sh '{}' "$state" | grep $gr | cut -d. -f4| cut -d' ' -f1 diff --git a/autoanswer_line.sh b/autoanswer_line.sh new file mode 100755 index 0000000..5003a4a --- /dev/null +++ b/autoanswer_line.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +cd "$(dirname "$0")" +line="$1" +state="$2" +{ [[ "$line" =~ ^[0-9]+$ ]] && [[ "$state" =~ ^[01]$ ]]; } || { echo >&2 "usage: $0 <0|1>"; exit 1; } +. config.txt +ip_prefix=${server_ip%.*} +ip="$ip_prefix.$line" + +./admin_scripts/auto_answer.pl "$ip" "$telnet_pass" 2 "$state" + diff --git a/cislovaci_plan b/cislovaci_plan new file mode 100644 index 0000000..a738fcb --- /dev/null +++ b/cislovaci_plan @@ -0,0 +1,24 @@ +veřejné číslo pro volání zvenku: 910 128 976 + +0 - 9 - nič +20 - 29 - ORG cisco telefóny +30 - 59 - zvyšné cisco telefóny +60 - 99 - zvyšné ne-cisco telefóny (ak budeme zapájať iných SIP klientov) +78 - (mnemonic: "su") Volání org-only čísel z libovolného telefonu, případně zvenku +100 - 199 - čísla pre automaty, odkazové schránky a iné veci + - 11x... veřejné konference + - 12x announce mechanismus + - 120 announce listen + - 121 [org only] announce speak (jen umožňuje mluvit k posluchačům) + - 122 [org only] announce (připoj všechny účastníky do konference a pak mluv) + - 123xx [org only] unicast announce na telefon xx (funguje obousměrně; nezneužívat k odposlechu, ale můžete se bavit s účastníky) + - 130 - vytočí náhodnú non-ORG linku + - 131 - vyzvednutí hlasových zpráv + - 14xx - přímé zanechání hlasové zprávy pro linku xx + - 16x - IVR + - 161 - FBI + +Podle samolepek na telefonu: + +8888 - helpdesk -> FBI +4445 - HR -> přečtení pokynů diff --git a/clean.sh b/clean.sh new file mode 100755 index 0000000..794b0ea --- /dev/null +++ b/clean.sh @@ -0,0 +1,2 @@ +#!/bin/sh +rm -f etc_asterisk/pjsip_wizard_phones.conf etc_asterisk/voicemail_gen.conf tftp_reflash/SIP00*.cnf tftp_reflash/SIPDefault.cnf tftp/Phones/SIP00*.cnf tftp/RINGLIST.DAT etc_dnsmasq.d/phones.conf www/directory.txt etc_asterisk/voicemail_gen.conf diff --git a/config.txt b/config.txt new file mode 100644 index 0000000..f2eb256 --- /dev/null +++ b/config.txt @@ -0,0 +1,4 @@ +server_ip=172.16.0.1 +telnet_pass=FIXME +hmac_key=FIXME +fake_year=2114 diff --git a/conv_ring.sh b/conv_ring.sh new file mode 100755 index 0000000..45d0f4b --- /dev/null +++ b/conv_ring.sh @@ -0,0 +1,8 @@ +#!/bin/sh -e +if test "$#" != "1"; then echo "Usage: $0 sound_file.ext"; exit 1; fi +file="${1%.*}.pcm" +ffmpeg -loglevel fatal -y -i "$1" -f u8 -c pcm_mulaw -ar 8000 -ac 1 "$file" +size=`du -b "$file" | cut -f1` +size=$(($size/240*240)) +if test "$size" -gt "16080"; then size=16080; fi +truncate -s "$size" "$file" diff --git a/etc_asterisk/confbridge.conf b/etc_asterisk/confbridge.conf new file mode 100644 index 0000000..c6141e0 --- /dev/null +++ b/etc_asterisk/confbridge.conf @@ -0,0 +1,22 @@ +[default_bridge] +type=bridge +video_mode=none + +[ann_listen] +type=user +startmuted=yes +quiet=yes +announce_only_user=no + +[ann_speak] +type=user +quiet=yes +announce_only_user=no +startmuted=no + +[ann] +type=bridge +video_mode=none + +[empty_menu] +type=menu diff --git a/etc_asterisk/extensions.lua b/etc_asterisk/extensions.lua new file mode 100644 index 0000000..e57da93 --- /dev/null +++ b/etc_asterisk/extensions.lua @@ -0,0 +1,141 @@ +extensions = {} +extensions.participants = {} +extensions.orgs = {} +extensions.emerg = {} +extensions.emerg_listen = {} +extensions.ann_bracket = {} +extensions.odorik = {} +extensions.external = {} + +function sip_exten(ch, ext) + app.dial("PJSIP/" .. ext, 40) + local status = channel.DIALSTATUS:get() + app.verbose("status: " .. status) + if status == "BUSY" then + flags="b" + else + flags="u" + end + app.voicemail(ext, flags) +end +function ann_unicast(ch, ext) + app.dial("PJSIP/emerg" .. string.sub(ext, 4)) +end +function sip_nightmode(ch, ext) + local hour = tonumber(os.date("%H")) + local minute = tonumber(os.date("%M")) + if hour < 12 or (hour == 12 and minute < 10) or hour > 23 or (hour == 23 and minute > 20) then + app.playback("/opt/ksp/sounds/nocni_klid") + app.voicemail(ext) + else + sip_exten(ch, ext) + end +end +function voicemail_direct(ch, ext) + app.voicemail(string.sub(ext, 3)) +end +function voicemail_listen(ch, ext) + local caller = channel.CALLERID("num"):get() + app.voicemailmain(caller, "s") -- no password prompt +end + +function conf(ch, ext) + app.confbridge(ext) +end + +function add(ctxs, ext, func) + for i = 1, #ctxs do + extensions[ctxs[i]][ext] = func + end +end + +function ann_listen(ch, ext) + app.confbridge("120", "ann", "ann_listen", "empty_menu") +end +function ann_speak(ch, ext) + app.confbridge("120", "ann", "ann_speak") +end + +function ann_bracket(ch, ext) + app.system("/opt/ksp/ann_listen_all.sh") + app.confbridge("120", "ann", "ann_speak") +end +function ann_bracket_hangup(ch, ext) + app.system("/opt/ksp/ann_end_all.sh") +end +function ann_bracket_goto(ch, ext) + app.goto("ann_bracket", "122", 1) +end + +function fbi(ch, ext) + app.dial("PJSIP/910119352@odorik") +end + +function odorik_incoming(ch, ext) + app.answer() + app.read("klapka", "/opt/ksp/sounds/klapka") + local klapka = channel.klapka:get() + app.goto("external", klapka, 1) +end + +function su(ch, ext) + app.read("heslo", "/opt/ksp/sounds/heslo") + local heslo = channel.heslo:get() + if heslo == "2886287" then + app.read("klapka", "/opt/ksp/sounds/klapka") + local klapka = channel.klapka:get() + app.goto("orgs", klapka, 1) + else + app.playback("/opt/ksp/sounds/spatne_heslo") + app.hangup() + end +end + +--http://lua-users.org/wiki/StringTrim +function trim1(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end +function call_rand(ch, ext) + local caller = channel.CALLERID("num"):get():gsub("'", "") + local handle = io.popen("/opt/ksp/rand_line.sh '" .. caller .. "'") + local line = trim1(handle:read("*all")) + handle:close() + app.verbose("RAND: " .. line) + app.dial("PJSIP/"..line) +end +function snd(name) + return function(ch, ext) + app.answer() + app.playback("/opt/ksp/sounds/" .. name) + app.hangup() + end +end + +add({"orgs"}, "_2X", sip_exten) -- org phones +add({"orgs"}, "_[345]X", sip_exten) -- participant phones +-- night mode restriction applies only when calling from participant phones +add({"participants", "external"}, "_2X", sip_nightmode) -- org phones +add({"participants", "external"}, "_[345]X", sip_nightmode) -- participant phones +add({"orgs", "participants", "external"}, "_11.", conf) +add({"orgs", "participants", "emerg_listen", "external"}, "120", ann_listen) +add({"orgs"}, "121", ann_speak) +-- Because hangup actions are per-context and not per-extension, we need to jump to +-- a separate context to allow a hangup handler to terminate listeners after a call +-- to 122 is done. +add({"orgs"}, "122", ann_bracket_goto) +add({"ann_bracket"}, "122", ann_bracket) +add({"ann_bracket"}, "h", ann_bracket_hangup) +add({"orgs"}, "_123XX", ann_unicast) +add({"orgs", "participants"}, "131", voicemail_listen) -- does not work, done in extensions.conf!! +add({"orgs", "participants", "external"}, "_14XX", voicemail_direct) +add({"participants", "external"}, "78", su) +add({"odorik"}, "s", odorik_incoming) +add({"orgs", "participants", "external"}, "160", fbi) +add({"orgs", "participants", "external"}, "910119352", fbi) +-- Na některých telefonech je od původních majitelů nálepka "call helpdesk at 8888" +add({"orgs", "participants", "external"}, "8888", fbi) +add({"orgs", "participants", "external"}, "4445", snd("hr")) +add({"orgs", "participants", "external"}, "130", call_rand) + + +--add({"orgs", "participants"}, "_131", snd("sadtromb")) diff --git a/etc_asterisk/logger.conf b/etc_asterisk/logger.conf new file mode 100644 index 0000000..690ac7f --- /dev/null +++ b/etc_asterisk/logger.conf @@ -0,0 +1,3 @@ +[logfiles] + +console => notice,warning,error,debug,verbose diff --git a/etc_asterisk/manager.conf b/etc_asterisk/manager.conf new file mode 100644 index 0000000..3e4f323 --- /dev/null +++ b/etc_asterisk/manager.conf @@ -0,0 +1,11 @@ +[general] +enabled = yes +webenabled = no + +port = 5038 +bindaddr = 127.0.0.1 + +[admin] +secret = admin +read = all +write = all diff --git a/etc_asterisk/modules.conf b/etc_asterisk/modules.conf new file mode 100644 index 0000000..be2a034 --- /dev/null +++ b/etc_asterisk/modules.conf @@ -0,0 +1,73 @@ +; +; Asterisk configuration file +; +; Module Loader configuration file +; + +[modules] +autoload=yes +; +; Any modules that need to be loaded before the Asterisk core has been +; initialized (just after the logger has been initialized) can be loaded +; using 'preload'. This will frequently be needed if you wish to map all +; module configuration files into Realtime storage, since the Realtime +; driver will need to be loaded before the modules using those configuration +; files are initialized. +; +; An example of loading ODBC support would be: +;preload => res_odbc.so +;preload => res_config_odbc.so +; +; If you want, load the GTK console right away. +; Don't load the KDE console since +; it's not as sophisticated right now. +; +noload => pbx_gtkconsole.so +;load => pbx_gtkconsole.so +noload => pbx_kdeconsole.so +; +; Intercom application is obsoleted by +; chan_oss. Don't load it. +; +noload => app_intercom.so +; +; The 'modem' channel driver and its subdrivers are +; obsolete, don't load them. +; +noload => chan_modem.so +noload => chan_modem_aopen.so +noload => chan_modem_bestdata.so +noload => chan_modem_i4l.so +; +; Comment this out (after installing CAPI middleware and hardware +; drivers) if you have CAPI-able hardware and wish to use it in +; Asterisk. +; +noload => chan_capi.so +; +load => res_musiconhold.so +; +; Do not load load local channel drivers (using the system speaker) by default, +; they are not used in most installations and might block the sound hardware +; +noload => chan_alsa.so +noload => chan_console.so +noload => chan_oss.so +; +; Disable CDR logging to SQLite by default since it writes unconditionally to +; cdr.db without a way to rotate it. +; +noload => cdr_sqlite.so +; +; These conflict with app_directory.so and each other. +noload => app_directory_odbc.so +; +; Enable these if you want to configure Asterisk in a database +; +noload => res_config_odbc.so +noload => res_config_pgsql.so +; +; Module names listed in "global" section will have symbols globally +; exported to modules loaded after them. +; +[global] diff --git a/etc_asterisk/pjsip.conf b/etc_asterisk/pjsip.conf new file mode 100644 index 0000000..504234a --- /dev/null +++ b/etc_asterisk/pjsip.conf @@ -0,0 +1,10 @@ +[system-udp] +type=transport +protocol=udp +bind=0.0.0.0 + + +[system-tcp] +type=transport +protocol=tcp +bind=0.0.0.0 diff --git a/etc_asterisk/pjsip_wizard.conf b/etc_asterisk/pjsip_wizard.conf new file mode 100644 index 0000000..50f9c1e --- /dev/null +++ b/etc_asterisk/pjsip_wizard.conf @@ -0,0 +1,36 @@ +[base_phone](!) +type = wizard +transport = system-udp +accepts_registrations = yes +sends_registrations = no +accepts_auth = yes +sends_auth = no +aor/max_contacts = 1 +aor/remove_existing = yes +endpoint/allow = !all,alaw +endpoint/direct_media = yes + +[participant_phone](!,base_phone) +endpoint/context = participants + +[participant_emerg](!,base_phone) +endpoint/context = emerg + +[org_phone](!,base_phone) +endpoint/context = orgs + +[odorik] +type = wizard +transport = system-udp +sends_auth = yes +sends_registrations = yes +remote_hosts = 81.31.45.51 ; sip.odorik.cz +; public number: 910 128 976 +outbound_auth/username = 747515 +#include odorik_pass.conf +endpoint/context = odorik +aor/qualify_frequency = 15 +endpoint/allow = !all,alaw + +#include pjsip_wizard_phones.conf + diff --git a/etc_asterisk/voicemail.conf b/etc_asterisk/voicemail.conf new file mode 100644 index 0000000..826dc2e --- /dev/null +++ b/etc_asterisk/voicemail.conf @@ -0,0 +1,6 @@ +[general] + +format=wav + +[default] +#include voicemail_gen.conf diff --git a/etc_dnsmasq.d/dhcp.conf b/etc_dnsmasq.d/dhcp.conf new file mode 100644 index 0000000..f1672d3 --- /dev/null +++ b/etc_dnsmasq.d/dhcp.conf @@ -0,0 +1,6 @@ +interface=eth0 +bind-dynamic +dhcp-authoritative +listen-address=172.16.0.1 +dhcp-range=172.16.0.100,172.16.0.200 +dhcp-leasefile=/tmp/dhcp.leases diff --git a/etc_dnsmasq.d/phones_tftp.conf b/etc_dnsmasq.d/phones_tftp.conf new file mode 100644 index 0000000..e17b523 --- /dev/null +++ b/etc_dnsmasq.d/phones_tftp.conf @@ -0,0 +1,4 @@ +dhcp-vendorclass=set:CiscoIPPhone,"Cisco Systems, Inc. IP Phone" +dhcp-option=tag:CiscoIPPhone,150,0.0.0.0 +enable-tftp +tftp-root=/opt/ksp/tftp diff --git a/gen.pl b/gen.pl new file mode 100755 index 0000000..568b4c8 --- /dev/null +++ b/gen.pl @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Digest::SHA qw(hmac_sha1_hex); +use Encode; +use Text::Unidecode; + +mkdir "tftp/Phones"; + +my $fh; + +my %config; +open $fh, '<', 'config.txt' or die "Cannot read file config: $!\n"; +while (<$fh>) { + chomp; + my ($key, $value) = split /=/, $_, 2; + $config{$key} = $value; +} +close $fh; + +my $server_ip = $config{server_ip}; +my $ip_template = $server_ip; +$ip_template =~ s/\.[^.]*$//; +my $fake_second_half = $config{fake_year}; + +my $sipdefault_reflash = <<"EOD"; +image_version: P0S3-8-12-00 +phone_password: $config{telnet_pass} +encrypt_key: 00000000000000000000000000000000 +telnet_level: 2 +tftp_cfg_dir: "" +EOD +chomp $sipdefault_reflash; + +open my $phones_fh, '<', 'phones.txt' or die "Cannot read file phones.txt: $!\n"; +open my $ast_fh, '>', 'etc_asterisk/pjsip_wizard_phones.conf' or die "Cannot create file etc_asterisk/pjsip_wizard_phones.conf: $!\n"; +open my $dnsmasq_fh, '>', 'etc_dnsmasq.d/phones.conf' or die "Cannot create file etc_dnsmasq.d/phones.conf: $!\n"; +open my $directory_fh, '>', 'www/directory.txt' or die "Cannot create file www/directory.txt: $!\n"; +open my $voicemail_fh, '>', 'etc_asterisk/voicemail_gen.conf' or die "Cannot create file etc_asterisk/voicemail_gen.conf: $!\n"; + +print $ast_fh "; This is autogenerated file, do not edit it!\n"; +print $dnsmasq_fh "# This is autogenerated file, do not edit it!\n"; +print $directory_fh "# This is autogenerated file, do not edit it!\n"; +print $voicemail_fh "; This is autogenerated file, do not edit it!\n"; + +while (<$phones_fh>) { + chomp $_; + next if $_ =~ /^(?:#|$)/; + $_ =~ s/#.*//; + $_ =~ s/\s*$//; + + my ($line, $mac, $alias, $name) = split /\s+/, $_, 4; + die "Invalid line $.: $_\n" unless defined $name; + + $mac = uc $mac; + my $name_latin1 = $name; + Encode::from_to($name_latin1, 'UTF-8', 'ISO-8859-1', sub { unidecode(chr($_[0])) }); + + $line =~ /^[2-9][0-9]$/ or die "Invalid LINE $line on line $.: $_\n"; + $alias =~ /^[A-Za-z0-9_]{1,20}$/ or die "Invalid ALIAS $alias on line $.: $_\n"; + length $name_latin1 <= 30 or die "Too long NAME $name on line $.: $_\n"; + + my $parent = ($line =~ /^2[0-9]$/) ? 'org_phone' : 'participant_phone'; + my $pass = substr(hmac_sha1_hex($line, $config{hmac_key}), 0, 12); + + my $cisco_fh; + my $ciscofile; + if ($mac ne '-') { + $mac =~ /^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$/ or die "Invalid MAC $mac on line $.: $_\n"; + $ciscofile = $mac; + $ciscofile =~ s/://g; + + open $cisco_fh, '>', "tftp/Phones/SIP$ciscofile.cnf" or die "Cannot create file tftp/Phones/SIP$ciscofile.cnf: $!\n"; + print $cisco_fh <<"EOD"; +# This is autogenerated file, do not edit it! +phone_label: "$fake_second_half Klapka $line " +phone_prompt: "Telnet phone $line" +proxy_register: 1 +proxy1_address: $server_ip +proxy1_port: 5060 +line1_name: $line +line1_authname: $line +line1_password: $pass +line1_displayname: "$alias" +line1_shortname: "$name_latin1" +sntp_server: $server_ip +sntp_mode: unicast +services_url: http://$server_ip/services.xml +directory_url: http://$server_ip/directory.xml +logo_url: http://$server_ip/logo.bmp +messages_uri: 131 +telnet_level: 2 +EOD + close $fh; + } + + print $ast_fh <<"EOD"; +[$line]($parent) +inbound_auth/username = $line +inbound_auth/password = $pass +endpoint/mailboxes = $line +EOD + if ($parent eq 'participant_phone') { + print $ast_fh <<"EOD"; +[emerg$line](participant_emerg) +inbound_auth/username = emerg$line +inbound_auth/password = $pass +EOD + if ($mac ne '-') { + print $cisco_fh <<"EOD" +proxy2_address: $server_ip +proxy2_port: 5060 +line2_name: emerg$line +line2_authname: emerg$line +line2_password: $pass +line2_displayname: "Emergency $line" +line2_shortname: " " +EOD + } + + } else { + if ($mac ne '-') { + print $cisco_fh <<"EOD" +dnd_control: 0 +EOD + } + } + if ($mac ne '-') { + close $cisco_fh; + open $fh, '>', "tftp_reflash/SIP$ciscofile.cnf" or die "Cannot create file tftp_reflash/SIP$ciscofile.cnf: $!\n"; + print $fh <<"EOD"; +# This is autogenerated file, do not edit it! +$sipdefault_reflash +proxy_register: 0 +line1_name: $line +EOD + } + if ($mac ne '-') { + print $dnsmasq_fh <<"EOD"; +dhcp-host=$mac,$ip_template.$line,$alias +EOD + } + print $directory_fh <<"EOD"; +$name=$line +EOD + + print $voicemail_fh <<"EOD" +$line => 0000,$name +EOD +} + +close $phones_fh; +close $ast_fh; +close $dnsmasq_fh; +close $directory_fh; +close $voicemail_fh; + +open $fh, '>', 'tftp_reflash/SIPDefault.cnf' or die "Cannot create file tftp_reflash/SIPDefault.cnf: $!\n"; +print $fh <<"EOD"; +# This is autogenerated file, do not edit it! +$sipdefault_reflash; +EOD +close $fh; + +open $fh, '>', 'tftp/RINGLIST.DAT' or die "Cannot create file tftp/RINGLIST.DAT: $!\n"; +foreach () { + $_ =~ m{^tftp/(RingTones/(.*)\.pcm)$}; + my ($file, $name) = ($1, $2); + $name =~ s/_/ /g; + print $fh "$name\t$file\n"; +} +close $fh; diff --git a/gen_hr.sh b/gen_hr.sh new file mode 100755 index 0000000..9b8ecac --- /dev/null +++ b/gen_hr.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +i=0 +grep . hr.txt | while read line; do + i=$((i+1)) + echo ">> [$i] $line" + fn=hr/$(printf %03d $i).wav + if [[ -e "$fn" ]]; then continue; fi + ./tts.sh "$line" "$fn" + sleep 10 +done diff --git a/gen_sounds.sh b/gen_sounds.sh new file mode 100755 index 0000000..d4c9d25 --- /dev/null +++ b/gen_sounds.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +gen_sound() { + fn="sounds/$1.wav" + [[ -e "$fn" ]] || ./tts.sh "$2" "$fn" +} +gen_sound nocni_klid "Z důvodu nočního klidu budete přesměrováni do hlasové schránky. Pokud chcete telefonovat v reálném čase, můžete oba zavolat do společné konference." +gen_sound heslo "Zadejte heslo" +gen_sound spatne_heslo "Špatné heslo" +gen_sound klapka "Zadejte číslo klapky" +gen_sound wc_thanks "Děkujeme za použití toalety. Nezapomeňte si umýt ruce." +gen_sound wc_thanks_m "Děkujeme, že jste použil naše toalety. Nezapomeňte si umýt ruce." +gen_sound wc_thanks_f "Děkujeme, že jste použila naše toalety. Nezapomeňte si umýt ruce." +gen_sound tp_prizemi "V kontaminační komoře na nulté palubě došel toaletní papír. Prosíme cestující, aby se solidárně podělili o své noviny." +gen_sound tp_prvni "V kontaminační komoře na první palubě došel toaletní papír. Prosíme cestující, aby se solidárně podělili o své noviny." +gen_sound tp_druhe "V kontaminační komoře na druhé palubě došel toaletní papír. Prosíme cestující, aby se solidárně podělili o své noviny." diff --git a/hangup_all.sh b/hangup_all.sh new file mode 100755 index 0000000..32519b0 --- /dev/null +++ b/hangup_all.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +echo "Action: login +username: admin +secret: admin +events: off + +Action: hangup +Channel: /.*/ +" | socat - TCP:localhost:5038 + + diff --git a/hr.txt b/hr.txt new file mode 100644 index 0000000..4282f0c --- /dev/null +++ b/hr.txt @@ -0,0 +1,179 @@ +VŠEOBECNÉ SMĚRNICE PROVOZU LODI + +Pokud je vaše pracovní uniforma kontaminována dihydrogen monoxidem, použijte vysokokapacitní savou substanci pro odstranění kontaminace. + +Loď je vybavena telekomunikačním systémem, jehož terminály jsou rozmístěny ve většině obytných i jiných prostor. +Tyto terminály smíte využívat pro vzájemnou komunikaci s posádkou i s vedením lodi. +Váš hovor může být monitorován pro zlepšení služeb, které jsou k dispozici vedení lodi. +Zároveň budou terminály využívány pro svolávání posádky či vyvolání poplachu. +Tyto terminály je ZAKÁZÁNO ničit, vypojovat, poškozovat či jinak s nimi nemístně manipulovat. + +V případě katastrofálního nedostatku toaletního papíru, který je detekován až po zahájení využívání toalety, použijte pro přivolání asistence přiloženého telekomunikačního zařízení. + +Strava na lodi je vydávána nejméně třikrát denně (snídaně, oběd, večeře). +Pro blaho posádky je povinnná účast na snídani. +Snídani předchází dobrovolná tělesná rozcvička a preventivní test psychoakustické zdatnosti. +Podmínkou účasti na snídani je účast na rozcvičce. + +Vzdělávání posádky je vedením podporováno. +Z tohoto důvodu se ve společenských prostorách budou každý den pořádat přibližně tři bloky odborného trénování a lekcí z teorie civilizace a vesmírné kolonizace. +Na těchto lekcích je přísně zakázáno rušit či spát. +Spící osoby budou kosmeticky či geneticky modifikovány. + +Při rekreační rotační pohybové hře kruhozávodu po směru hodinových ručiček budou libovolné vzpoury tvrdě potlačeny. +Viníci budou vyhozeni přetlakovou komorou do mezihvězdného prostoru, následně budou opět zachyceni a zpracováni na karbonovou pastu. + +Vedení by chtělo důrazně varovat posádku lodi o faktu, že kdo umře v Polsku, umře i ve skutečnosti. + +Je zakázáno chovat na lodi domácí mazlíčky či jinou zvěř mimo prostor skladiště biologického materiálu. +Vyjímku tvoří lišky, hroši, prasata a medvědi. + +Každý lodní den bude vyhrazeno nejméně třicet tři procent dne na spánek či odpočinek. +Definice lodního dne, spánku, odpočinku a procent bude upřesněna. + +Při zjištění incidentu zcizení vlastního předmětu jiným členem posádky je nutno zajistit znalost jména všech zúčastněných osob. + +V případě závady na skafandru je možno vyžádat si od vedení lodi náhradní. +Mějte ovšem na paměti, že nadbytečných skafandrů je omezené množství. + +K respirátorům jsou k dispozici speciální kyslíkové náplně s vůní mrkve. + +Je přísně zakázáno krmit zvěř ve skladišti biologického materiálu. + +Po večerce se uložte ke spánku v gravitačních kójích. +Pro kvalitní spánek je nutné nejdříve ke svému jazyku připojit kabely s koncovkou typu krokodýl, která stimuluje sny, detekuje náměsíčnost a slouží jako efektivní budíček. +Budíček smí využívat pouze bezpečných úrovní napětí. + +Pokud nastane katastrofální selhání štěpného reaktoru, použijte k pacifikaci zběhlých neutronů vystužených kontrolních tyčí z boronu. + +Vedení lodi by chtělo zvlášť poděkovat umělci Markovi "Maark" Černému za design lodního exteriéru. + +Pro zlepšenou orientaci posádky je interiér lodi vybaven orietačními symboly a směrovkami. +Mějte na paměti, že směrovky jsou orientované! Navíc je zaručeno, že graf směrovek je 2-souvislý. + +Je přísně zakázáno kontaminovat mezihvězdný prostor odpadky, jako jsou například konzervy. + +Veškerá rekreační zařízení jsou testována na dětech. + +Do stázové komory je vstup povolen pouze v pyžamu splňujícím normu 3GPP-4923587-3B. +Nedodržení může vyústit ve smrt stářím. + +Berte na vědomí, že červená reflexní etiketa značí extrémně pálivé pokrmy. + +Politické mapy nově kolonizovaných území musí splňovat, že sousední území nejsou obarvena shodně a jsou použity nejvýše čtyři barvy. + +Pro případ politické diskuze jsou nouzové plamenomety uloženy na třetí palubě. + +Nekrmte lodní kočku bez jejího svolení. + +Veškerá data o posádce (včetně záznamů pohybu, biotelemetrie, vyhledávaných frází a publikovaných příspěvků na lodní sociální síti) +budou využita pro algoritmické vylepšení a personalizaci lodních předpisů. + +Každý člen posádky musí znát nejméně 50 souhvězdí. + + + + + +POKYNY PŘI EVAKUACI + +Veškerá posádka lodi je povinna řídit se evakuačními pokyny. + +Pokud dojde k evakuaci z důvodu úniku radioaktivního materiálu ze štěpného reaktoru, +z důvodu vniku radioaktivního materiálu do fůzního reaktoru, +kvůli selhání vzduchotechniky, softwarové vyjímky, kolize s cizím objektem, +kolize se spřízněným objektem, nebo z důvodu napadení cizí formou života, +ignorujte v tomto případě všeobecné nařízení §451-3. + +Pokud dojde k evakuaci z důvodu ztráty elektrické energie, +z důvodu vniku radioaktivního materiálu do fůzního reaktoru, +kvůli prudkému poklesu tlaku, kontaminaci melounovou Kofolou či katastrofálnímu nadbytku čočky, +ignorujte lemma 6.66. + +Pokyny: + +Každý člen posádky je především povinen řídit se pokyny z lodní telefonní sítě. +S telefony je přísně zakázáno neoprávněně manipulovat či narušovat jejich činnost. + +Každý člen posádky je povinen řídit se pokyny velících důstojníků, a to i mimo své domovské oddělení. + +Evakuace je zahájena všeobecným poplachem. + +Po zahájení evakuace se urychleně připravte opustit loď. +Očekávaná doba na přípravu je PĚT AŽ SEDM MINUT. +Pomalejší členové posádky budou zanecháni na lodi! + +S sebou si vemte: +nezbytnou osobní výbavu na 2 až 5 hodin v mezihvězdném prostoru, +vhodný exosuit do slunečního větru, meteorického deště a zimy blízké absolutní nule, +osobní jetpack, +otvírák na konzervy a lžičku, +diplomatickou příručku, +šifrovací pomůcky +kyanidovou tabletku. + +Po shromáždění osobní výbavy se urychleně přesuňte k přetlakové komoře. + +Zde vám bude vydán skafandr, který si nasaďte před opuštěním lodi. + +Po opuštění lodi se přesuňte k nástupnímu prostoru únikového modulu a urychleně do něj nastupte. + +Únikový modul má kapacitu DESET osob. + +Do únikového modulu vkročte PRAVOU nohou. + +Unikový modul odlétá do PATNÁCTI minut od zahájení evakuace a v zájmu záchrany co největší části posádky na nikoho nečeká. + +Jakmile budete v bezpečí, řiďte se pokyny pro zjistění stavu lodi a příčiny evakuace. + + + + + +POKYNY V PŘÍPADĚ KONTAKTU S CIZÍ FORMOU ŽIVOTA + +Při komunikaci ujistěte cizí formu života, že sdělené názory jsou vaše vlastní a nereprezentují oficiální stanovisko Hegemonie člověka. + +V případě nenalezení společného jazyka využijte Braillovo písmo. + +Při konfliktu s formou života na bázi stroje pamatujte, že před kyBorkem neutečete. + + + + + +POKYNY PRO POUŽÍVÁNÍ TELEKOMUNIKAČNÍCH ZAŘÍZENÍ + +Je přísně zakázáno libovolné telekomunikační zařízení vypínat, odpojovat z rozvodné sítě či jinak narušovat jeho činnost! + +Dále je zakázáno měnit nastavení libovolného terminálu. +Při problémech se obraťte na vedení posádky či lodního síťaře. + +Nenechávejte vyvěšené sluchátko! + +V případě vypojení libovolného kabelu z terminálu DBEJTE ZVÝŠENÉ OPATRNOSTI! Terminály jsou netradičně napájeny z datových kabelů napětím 48V. + +Je zakázáno olizovat libovolné dráty. +Některé jsou pod napětím. +Navíc jsou ostré. + +Terminál může být použit k účelům všeobecné distribuce informace. + + + + + +POKYNY V PŘÍPADĚ NÁVŠTĚVY EXOPLANETY + +Tyto pokyny se vztahují pouze pro návštěvy exoplanet s prokazatelnou přítomností vyšších organismů. +Na exoplanetách s pouze bakteriálním životem či zcela bez biosféry se řiďte předpisy pro návštěvu asteroidů vyjma sekce 3 pokynů pro chování v mikrogravitaci. + +Při pohybu na exoplanetách dbejte zvýšené opatrnosti. + +Všichni členové posádky jsou povinni pohybovat se ve skupinách nejméně dvou osob. + +V případě výskytu inteligentního domorodého života omezte kontakt na minimum, není-li vedením lodi specifikováno jinak. + +Je doporučeno zahrnout do výbavy expedice šifrovací pomůcky. + +Každá skupina je povinna mít s sebou nejméně jeden měřič ionizujícího záření. diff --git a/hr_join.sh b/hr_join.sh new file mode 100755 index 0000000..64412fc --- /dev/null +++ b/hr_join.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +printf "file '%s'\n" hr/*.wav > hr_concat.txt +ffmpeg -f concat -safe 0 -i hr_concat.txt -c copy sounds/hr.wav + diff --git a/list_errors.sh b/list_errors.sh new file mode 100755 index 0000000..21a741b --- /dev/null +++ b/list_errors.sh @@ -0,0 +1,6 @@ +#!/bin/sh +pass=`sed -n 's/telnet_pass=//p' config.txt` +ip=`sed -n 's/server_ip=//p' config.txt | sed 's/\.[0-9]*$//'` +for i in `cat phones.txt | grep -v backup | grep -v \- | sed -n 's/^\([0-9][0-9]\).*/\1/p'`; do + admin_scripts/list_errors.pl "$ip.$i" "$pass" 2>&1 | sed '/^$/d' | sed "s/^/$i: /" +done diff --git a/list_errors_crontab b/list_errors_crontab new file mode 100644 index 0000000..8132124 --- /dev/null +++ b/list_errors_crontab @@ -0,0 +1 @@ +*/10 * * * * cd /opt/ksp; ./list_errors.sh | sed -E 's/172\.16\.0\.//;s/,? ?port 23//;s/ ?at .* line [0-9]*//' > /tmp/error.log.new; mv /tmp/error.log.new /tmp/error.log diff --git a/logo/anytoppm.sh b/logo/anytoppm.sh new file mode 100755 index 0000000..5d1018d --- /dev/null +++ b/logo/anytoppm.sh @@ -0,0 +1,54 @@ +#!/bin/bash -eu + +usage() { + echo >&2 "usage: $0 " + exit 1 +} + +[[ $# == 2 ]] || usage +FW_INFILE="$1" +FW_OUTFILE="$2" + +MIME=`file -b --mime-type "$FW_INFILE"` + +case $MIME in + image/gif) + giftopnm "$FW_INFILE" > "$FW_OUTFILE" 2>/dev/null + ;; + image/jpeg |\ + image/jpg) + jpegtopnm "$FW_INFILE" > "$FW_OUTFILE" 2>/dev/null + ;; + image/png) + pngtopnm "$FW_INFILE" > "$FW_OUTFILE" 2>/dev/null + ;; + image/x-ms-bmp |\ + image/bmp |\ + image/x-bmp |\ + image/x-bitmap |\ + image/x-xbitmap |\ + image/x-win-bitmap |\ + image/x-windows-bmp |\ + image/ms-bmp) + bmptoppm "$FW_INFILE" > "$FW_OUTFILE" 2>/dev/null + ;; + *) + echo "Unknown file contents. [$MIME]" >&2 + exit 1 + ;; +esac + +MIME2=`file -b --mime-type "$FW_OUTFILE"` +case $MIME2 in + image/x-portable-pixmap |\ + image/x-portable-bitmap |\ + image/x-portable-greymap) + #temporary file created +;; + *) + echo "Failed to convert file. [$MIME => $MIME2]" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/logo/hipporion.bmp b/logo/hipporion.bmp new file mode 100644 index 0000000..a69517f Binary files /dev/null and b/logo/hipporion.bmp differ diff --git a/logo/hipporion.png b/logo/hipporion.png new file mode 100644 index 0000000..6e65896 Binary files /dev/null and b/logo/hipporion.png differ diff --git a/logo/hipporion2.bmp b/logo/hipporion2.bmp new file mode 100644 index 0000000..7942142 Binary files /dev/null and b/logo/hipporion2.bmp differ diff --git a/logo/hipporion2.png b/logo/hipporion2.png new file mode 100644 index 0000000..adea342 Binary files /dev/null and b/logo/hipporion2.png differ diff --git a/logo/ksp.bmp b/logo/ksp.bmp new file mode 100644 index 0000000..34c3dd0 Binary files /dev/null and b/logo/ksp.bmp differ diff --git a/logo/logo b/logo/logo new file mode 100644 index 0000000..34c3dd0 Binary files /dev/null and b/logo/logo differ diff --git a/logo/logo.sh b/logo/logo.sh new file mode 100755 index 0000000..373a28a --- /dev/null +++ b/logo/logo.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -eu + +CONVERTED_FILE=processed.pnm +FW_INFILE="$1" +TARGET="$2" +./anytoppm.sh "$FW_INFILE" $CONVERTED_FILE || exit 1 + +#generate logo for the phone +PREVIEW=_preview.png +FW_IDENT=logo_sip + +case $FW_IDENT in + logo_sip) + # BMP 90x56 (8-bit), phone can display 4 colors + { cat $CONVERTED_FILE | pnmscale -width 90 -height 56 | ppmquant 4 | ./ppmfix.sh | ppmtobmp -bpp=8 > $TARGET; } 2>/dev/null + + #generate logo preview for Operator's Administration + { cat $TARGET | bmptopnm | ./ppmfix.sh | pnmtopng > $PREVIEW; } 2>/dev/null + ;; + logo_sep_bw) + # PNG 320x196 (8-bit), phone can display a 4 color PNG file + { cat $CONVERTED_FILE | pnmscale -width 320 -height 196 | ppmquant 4 | ./ppmfix.sh | pnmtopng > $TARGET; } 2>/dev/null + # BMP 80x49 (8-bit), phone can display a 4 color PNG file + { cat $CONVERTED_FILE | pnmscale -width 80 -height 49 | ppmquant 4 | ./ppmfix.sh | pnmtopng > $TARGET_TN; } 2>/dev/null + + #generate logo preview for Operator's Administration + cp $TARGET $PREVIEW + ;; + logo_sep_color) + # PNG 320x212 (12-bit) + { cat $CONVERTED_FILE | pnmscale -width 320 -height 212 | ppmquant 4096 | ./ppmfix.sh | pnmtopng > $TARGET; } 2>/dev/null + # PNG 80x53 (12-bit) + { cat $CONVERTED_FILE | pnmscale -width 80 -height 53 | ppmquant 4096 | ./ppmfix.sh | pnmtopng > $TARGET_TN; } 2>/dev/null + + #generate logo preview for Operator's Administration + cp $TARGET $PREVIEW + ;; + logo_sep_color_16) + # PNG 320x212 (16-bit) + { cat $CONVERTED_FILE | pnmscale -width 320 -height 212 | ppmquant 65536 | ./ppmfix.sh | pnmtopng > $TARGET; } 2>/dev/null + # PNG 80x53 (16-bit) + { cat $CONVERTED_FILE | pnmscale -width 80 -height 53 | ppmquant 65536 | ./ppmfix.sh | pnmtopng > $TARGET_TN; } 2>/dev/null + + #generate logo preview for Operator's Administration + cp $TARGET $PREVIEW + ;; + *) + echo "Unknown logo ident. [$FW_IDENT]" >&2 + exit 1 + ;; +esac + + + diff --git a/logo/ppmfix.sh b/logo/ppmfix.sh new file mode 100755 index 0000000..02c141d --- /dev/null +++ b/logo/ppmfix.sh @@ -0,0 +1,21 @@ +#!/usr/bin/gawk -f + +BEGIN { + fix = 0 +} + +NR == 3 && /^0$/ { + fix = 1 + print "1" + next +} + +fix == 0 { + print + next +} + +fix == 1 { + gsub(/\x00/, "\x01", $0) + print $0 +} diff --git a/message_receiver.pl b/message_receiver.pl new file mode 100755 index 0000000..f2a524a --- /dev/null +++ b/message_receiver.pl @@ -0,0 +1,58 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use DBI; +use Encode; +use Net::SIP; +use Net::SIP::Util qw(sip_hdrval2parts sip_uri2parts); + +my $addr = $ARGV[0]; +my $port = $ARGV[1]; +my $dbfile = $ARGV[2]; + +die "Usage: $0 listen_address listen_port database_file\n" unless $addr and $port and $dbfile; + +my $dbh = DBI->connect("DBI:SQLite:$dbfile", undef, undef, { PrintError => 0, RaiseError => 1, sqlite_unicode => 1 }); + +my $leg = Net::SIP::Leg->new(proto => 'udp', addr => $addr, port => $port) or die "Error: Cannot create leg: $!\n"; +my $ua = Net::SIP::Simple->new(from => '', leg => $leg) or die "Error: Cannot create user agent: $!\n"; + +$dbh->do('CREATE TABLE IF NOT EXISTS messages(id INTEGER PRIMARY KEY AUTOINCREMENT, r INT NOT NULL DEFAULT 0, f TEXT NOT NULL, t TEXT NOT NULL, m TEXT NOT NULL)'); +$dbh->do('CREATE INDEX IF NOT EXISTS idx ON messages(r, t)'); + +$ua->{endpoint}->set_application(sub { + my ($endpoint, $ctx, $packet, $leg, $from_addr) = @_; + + return unless $packet->is_request; + + my $resp; + if ($packet->method eq 'MESSAGE') { + my (undef, $for, undef, $message) = $packet->as_parts; + $message = decode('UTF-8', $message); + my $for_user = (sip_uri2parts($for))[1]; + my ($from) = $packet->get_header('from'); + ($from) = sip_hdrval2parts(from => $from); + + print "Recevied message for user $for_user from uri: $from\n"; + + my $success = eval { $dbh->do('INSERT INTO messages(f, t, m) VALUES(?, ?, ?)', undef, $from, $for_user, $message) }; + + if ($success) { + $resp = $packet->create_response('200', 'OK'); + } else { + $resp = $packet->create_response('500', $dbh->errstr); + } + } elsif ($packet->method eq 'OPTIONS') { + $resp = $packet->create_response('200', 'OK'); + } else { + $resp = $packet->create_response('606', 'Not Acceptable'); + } + + $resp->set_header('Allow' => 'OPTIONS, MESSAGE'); + $endpoint->new_response($ctx, $resp, $leg, $from_addr); + $endpoint->close_context($ctx); +}); + +$ua->loop(); diff --git a/message_receiver.service b/message_receiver.service new file mode 100644 index 0000000..fc79019 --- /dev/null +++ b/message_receiver.service @@ -0,0 +1,4 @@ +[Service] +ExecStart=/usr/bin/perl /opt/ksp/message_receiver.pl 172.16.0.1 5062 /tmp/messages.db +[Install] +WantedBy=multi-user.target diff --git a/normalize_volume_all.sh b/normalize_volume_all.sh new file mode 100755 index 0000000..cd13821 --- /dev/null +++ b/normalize_volume_all.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +vol=9 + + +cd /opt/ksp +. config.txt +ip_prefix=${server_ip%.*} +./hangup_all.sh +sleep 1 +cat phones.txt | awk '{print $1}' | grep '^[2-5]' | xargs -i -n1 -P0 ./admin_scripts/normalize_volume.pl "$ip_prefix.{}" "$telnet_pass" "$vol" + diff --git a/phones.txt b/phones.txt new file mode 100644 index 0000000..8db7f95 --- /dev/null +++ b/phones.txt @@ -0,0 +1,40 @@ +# LINE MAC ALIAS NAME + +# org +21 00:0c:85:b9:8d:72 org1 Org 1 +22 00:0a:41:9e:70:4c org2 Org 2 +23 00:1d:a2:66:e1:1b org3 Org 3 +24 00:1e:be:90:7a:1a org4 Org 4 +25 - lodni_kocka Lodní kočka # Medvěd + +# non-org +31 00:0a:8a:2c:8c:d2 prechod_komora Přechodová komora # botnik +32 00:0c:85:b9:8d:47 kontam_komora_0 Kontaminační komora 0 # wc přízemí +33 00:1b:d4:60:6e:3f lodni_kaple_1 Lodní kaple 1 # jedalen1 +34 00:1d:a2:66:e1:0b lodni_kaple_2 Lodní kaple 2 # jedalen2 +35 00:0c:85:b9:8d:57 unikovy_vychod Únikový východ # chodba +36 00:0a:41:f9:77:32 xenobio_lab_1 Xenobiologická laboratoř 1 # jedalen1 mala +37 00:1e:f7:c2:28:66 xenobio_lab_2 Xenobiologická laboratoř 2 # jedalen2 mala +38 00:0c:85:b9:8d:50 odd_inkub_techn Oddělení inkubačních techn. # izba 6.c +39 00:0c:85:b9:8a:63 odd_appl_noem Oddělení aplikované noematiky # izba 5 +40 00:17:0e:c8:52:bf chodba_0 Chodba 0 # chodba +41 00:1d:a2:66:e0:cc odd_rela_efekt Oddělení relat. efektů # izba 4 +42 00:1b:d4:5f:f3:33 odd_auto_agrik Oddělení autonomní agrikultury # izba 3 +43 00:0c:85:3b:ba:84 dekontam_sprcha Dekontaminační sprcha # sprchy +44 00:0c:85:b9:8d:5e kontam_komora_1 Kontaminační komora 1 # wc 1. patro +45 00:0a:8a:2c:8d:73 odd_civil_vycvik Oddělení civilizačního výcviku # izba 7 +46 00:1e:be:90:79:ea odd_psycho Oddělení psychoakustiky # izba 8 +47 00:0a:8a:21:57:38 serverovna Serverovna # switch +48 00:0c:85:48:c9:c3 sklad_nebez_odpad Sklad nebezpečného odpadu # schody +49 00:0c:85:8d:18:2d chodba_1 Chodba 1 # chodba +50 00:17:0e:c8:50:d2 odd_abstr_umeni Oddělení abstraktního umění # izba 1 +51 00:0c:85:8d:16:13 odd_dezinfo Oddělení dezinformace # izba 2 + +56 00:0a:8a:21:51:bc backup1 backup1 +57 00:0a:8a:66:49:8e backup2 backup2 +58 00:0a:8a:2c:8d:0b backup3 backup3 +59 00:0a:41:f9:79:2a backup4 backup4 + +# dead +#00:0a:8a:2c:8f:f1 +#00:0a:8a:2c:8d:74 diff --git a/pocasi.py b/pocasi.py new file mode 100755 index 0000000..8032e13 --- /dev/null +++ b/pocasi.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +import xml.etree.ElementTree as ET +from datetime import datetime as dt +from urllib import request + +xml = request.urlopen('https://www.yr.no/place/Czech_Republic/Olomouc/Ruda_nad_Moravou/forecast.xml').read() + +root = ET.fromstring(xml) +days = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] + +for time in root.iter('time'): + attrib = time.attrib + time_from = dt.strptime(attrib['from'], '%Y-%m-%dT%H:%M:%S') + time_to = dt.strptime(attrib['to'], '%Y-%m-%dT%H:%M:%S') + style = time.find('symbol').attrib + temperature = time.find('temperature').attrib + preci = time.find('precipitation') + output = days[time_from.weekday()] + time_from.strftime(' %H') + '-' + time_to.strftime("%Hh") + ': ' + temperature['value'] + '°C' + ', ' + style['name'] + print(output.replace('Partly', 'Pt.')) diff --git a/rand_line.sh b/rand_line.sh new file mode 100755 index 0000000..ac902c3 --- /dev/null +++ b/rand_line.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +cd "$(dirname "$0")" +myself="$1" +[[ -n "$myself" ]] || myself=xxx +cat phones.txt | grep -E '^[3-5]' | cut -d' ' -f1 | grep -vFx "$myself" | sort -R | head -n 1 + diff --git a/sounds/heslo.wav b/sounds/heslo.wav new file mode 100644 index 0000000..5fadbe3 Binary files /dev/null and b/sounds/heslo.wav differ diff --git a/sounds/klapka.wav b/sounds/klapka.wav new file mode 100644 index 0000000..fd77418 Binary files /dev/null and b/sounds/klapka.wav differ diff --git a/sounds/spatne_heslo.wav b/sounds/spatne_heslo.wav new file mode 100644 index 0000000..dfb33d8 Binary files /dev/null and b/sounds/spatne_heslo.wav differ diff --git a/tftp/Dialplan.xml b/tftp/Dialplan.xml new file mode 100644 index 0000000..955cfd9 --- /dev/null +++ b/tftp/Dialplan.xml @@ -0,0 +1,17 @@ + +