From 4a0f2d370b15c6355bd7147864bcfe775ca3b823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 1 Oct 2019 19:01:56 +0200 Subject: [PATCH] Initial commit --- admin_scripts/auto_answer.pl | 59 +++ admin_scripts/erase_config.pl | 25 ++ admin_scripts/force_reboot.pl | 24 ++ admin_scripts/list_errors.pl | 23 + admin_scripts/normalize_volume.pl | 29 ++ admin_scripts/send_reboot.pl | 54 +++ admin_scripts/volume_up.pl | 33 ++ all_reboot.sh | 6 + ann_end.sh | 14 + ann_end_all.sh | 11 + ann_listen.sh | 21 + ann_listen_all.sh | 5 + ann_play.sh | 30 ++ ann_play_unicast.sh | 36 ++ ann_stop.sh | 18 + ann_volup.sh | 18 + autoanswer_all.sh | 15 + autoanswer_line.sh | 12 + cislovaci_plan | 24 ++ clean.sh | 2 + config.txt | 4 + conv_ring.sh | 8 + etc_asterisk/confbridge.conf | 22 + etc_asterisk/extensions.lua | 141 +++++++ etc_asterisk/logger.conf | 3 + etc_asterisk/manager.conf | 11 + etc_asterisk/modules.conf | 73 ++++ etc_asterisk/pjsip.conf | 10 + etc_asterisk/pjsip_wizard.conf | 36 ++ etc_asterisk/voicemail.conf | 6 + etc_dnsmasq.d/dhcp.conf | 6 + etc_dnsmasq.d/phones_tftp.conf | 4 + gen.pl | 174 ++++++++ gen_hr.sh | 11 + gen_sounds.sh | 16 + hangup_all.sh | 12 + hr.txt | 179 ++++++++ hr_join.sh | 5 + list_errors.sh | 6 + list_errors_crontab | 1 + logo/anytoppm.sh | 54 +++ logo/hipporion.bmp | Bin 0 -> 6230 bytes logo/hipporion.png | Bin 0 -> 797 bytes logo/hipporion2.bmp | Bin 0 -> 6230 bytes logo/hipporion2.png | Bin 0 -> 777 bytes logo/ksp.bmp | Bin 0 -> 6230 bytes logo/logo | Bin 0 -> 6230 bytes logo/logo.sh | 55 +++ logo/ppmfix.sh | 21 + message_receiver.pl | 58 +++ message_receiver.service | 4 + normalize_volume_all.sh | 12 + phones.txt | 40 ++ pocasi.py | 20 + rand_line.sh | 7 + sounds/heslo.wav | Bin 0 -> 19662 bytes sounds/klapka.wav | Bin 0 -> 28494 bytes sounds/spatne_heslo.wav | Bin 0 -> 21198 bytes tftp/Dialplan.xml | 17 + tftp/RingTones/Piano.pcm | 9 + tftp/SIPDefault.cnf | 230 ++++++++++ tftp/syncinfo.xml | 3 + tftp_reflash/XMLDefault.cnf.xml | 26 ++ toilet_paper.sh | 25 ++ tts.sh | 3 + wc_thanks.sh | 5 + webapp/directory.psgi | 157 +++++++ webapp/directory.service | 4 + webapp/directory.uwsgi | 6 + webapp/hraj.pl | 33 ++ webapp/hraj.service | 4 + webapp/hraj.uwsgi | 7 + webapp/services.psgi | 676 ++++++++++++++++++++++++++++++ webapp/services.service | 4 + webapp/services.uwsgi | 6 + www/directory_external.txt | 13 + www/logo.bmp | Bin 0 -> 6230 bytes www/orgovia.txt | 2 + www/osoby.txt | 2 + www/tovar.txt | 34 ++ znelky/.keep | 0 81 files changed, 2724 insertions(+) create mode 100755 admin_scripts/auto_answer.pl create mode 100755 admin_scripts/erase_config.pl create mode 100755 admin_scripts/force_reboot.pl create mode 100755 admin_scripts/list_errors.pl create mode 100755 admin_scripts/normalize_volume.pl create mode 100755 admin_scripts/send_reboot.pl create mode 100755 admin_scripts/volume_up.pl create mode 100755 all_reboot.sh create mode 100755 ann_end.sh create mode 100755 ann_end_all.sh create mode 100755 ann_listen.sh create mode 100755 ann_listen_all.sh create mode 100755 ann_play.sh create mode 100755 ann_play_unicast.sh create mode 100755 ann_stop.sh create mode 100755 ann_volup.sh create mode 100755 autoanswer_all.sh create mode 100755 autoanswer_line.sh create mode 100644 cislovaci_plan create mode 100755 clean.sh create mode 100644 config.txt create mode 100755 conv_ring.sh create mode 100644 etc_asterisk/confbridge.conf create mode 100644 etc_asterisk/extensions.lua create mode 100644 etc_asterisk/logger.conf create mode 100644 etc_asterisk/manager.conf create mode 100644 etc_asterisk/modules.conf create mode 100644 etc_asterisk/pjsip.conf create mode 100644 etc_asterisk/pjsip_wizard.conf create mode 100644 etc_asterisk/voicemail.conf create mode 100644 etc_dnsmasq.d/dhcp.conf create mode 100644 etc_dnsmasq.d/phones_tftp.conf create mode 100755 gen.pl create mode 100755 gen_hr.sh create mode 100755 gen_sounds.sh create mode 100755 hangup_all.sh create mode 100644 hr.txt create mode 100755 hr_join.sh create mode 100755 list_errors.sh create mode 100644 list_errors_crontab create mode 100755 logo/anytoppm.sh create mode 100644 logo/hipporion.bmp create mode 100644 logo/hipporion.png create mode 100644 logo/hipporion2.bmp create mode 100644 logo/hipporion2.png create mode 100644 logo/ksp.bmp create mode 100644 logo/logo create mode 100755 logo/logo.sh create mode 100755 logo/ppmfix.sh create mode 100755 message_receiver.pl create mode 100644 message_receiver.service create mode 100755 normalize_volume_all.sh create mode 100644 phones.txt create mode 100755 pocasi.py create mode 100755 rand_line.sh create mode 100644 sounds/heslo.wav create mode 100644 sounds/klapka.wav create mode 100644 sounds/spatne_heslo.wav create mode 100644 tftp/Dialplan.xml create mode 100644 tftp/RingTones/Piano.pcm create mode 100644 tftp/SIPDefault.cnf create mode 100644 tftp/syncinfo.xml create mode 100644 tftp_reflash/XMLDefault.cnf.xml create mode 100644 toilet_paper.sh create mode 100755 tts.sh create mode 100755 wc_thanks.sh create mode 100755 webapp/directory.psgi create mode 100644 webapp/directory.service create mode 100644 webapp/directory.uwsgi create mode 100644 webapp/hraj.pl create mode 100644 webapp/hraj.service create mode 100644 webapp/hraj.uwsgi create mode 100755 webapp/services.psgi create mode 100644 webapp/services.service create mode 100644 webapp/services.uwsgi create mode 100644 www/directory_external.txt create mode 100644 www/logo.bmp create mode 100644 www/orgovia.txt create mode 100644 www/osoby.txt create mode 100644 www/tovar.txt create mode 100644 znelky/.keep 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 0000000000000000000000000000000000000000..a69517f962768a8ba7ab86b4ef7b5e2dfecc59cf GIT binary patch literal 6230 zcmeH}OHKnZ42Gu?3y#1MI00hKo-GURe~;p~o!AbYJ~q_^wd4G@KReE-;_Lh8ZKL(^ zvTg5R{le!HKBw)K^zQ3?K6kD|KPGTY;E5-2df0;BorkUGW&5kPcX-R0IM%Hl1r}`K z3C!t>l(BFh2(U2}cUB?0vQhyks&yzovu343bUNpA`!j3aH;i&1LoVS5C2d-EicG@4 z^c&c6v#F*D4cq*;7|ymg4*qL`KV5F=3j&IY6v!8gAeSjSu*Cz)rECf1=L8dP7;;l=gLBoh|elG7Ui! z@!d`AbW|!B=gkp8(Svv@bf7C(X8N3{RSOLP#MBz$_?V#aZb7t)ZcS{Bn7WniT_4_e zjm2JT&!|>Wl{RG2AO@w}RGdnik}slHoJyP6dUZ(-LWwEGkR&Gc-pAIL(#OvQ1Yg{2 zO~&KSjKyB@_~bBA>KqNKy;+U;B^Xlovbma7$i;(l9XkLP=E2Uxv6+|=W8ltkYgacK z6j|mmLtR2)QND?U_K5VI_#`|%7HmVe@N3!JUFyXJ2)K$Z$97O*?P3ei9}aYFu%z!n z;|-;Tc~2ou?(R|mQ=Y?nwtAK~3HTCC$x48T+^8s{FNC!wXDD*chdnOJ)@O@K4$kP< zdR9!sBE@22;UJ0fEQF2ltuae@!$yqu?M8qjl!HnFMV20&Wn|sgw!ZI+l_Na>D#)Yn IJlk#i1C6T`tpET3 literal 0 HcmV?d00001 diff --git a/logo/hipporion.png b/logo/hipporion.png new file mode 100644 index 0000000000000000000000000000000000000000..6e65896ee799ac410092d3ca5df6912bfbf2f757 GIT binary patch literal 797 zcmV+&1LFLNP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;2FkAZe8V00NCkL_t(|UhS2EZfhY7L;L?f-IZyPtjIXr zHUw_Rku2_;O#pAwdpr*%oT7_3MHg|3F5(nj#3{N6S@h%a_*Eu0lg&jhTMU-V5Tn~- zwDBr9uQ!)vvczDyEP19EjdM^QmdR2NmdzA0t!Uiu#fbd7(0fOE(YVh`F`C<*-aCeh z&QJu~lO+YqX9<~J^cC3tEHPLvOP=XPn?_-Kv*cl!3^9g^z5?#^T7f!WdD)~Fjo=Ja zCF)$|Wiz#C17}4uSvE@^T&30i=n)1YEC(vqN_MX z7jcR%;_HgW{{VYh!EK9X1-`2aZdEiZNvQ|Rnr5+m(X0$q7BgldTNaIv_L|MCv$iT4 zABn1F#<^P*jit_bQ(^qoJ#0pP0~ay2)Se|P4U*-=*c;VEtNh%9S(-^*Yg$}$m{jbu4o z6{A_@ho`j7BeJZmN(S>#27dRj4DRi+8P`=*zA{ySXj9(*0bB&f&GVq&W zzTcx{;5S40dgmdHDMkCggk7+Ep{n>7MPsq6?l!gP6%Ru29;@#&?c`Mt!%|VJnR3y#1MI00hKo-GURe~;pSJF%U%)3N|f5FO|F`HSPJ;N$b_Wux`> zv~8~teZ%iN{GPUF(z}oI`P`)r{g}Wpfqy)K(}m?%zhF#h_`B0D$9mMeQ)a;yo|HI! zQ8MCtBfv&0?(Bq|%1Q+wSDR3NX3a{6=ya~<_Gi|-Zy4o3hFZc8O4_vSo6^4StGk6>L!}{TBEGweovum;#(A?N zD0&eug${Iu$U>hJwQAO2Af}!Xu8#%k_Xyl7dNi@sF?B23hd#XT8jHQwnNh7=l{Qq- zAO@w}RGdniim#$qoJyP6`s$J#gc4JVp-4jNz4z8HrT5PV2)=l;H5sovGZuTrmxH?`3m$sTUW(u!}9%c2E)B#1^1G9O&8*N#BFU8!8R+o-9u8-lYJhI*0dc z%`D#};7c?WD*+t2QBlTRu(csqC~~fcJua%&XNyV+uISi$S1iLrip9htK@!!Og@f>^ zo+Z3tBS!o7AixpIrjkI;GNZGMtjEUI_hYegrC)#w^5{Fy_L#{rlRSZ}{N3-#57ZD8 Av;Y7A literal 0 HcmV?d00001 diff --git a/logo/hipporion2.png b/logo/hipporion2.png new file mode 100644 index 0000000000000000000000000000000000000000..adea342f741d728b235ec1c75371b266f7171ccc GIT binary patch literal 777 zcmV+k1NQuhP)N2bZe?^J zG%heMGBNQWX_Wu~0)|OMK~#8N?UI3RBq0n#_y2!-Z#gxR6&Z)wCSj)HNfy)E1aSL$ zA6hs?H*tz?;uPJ)DY}VMbQ7oOCQi{!oT8gJMK^JZZsHW(#3{OoQ*;xu=-2D@UzylU zHW$5YF<34`jA@I}#;f4G*<6;%5`*Qkj6D71;hPF<353p7NqitFXOU@~}*X7)wQ80rz?B zK%K9=Y|@KHa0aRqb*}QVDJ|N-STmNivz`=VJHs4OaGBDX9WAMI65)mgVH z8Xt-3rsCXN6pf`;Jn|c|@3HkoSZwygeoOX!w!I9?&3sT6+4s8N3;!r#(JOyd%itPm zC5JE{WiZdna)$T45ayc{+Wim>K_AyhS8@a9p$z7ES&)(O8(oKS7t|9<%g$?%`393;e9WIc__<7U^bHF za8;~kl^>omHm}ICwkjFSLmBuz!!o$v3$dU5?-{FE<%g$?&2j+vevP=2Q(5$9IX?sQ zvpoa!Rc;{X{H#;(AO`w=jabbM?3|el{Ptkh?@==Fo1uKY^FuUzU>UzgtmXzIt7PCe z!+gI-$-r-h^7YO`8YM;h|AgJxeNf$$7QN#^2;O7&eacSW^)M_IwVTo#bUhLa^|}k? zH>r3u&YbCPwA_dlVN$TX(w%9&9V_QIdJ@}j%L-(AHt+X8c5|frbPWC&00000NkvXX Hu0mjfH@amx literal 0 HcmV?d00001 diff --git a/logo/ksp.bmp b/logo/ksp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..34c3dd0f23fd0fd4e14ef8235b742d81410df529 GIT binary patch literal 6230 zcmeH}OL8IyX5jW^ zqI>7dB-p3KE*Ky`@b|9uZd0(Ij^jz9hX*IGONO<6z$%2i8Q_gR!Zy#{K5rY0$4><={bmB`m_9>T) z%1N-TxE+F&MP_LO?y)9XABGGgcsS3s6Nmp!?$)LRhhkg$DvN_-@_FO*!*%>KOfpp)9U5C1EZCw@)$|!zz{x|IW;4(&QsPcba&U20`&MjjuYs`hrn^iCuAylF zX$_{Q)DRQGBW&%*RfXe8GdM=1Y`q6}E)9y8?1E_Lgs?Vv4KEH!P!R)JT;V4nymUq^rl?EZ4d_U!p_lyTnJ)H*^-jFkYtU8XUPg4l{sk$ zws=5GEcKJ{Sw|cpH(VyvAs3n*H1?KrDfw{6CTud2Ja?=;Wf6?amt0U0yl%2FPbO`z zoOoRRTyH7(4)L+p>ItQkkK;SE6CBcGb$Dl08oX_!hyVvd4>+b5X>js5Hwc@mS)AbB z$5EM0zG3ZOsM<=<>{(U@JHEg!8?iB5m(E>x8E2t3T%t5~HLQ>qXrP*gT4{!g%X^;y zU$htOa2v4&krph8{Smfwn|rO?u*>g&hMu$Pc-*8>g^9R@*-8PSd>6(&qWSYmiM}q}>q;(-)UO*l#{z2qAI|*?@ z3Z{5e@P$0ok67O8R^H=&oL&ZYc77%!SKfUx$Awmk`rkaB`T*S%y=dTFp~AL#_Mkf= zrA($iRm%miYd47dACjHVV6dz2XYdv_jJ#*@5-UCZdE8Ob{%_aK)B{9G$=k$L(|eLlMP-$9(}V9$Atgng&` QwBjA?Pvbn=@U__g07TRzIyX5jW^ zqI>7dB-p3KE*Ky`@b|9uZd0(Ij^jz9hX*IGONO<6z$%2i8Q_gR!Zy#{K5rY0$4><={bmB`m_9>T) z%1N-TxE+F&MP_LO?y)9XABGGgcsS3s6Nmp!?$)LRhhkg$DvN_-@_FO*!*%>KOfpp)9U5C1EZCw@)$|!zz{x|IW;4(&QsPcba&U20`&MjjuYs`hrn^iCuAylF zX$_{Q)DRQGBW&%*RfXe8GdM=1Y`q6}E)9y8?1E_Lgs?Vv4KEH!P!R)JT;V4nymUq^rl?EZ4d_U!p_lyTnJ)H*^-jFkYtU8XUPg4l{sk$ zws=5GEcKJ{Sw|cpH(VyvAs3n*H1?KrDfw{6CTud2Ja?=;Wf6?amt0U0yl%2FPbO`z zoOoRRTyH7(4)L+p>ItQkkK;SE6CBcGb$Dl08oX_!hyVvd4>+b5X>js5Hwc@mS)AbB z$5EM0zG3ZOsM<=<>{(U@JHEg!8?iB5m(E>x8E2t3T%t5~HLQ>qXrP*gT4{!g%X^;y zU$htOa2v4&krph8{Smfwn|rO?u*>g&hMu$Pc-*8>g^9R@*-8PSd>6(&qWSYmiM}q}>q;(-)UO*l#{z2qAI|*?@ z3Z{5e@P$0ok67O8R^H=&oL&ZYc77%!SKfUx$Awmk`rkaB`T*S%y=dTFp~AL#_Mkf= zrA($iRm%miYd47dACjHVV6dz2XYdv_jJ#*@5-UCZdE8Ob{%_aK)B{9G$=k$L(|eLlMP-$9(}V9$Atgng&` QwBjA?Pvbn=@U__g07TRz $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 0000000000000000000000000000000000000000..5fadbe3bc7bb23c80c768b7af41e86f0d62b95c5 GIT binary patch literal 19662 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 literal 0 HcmV?d00001 diff --git a/sounds/klapka.wav b/sounds/klapka.wav new file mode 100644 index 0000000000000000000000000000000000000000..fd7741888d7293cd0a4eb189c72811c1a2a2eb1b GIT binary patch literal 28494 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

^oEml^nH%-xnggnz7#19l#;j-W-!y6 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 +