From 87bc1d7a25512e669092e1d8ff165d939cde7549 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Wed, 3 Aug 2022 22:26:07 +0200
Subject: [PATCH 1/9] Add SIP registration string

This string contains user, password and registry (Sipgate). Instead of building
the rules around this, it is added as a whole string to the vault.
---
 inventory.yml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/inventory.yml b/inventory.yml
index d9459f3..c1bc095 100644
--- a/inventory.yml
+++ b/inventory.yml
@@ -88,6 +88,14 @@ all:
       server_admin: "admin+platon@netz39.de"
       mac: "b8:27:eb:8f:98:2f"
       gatekeeper_user: pi
+      gatekeeper_sip_registration:  !vault |
+        $ANSIBLE_VAULT;1.1;AES256
+        31306464613437343762323366393132323231306362393762636361353230353632333834663430
+        3133663661396566623664323134353737643039646263320a333434326561383962643739346265
+        61376631393266393737306261393137353364353637623335386663613834373233633264316130
+        3931316365663739380a616334626264376164376165346263353366363234646462383637383034
+        62343231636664623938356233363137383166306232373063306362366265333061623532393066
+        6261613435373465336463376431366164373538376465343031
     radon.n39.eu:
       server_admin: "admin+radon@netz39.de"
     krypton.n39.eu:

From b17e1ad25886c477bff91e968e14d331302607aa Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Wed, 3 Aug 2022 22:37:45 +0200
Subject: [PATCH 2/9] Add template for Asterisk extensions

---
 templates/platon/extensions.conf.j2 | 130 ++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)
 create mode 100644 templates/platon/extensions.conf.j2

diff --git a/templates/platon/extensions.conf.j2 b/templates/platon/extensions.conf.j2
new file mode 100644
index 0000000..9bfaf55
--- /dev/null
+++ b/templates/platon/extensions.conf.j2
@@ -0,0 +1,130 @@
+; extensions.conf - the Asterisk dial plan
+;
+; Static extension configuration file, used by
+; the pbx_config module. This is where you configure all your
+; inbound and outbound calls in Asterisk.
+;
+; This configuration file is reloaded
+; - With the "dialplan reload" command in the CLI
+; - With the "reload" command (that reloads everything) in the CLI
+
+;
+; The "General" category is for certain variables.
+;
+[general]
+;
+; If static is set to no, or omitted, then the pbx_config will rewrite
+; this file when extensions are modified.  Remember that all comments
+; made in the file will be lost when that happens.
+;
+; XXX Not yet implemented XXX
+;
+static=yes
+;
+; if static=yes and writeprotect=no, you can save dialplan by
+; CLI command "dialplan save" too
+;
+writeprotect=yes
+;
+; If autofallthrough is set, then if an extension runs out of
+; things to do, it will terminate the call with BUSY, CONGESTION
+; or HANGUP depending on Asterisk's best guess. This is the default.
+;
+; If autofallthrough is not set, then if an extension runs out of
+; things to do, Asterisk will wait for a new extension to be dialed
+; (this is the original behavior of Asterisk 1.0 and earlier).
+;
+;autofallthrough=no
+;
+;
+;
+; If clearglobalvars is set, global variables will be cleared
+; and reparsed on a dialplan reload, or Asterisk reload.
+;
+; If clearglobalvars is not set, then global variables will persist
+; through reloads, and even if deleted from the extensions.conf or
+; one of its included files, will remain set to the previous value.
+;
+; NOTE: A complication sets in, if you put your global variables into
+; the AEL file, instead of the extensions.conf file. With clearglobalvars
+; set, a "reload" will often leave the globals vars cleared, because it
+; is not unusual to have extensions.conf (which will have no globals)
+; load after the extensions.ael file (where the global vars are stored).
+; So, with "reload" in this particular situation, first the AEL file will
+; clear and then set all the global vars, then, later, when the extensions.conf
+; file is loaded, the global vars are all cleared, and then not set, because
+; they are not stored in the extensions.conf file.
+;
+clearglobalvars=no
+;
+; User context is where entries from users.conf are registered.  The
+; default value is 'default'
+;
+;userscontext=default
+;
+; You can include other config files, use the #include command
+; (without the ';'). Note that this is different from the "include" command
+; that includes contexts within other contexts. The #include command works
+; in all asterisk configuration files.
+;#include "filename.conf"
+;#include <filename.conf>
+;#include filename.conf
+;
+; You can execute a program or script that produces config files, and they
+; will be inserted where you insert the #exec command. The #exec command
+; works on all asterisk configuration files.  However, you will need to
+; activate them within asterisk.conf with the "execincludes" option.  They
+; are otherwise considered a security risk.
+;#exec /opt/bin/build-extra-contexts.sh
+;#exec /opt/bin/build-extra-contexts.sh --foo="bar"
+;#exec </opt/bin/build-extra-contexts.sh --foo="bar">
+;#exec "/opt/bin/build-extra-contexts.sh --foo=\"bar\""
+;
+
+; The "Globals" category contains global variables that can be referenced
+; in the dialplan with the GLOBAL dialplan function:
+; ${GLOBAL(VARIABLE)}
+; ${${GLOBAL(VARIABLE)}} or ${text${GLOBAL(VARIABLE)}} or any hybrid
+; Unix/Linux environmental variables can be reached with the ENV dialplan
+; function: ${ENV(VARIABLE)}
+;
+[globals]
+
+;;; Dialplans
+
+[default]
+
+;; get the caller ID as number
+exten => s,1, Set(cid=${CALLERID(number)})
+exten => s,n, Verbose(2,Incoming call from ${cid})
+exten => s,n, Answer
+exten => s,n, Playback(silence/1)
+;; welcome message
+;exten => s,n, Playback(n39/welcome)
+exten => s,n, Playback(custom/n39/hello)
+;; get the PIN
+exten => s,n, Read(pin)
+;; check PIN and CID
+exten => s,n, Set(access=${SHELL( /home/{{ gatekeeper_user }}/netz39_rollladensteuerung/raspberry/asterisk/door-phone-auth.sh ${cid} ${pin} /home/{{ gatekeeper_user }}/phone-whitelist.txt )})
+exten => s,n, NoOp(Access result: ${access})
+exten => s,n, GotoIf($[ "${access}" = "OK" ]?granted:failed)
+exten => s,n, Hangup()
+
+;; access granted
+exten => s,100(granted), noop()
+;exten => s,n, Playback(n39/accessgranted)
+exten => s,n, System({{ door_open_command }})
+exten => s,n, Playback(custom/n39/granted)
+exten => s,n, Goto(done)
+
+;; access failed
+exten => s,200(failed), noop()
+;exten => s,n, Playback(n39/youcannotpass)
+exten => s,n, Playback(custom/n39/denied)
+exten => s,n, Goto(done)
+
+;; done
+exten => s,300(done), noop()
+exten => s,n, Hangup()
+
+

From 51c1f9860996b84b7f5ce7e3d2ae9a46cc61cb50 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Wed, 3 Aug 2022 22:37:53 +0200
Subject: [PATCH 3/9] Add template for SIP configuration

---
 templates/platon/sip.conf.j2 | 642 +++++++++++++++++++++++++++++++++++
 1 file changed, 642 insertions(+)
 create mode 100644 templates/platon/sip.conf.j2

diff --git a/templates/platon/sip.conf.j2 b/templates/platon/sip.conf.j2
new file mode 100644
index 0000000..a01b3c6
--- /dev/null
+++ b/templates/platon/sip.conf.j2
@@ -0,0 +1,642 @@
+; SIP Configuration for Asterisk
+
+[general]
+context=default                 ; Default context for incoming calls
+allowguest=yes                   ; Allow or reject guest calls (default is yes)
+				; If your Asterisk is connected to the Internet
+				; and you have allowguest=yes
+				; you want to check which services you offer everyone
+				; out there, by enabling them in the default context (see below).
+;match_auth_username=yes        ; if available, match user entry using the
+                                ; 'username' field from the authentication line
+                                ; instead of the From: field.
+allowoverlap=no                 ; Disable overlap dialing support. (Default is yes)
+;allowoverlap=yes               ; Enable RFC3578 overlap dialing support.
+                                ; Can use the Incomplete application to collect the
+                                ; needed digits from an ambiguous dialplan match.
+;allowoverlap=dtmf              ; Enable overlap dialing support using DTMF delivery
+                                ; methods (inband, RFC2833, SIP INFO) in the early
+                                ; media phase.  Uses the Incomplete application to
+                                ; collect the needed digits.
+;allowtransfer=no               ; Disable all transfers (unless enabled in peers or users)
+                                ; Default is enabled. The Dial() options 't' and 'T' are not
+                                ; related as to whether SIP transfers are allowed or not.
+;realm=mydomain.tld             ; Realm for digest authentication
+                                ; defaults to "asterisk". If you set a system name in
+                                ; asterisk.conf, it defaults to that system name
+                                ; Realms MUST be globally unique according to RFC 3261
+                                ; Set this to your host name or domain name
+;domainsasrealm=no              ; Use domains list as realms
+                                ; You can serve multiple Realms specifying several
+                                ; 'domain=...' directives (see below). 
+                                ; In this case Realm will be based on request 'From'/'To' header
+                                ; and should match one of domain names.
+                                ; Otherwise default 'realm=...' will be used.
+
+
+udpbindaddr=0.0.0.0             ; IP address to bind UDP listen socket to (0.0.0.0 binds to all)
+                                ; Optionally add a port number, 192.168.1.1:5062 (default is port 5060)
+
+
+                                tcpenable=no                    ; Enable server for incoming TCP connections (default is no)
+tcpbindaddr=0.0.0.0             ; IP address for TCP server to bind to (0.0.0.0 binds to all interfaces)
+                                ; Optionally add a port number, 192.168.1.1:5062 (default is port 5060)
+
+;tlsenable=no                   ; Enable server for incoming TLS (secure) connections (default is no)
+;tlsbindaddr=0.0.0.0            ; IP address for TLS server to bind to (0.0.0.0) binds to all interfaces)
+                                ; Optionally add a port number, 192.168.1.1:5063 (default is port 5061)
+                                ; Remember that the IP address must match the common name (hostname) in the
+                                ; certificate, so you don't want to bind a TLS socket to multiple IP addresses.
+                                ; For details how to construct a certificate for SIP see 
+                                ; http://tools.ietf.org/html/draft-ietf-sip-domain-certs
+
+;tcpauthtimeout = 30            ; tcpauthtimeout specifies the maximum number
+				; of seconds a client has to authenticate.  If
+				; the client does not authenticate beofre this
+				; timeout expires, the client will be
+                                ; disconnected. (default: 30 seconds)
+
+;tcpauthlimit = 100             ; tcpauthlimit specifies the maximum number of
+				; unauthenticated sessions that will be allowed
+                                ; to connect at any given time. (default: 100)
+
+transport=udp                   ; Set the default transports.  The order determines the primary default transport.
+                                ; If tcpenable=no and the transport set is tcp, we will fallback to UDP.
+
+srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
+                                ; Note: Asterisk only uses the first host
+                                ; in SRV records
+                                ; Disabling DNS SRV lookups disables the
+                                ; ability to place SIP calls based on domain
+                                ; names to some other SIP users on the Internet
+                                ; Specifying a port in a SIP peer definition or
+                                ; when dialing outbound calls will supress SRV
+                                ; lookups for that peer or call.
+
+;pedantic=yes                   ; Enable checking of tags in headers,
+                                ; international character conversions in URIs
+                                ; and multiline formatted headers for strict
+                                ; SIP compatibility (defaults to "yes")
+
+; See https://wiki.asterisk.org/wiki/display/AST/IP+Quality+of+Service for a description of these parameters.
+;tos_sip=cs3                    ; Sets TOS for SIP packets.
+;tos_audio=ef                   ; Sets TOS for RTP audio packets.
+;tos_video=af41                 ; Sets TOS for RTP video packets.
+;tos_text=af41                  ; Sets TOS for RTP text packets.
+
+;cos_sip=3                      ; Sets 802.1p priority for SIP packets.
+;cos_audio=5                    ; Sets 802.1p priority for RTP audio packets.
+;cos_video=4                    ; Sets 802.1p priority for RTP video packets.
+;cos_text=3                     ; Sets 802.1p priority for RTP text packets.
+
+;maxexpiry=3600                 ; Maximum allowed time of incoming registrations
+                                ; and subscriptions (seconds)
+;minexpiry=60                   ; Minimum length of registrations/subscriptions (default 60)
+;defaultexpiry=120              ; Default length of incoming/outgoing registration
+;mwiexpiry=3600                 ; Expiry time for outgoing MWI subscriptions
+;maxforwards=70			; Setting for the SIP Max-Forwards: header (loop prevention)
+				; Default value is 70
+;qualifyfreq=60                 ; Qualification: How often to check for the host to be up in seconds
+				; and reported in milliseconds with sip show settings.
+                                ; Set to low value if you use low timeout for NAT of UDP sessions
+				; Default: 60
+;qualifygap=100			; Number of milliseconds between each group of peers being qualified
+				; Default: 100
+;qualifypeers=1			; Number of peers in a group to be qualified at the same time
+				; Default: 1
+;notifymimetype=text/plain      ; Allow overriding of mime type in MWI NOTIFY
+;buggymwi=no                    ; Cisco SIP firmware doesn't support the MWI RFC
+                                ; fully. Enable this option to not get error messages
+                                ; when sending MWI to phones with this bug.
+;mwi_from=asterisk              ; When sending MWI NOTIFY requests, use this setting in
+                                ; the From: header as the "name" portion. Also fill the
+			        ; "user" portion of the URI in the From: header with this
+			        ; value if no fromuser is set
+			        ; Default: empty
+;vmexten=voicemail              ; dialplan extension to reach mailbox sets the
+                                ; Message-Account in the MWI notify message
+                                ; defaults to "asterisk"
+
+; Codec negotiation
+;
+; When Asterisk is receiving a call, the codec will initially be set to the
+; first codec in the allowed codecs defined for the user receiving the call
+; that the caller also indicates that it supports. But, after the caller
+; starts sending RTP, Asterisk will switch to using whatever codec the caller
+; is sending.
+;
+; When Asterisk is placing a call, the codec used will be the first codec in
+; the allowed codecs that the callee indicates that it supports. Asterisk will
+; *not* switch to whatever codec the callee is sending.
+;
+preferred_codec_only=yes       ; Respond to a SIP invite with the single most preferred codec
+                                ; rather than advertising all joint codec capabilities. This
+                                ; limits the other side's codec choice to exactly what we prefer.
+
+;disallow=all                   ; First disallow all codecs
+allow=alaw
+allow=ulaw                     ; Allow codecs in order of preference
+allow=ilbc                     ; see https://wiki.asterisk.org/wiki/display/AST/RTP+Packetization
+				; for framing options
+;
+; This option specifies a preference for which music on hold class this channel
+; should listen to when put on hold if the music class has not been set on the
+; channel with Set(CHANNEL(musicclass)=whatever) in the dialplan, and the peer
+; channel putting this one on hold did not suggest a music class.
+;
+; This option may be specified globally, or on a per-user or per-peer basis.
+;
+;mohinterpret=default
+;
+; This option specifies which music on hold class to suggest to the peer channel
+; when this channel places the peer on hold. It may be specified globally or on
+; a per-user or per-peer basis.
+;
+;mohsuggest=default
+;
+;parkinglot=plaza               ; Sets the default parking lot for call parking
+                                ; This may also be set for individual users/peers
+                                ; Parkinglots are configured in features.conf
+;language=en                    ; Default language setting for all users/peers
+                                ; This may also be set for individual users/peers
+;relaxdtmf=yes                  ; Relax dtmf handling
+;trustrpid = no                 ; If Remote-Party-ID should be trusted
+;sendrpid = yes                 ; If Remote-Party-ID should be sent (defaults to no)
+;sendrpid = rpid                ; Use the "Remote-Party-ID" header
+                                ; to send the identity of the remote party
+                                ; This is identical to sendrpid=yes
+;sendrpid = pai                 ; Use the "P-Asserted-Identity" header
+                                ; to send the identity of the remote party
+;rpid_update = no               ; In certain cases, the only method by which a connected line
+                                ; change may be immediately transmitted is with a SIP UPDATE request.
+                                ; If communicating with another Asterisk server, and you wish to be able
+                                ; transmit such UPDATE messages to it, then you must enable this option.
+                                ; Otherwise, we will have to wait until we can send a reinvite to
+                                ; transmit the information.
+;prematuremedia=no              ; Some ISDN links send empty media frames before 
+                                ; the call is in ringing or progress state. The SIP 
+                                ; channel will then send 183 indicating early media
+                                ; which will be empty - thus users get no ring signal.
+                                ; Setting this to "yes" will stop any media before we have
+                                ; call progress (meaning the SIP channel will not send 183 Session
+                                ; Progress for early media). Default is "yes". Also make sure that
+                                ; the SIP peer is configured with progressinband=never. 
+                                ;
+                                ; In order for "noanswer" applications to work, you need to run
+                                ; the progress() application in the priority before the app.
+
+;progressinband=never           ; If we should generate in-band ringing always
+                                ; use 'never' to never use in-band signalling, even in cases
+                                ; where some buggy devices might not render it
+                                ; Valid values: yes, no, never Default: never
+useragent=N39 Door PBX          ; Allows you to change the user agent string
+                                ; The default user agent string also contains the Asterisk
+                                ; version. If you don't want to expose this, change the
+                                ; useragent string.
+;promiscredir = no              ; If yes, allows 302 or REDIR to non-local SIP address
+                                ; Note that promiscredir when redirects are made to the
+                                ; local system will cause loops since Asterisk is incapable
+                                ; of performing a "hairpin" call.
+;usereqphone = no               ; If yes, ";user=phone" is added to uri that contains
+                                ; a valid phone number
+;dtmfmode = rfc2833             ; Set default dtmfmode for sending DTMF. Default: rfc2833
+                                ; Other options:
+                                ; info : SIP INFO messages (application/dtmf-relay)
+                                ; shortinfo : SIP INFO messages (application/dtmf)
+                                ; inband : Inband audio (requires 64 kbit codec -alaw, ulaw)
+                                ; auto : Use rfc2833 if offered, inband otherwise
+
+;compactheaders = yes           ; send compact sip headers.
+;
+;videosupport=yes               ; Turn on support for SIP video. You need to turn this
+                                ; on in this section to get any video support at all.
+                                ; You can turn it off on a per peer basis if the general
+                                ; video support is enabled, but you can't enable it for
+                                ; one peer only without enabling in the general section.
+                                ; If you set videosupport to "always", then RTP ports will
+                                ; always be set up for video, even on clients that don't
+                                ; support it.  This assists callfile-derived calls and
+                                ; certain transferred calls to use always use video when
+                                ; available. [yes|NO|always]
+
+;maxcallbitrate=384             ; Maximum bitrate for video calls (default 384 kb/s)
+                                ; Videosupport and maxcallbitrate is settable
+                                ; for peers and users as well
+;callevents=no                  ; generate manager events when sip ua
+                                ; performs events (e.g. hold)
+;authfailureevents=no           ; generate manager "peerstatus" events when peer can't
+                                ; authenticate with Asterisk. Peerstatus will be "rejected".
+alwaysauthreject = yes         ; When an incoming INVITE or REGISTER is to be rejected,
+                                ; for any reason, always reject with an identical response
+                                ; equivalent to valid username and invalid password/hash
+                                ; instead of letting the requester know whether there was
+                                ; a matching user or peer for their request.  This reduces
+                                ; the ability of an attacker to scan for valid SIP usernames.
+                                ; This option is set to "yes" by default.
+
+;auth_options_requests = yes    ; Enabling this option will authenticate OPTIONS requests just like
+                                ; INVITE requests are.  By default this option is disabled.
+
+;g726nonstandard = yes          ; If the peer negotiates G726-32 audio, use AAL2 packing
+                                ; order instead of RFC3551 packing order (this is required
+                                ; for Sipura and Grandstream ATAs, among others). This is
+                                ; contrary to the RFC3551 specification, the peer _should_
+                                ; be negotiating AAL2-G726-32 instead :-(
+;dynamic_exclude_static = yes   ; Disallow all dynamic hosts from registering
+                                ; as any IP address used for staticly defined
+                                ; hosts.  This helps avoid the configuration
+                                ; error of allowing your users to register at
+                                ; the same address as a SIP provider.
+
+;contactdeny=0.0.0.0/0.0.0.0           ; Use contactpermit and contactdeny to
+;contactpermit=172.16.0.0/255.255.0.0  ; restrict at what IPs your users may
+                                       ; register their phones.
+contactpermit=172.23.48.0/255.255.252.0
+
+
+;engine=asterisk                ; RTP engine to use when communicating with the device
+
+;
+; If regcontext is specified, Asterisk will dynamically create and destroy a
+; NoOp priority 1 extension for a given peer who registers or unregisters with
+; us and have a "regexten=" configuration item.
+; Multiple contexts may be specified by separating them with '&'. The
+; actual extension is the 'regexten' parameter of the registering peer or its
+; name if 'regexten' is not provided.  If more than one context is provided,
+; the context must be specified within regexten by appending the desired
+; context after '@'.  More than one regexten may be supplied if they are
+; separated by '&'.  Patterns may be used in regexten.
+;
+;regcontext=sipregistrations
+;regextenonqualify=yes          ; Default "no"
+                                ; If you have qualify on and the peer becomes unreachable
+                                ; this setting will enforce inactivation of the regexten
+                                ; extension for the peer
+;legacy_useroption_parsing=yes	; Default "no"      ; If you have this option enabled and there are semicolons
+                                                    ; in the user field of a sip URI, the field be truncated
+                                                    ; at the first semicolon seen. This effectively makes
+                                                    ; semicolon a non-usable character for peer names, extensions,
+                                                    ; and maybe other, less tested things.  This can be useful
+                                                    ; for improving compatability with devices that like to use
+                                                    ; user options for whatever reason.  The behavior is similar to
+                                                    ; how SIP URI's were typically handled in 1.6.2, hence the name.
+
+; The shrinkcallerid function removes '(', ' ', ')', non-trailing '.', and '-' not
+; in square brackets.  For example, the caller id value 555.5555 becomes 5555555
+; when this option is enabled.  Disabling this option results in no modification
+; of the caller id value, which is necessary when the caller id represents something
+; that must be preserved.  This option can only be used in the [general] section.
+; By default this option is on.
+;
+;shrinkcallerid=yes     ; on by default
+
+
+;use_q850_reason = no ; Default "no"
+                      ; Set to yes add Reason header and use Reason header if it is available.
+
+;--------------------------- SIP timers ----------------------------------------------------
+; These timers are used primarily in INVITE transactions.
+; The default for Timer T1 is 500 ms or the measured run-trip time between
+; Asterisk and the device if you have qualify=yes for the device.
+;
+;t1min=100                      ; Minimum roundtrip time for messages to monitored hosts
+                                ; Defaults to 100 ms
+;timert1=500                    ; Default T1 timer
+                                ; Defaults to 500 ms or the measured round-trip
+                                ; time to a peer (qualify=yes).
+;timerb=32000                   ; Call setup timer. If a provisional response is not received
+                                ; in this amount of time, the call will autocongest
+                                ; Defaults to 64*timert1
+
+;--------------------------- RTP timers ----------------------------------------------------
+; These timers are currently used for both audio and video streams. The RTP timeouts
+; are only applied to the audio channel.
+; The settings are settable in the global section as well as per device
+;
+;rtptimeout=60                  ; Terminate call if 60 seconds of no RTP or RTCP activity
+                                ; on the audio channel
+                                ; when we're not on hold. This is to be able to hangup
+                                ; a call in the case of a phone disappearing from the net,
+                                ; like a powerloss or grandma tripping over a cable.
+;rtpholdtimeout=300             ; Terminate call if 300 seconds of no RTP or RTCP activity
+                                ; on the audio channel
+                                ; when we're on hold (must be > rtptimeout)
+;rtpkeepalive=<secs>            ; Send keepalives in the RTP stream to keep NAT open
+                                ; (default is off - zero)
+
+;--------------------------- SIP Session-Timers (RFC 4028)------------------------------------
+; SIP Session-Timers provide an end-to-end keep-alive mechanism for active SIP sessions.
+; This mechanism can detect and reclaim SIP channels that do not terminate through normal
+; signaling procedures. Session-Timers can be configured globally or at a user/peer level.
+; The operation of Session-Timers is driven by the following configuration parameters:
+;
+; * session-timers    - Session-Timers feature operates in the following three modes:
+;                            originate : Request and run session-timers always
+;                            accept    : Run session-timers only when requested by other UA
+;                            refuse    : Do not run session timers in any case
+;                       The default mode of operation is 'accept'.
+; * session-expires   - Maximum session refresh interval in seconds. Defaults to 1800 secs.
+; * session-minse     - Minimum session refresh interval in seconds. Defualts to 90 secs.
+; * session-refresher - The session refresher (uac|uas). Defaults to 'uas'.
+;
+;session-timers=originate
+;session-expires=600
+;session-minse=90
+;session-refresher=uas
+;
+;--------------------------- SIP DEBUGGING ---------------------------------------------------
+;sipdebug = yes                 ; Turn on SIP debugging by default, from
+                                ; the moment the channel loads this configuration
+;recordhistory=yes              ; Record SIP history by default
+                                ; (see sip history / sip no history)
+;dumphistory=yes                ; Dump SIP history at end of SIP dialogue
+                                ; SIP history is output to the DEBUG logging channel
+
+
+;--------------------------- STATUS NOTIFICATIONS (SUBSCRIPTIONS) ----------------------------
+; You can subscribe to the status of extensions with a "hint" priority
+; (See extensions.conf.sample for examples)
+; chan_sip support two major formats for notifications: dialog-info and SIMPLE
+;
+; You will get more detailed reports (busy etc) if you have a call counter enabled
+; for a device.
+;
+; If you set the busylevel, we will indicate busy when we have a number of calls that
+; matches the busylevel treshold.
+;
+; For queues, you will need this level of detail in status reporting, regardless
+; if you use SIP subscriptions. Queues and manager use the same internal interface
+; for reading status information.
+;
+; Note: Subscriptions does not work if you have a realtime dialplan and use the
+; realtime switch.
+;
+;allowsubscribe=no              ; Disable support for subscriptions. (Default is yes)
+;subscribecontext = default     ; Set a specific context for SUBSCRIBE requests
+                                ; Useful to limit subscriptions to local extensions
+                                ; Settable per peer/user also
+;notifyringing = no             ; Control whether subscriptions already INUSE get sent
+                                ; RINGING when another call is sent (default: yes)
+;notifyhold = yes               ; Notify subscriptions on HOLD state (default: no)
+                                ; Turning on notifyringing and notifyhold will add a lot
+                                ; more database transactions if you are using realtime.
+;notifycid = yes                ; Control whether caller ID information is sent along with
+                                ; dialog-info+xml notifications (supported by snom phones).
+                                ; Note that this feature will only work properly when the
+                                ; incoming call is using the same extension and context that
+                                ; is being used as the hint for the called extension.  This means
+                                ; that it won't work when using subscribecontext for your sip
+                                ; user or peer (if subscribecontext is different than context).
+                                ; This is also limited to a single caller, meaning that if an
+                                ; extension is ringing because multiple calls are incoming,
+                                ; only one will be used as the source of caller ID.  Specify
+                                ; 'ignore-context' to ignore the called context when looking
+                                ; for the caller's channel.  The default value is 'no.' Setting
+                                ; notifycid to 'ignore-context' also causes call-pickups attempted
+                                ; via SNOM's NOTIFY mechanism to set the context for the call pickup
+                                ; to PICKUPMARK.
+;callcounter = yes              ; Enable call counters on devices. This can be set per
+                                ; device too.
+
+;----------------------------------------- OUTBOUND SIP REGISTRATIONS  ------------------------
+; Asterisk can register as a SIP user agent to a SIP proxy (provider)
+
+register => {{ gatekeeper_sip_registration }}/s
+;
+;     This will pass incoming calls to the 's' extension
+
+;----------------------------------- MEDIA HANDLING --------------------------------
+; By default, Asterisk tries to re-invite media streams to an optimal path. If there's
+; no reason for Asterisk to stay in the media path, the media will be redirected.
+; This does not really work well in the case where Asterisk is outside and the
+; clients are on the inside of a NAT. In that case, you want to set directmedia=nonat.
+;
+;directmedia=yes                ; Asterisk by default tries to redirect the
+                                ; RTP media stream to go directly from
+                                ; the caller to the callee.  Some devices do not
+                                ; support this (especially if one of them is behind a NAT).
+                                ; The default setting is YES. If you have all clients
+                                ; behind a NAT, or for some other reason want Asterisk to
+                                ; stay in the audio path, you may want to turn this off.
+
+                                ; This setting also affect direct RTP
+                                ; at call setup (a new feature in 1.4 - setting up the
+                                ; call directly between the endpoints instead of sending
+                                ; a re-INVITE).
+
+                                ; Additionally this option does not disable all reINVITE operations.
+                                ; It only controls Asterisk generating reINVITEs for the specific
+                                ; purpose of setting up a direct media path. If a reINVITE is
+                                ; needed to switch a media stream to inactive (when placed on
+                                ; hold) or to T.38, it will still be done, regardless of this 
+                                ; setting. Note that direct T.38 is not supported.
+
+;directmedia=nonat              ; An additional option is to allow media path redirection
+                                ; (reinvite) but only when the peer where the media is being
+                                ; sent is known to not be behind a NAT (as the RTP core can
+                                ; determine it based on the apparent IP address the media
+                                ; arrives from).
+
+;directmedia=update             ; Yet a third option... use UPDATE for media path redirection,
+                                ; instead of INVITE. This can be combined with 'nonat', as
+                                ; 'directmedia=update,nonat'. It implies 'yes'.
+
+;directrtpsetup=yes             ; Enable the new experimental direct RTP setup. This sets up
+                                ; the call directly with media peer-2-peer without re-invites.
+                                ; Will not work for video and cases where the callee sends
+                                ; RTP payloads and fmtp headers in the 200 OK that does not match the
+                                ; callers INVITE. This will also fail if directmedia is enabled when
+                                ; the device is actually behind NAT.
+
+;directmediadeny=0.0.0.0/0      ; Use directmediapermit and directmediadeny to restrict 
+;directmediapermit=172.16.0.0/16; which peers should be able to pass directmedia to each other
+                                ; (There is no default setting, this is just an example)
+                                ; Use this if some of your phones are on IP addresses that
+                                ; can not reach each other directly. This way you can force 
+                                ; RTP to always flow through asterisk in such cases.
+
+;ignoresdpversion=yes           ; By default, Asterisk will honor the session version
+                                ; number in SDP packets and will only modify the SDP
+                                ; session if the version number changes. This option will
+                                ; force asterisk to ignore the SDP session version number
+                                ; and treat all SDP data as new data.  This is required
+                                ; for devices that send us non standard SDP packets
+                                ; (observed with Microsoft OCS). By default this option is
+                                ; off.
+
+;sdpsession=Asterisk PBX        ; Allows you to change the SDP session name string, (s=)
+                                ; Like the useragent parameter, the default user agent string
+                                ; also contains the Asterisk version.
+;sdpowner=root                  ; Allows you to change the username field in the SDP owner string, (o=)
+                                ; This field MUST NOT contain spaces
+;encryption=no                  ; Whether to offer SRTP encrypted media (and only SRTP encrypted media)
+                                ; on outgoing calls to a peer. Calls will fail with HANGUPCAUSE=58 if
+                                ; the peer does not support SRTP. Defaults to no.
+
+;----------------------------------------- REALTIME SUPPORT ------------------------
+; For additional information on ARA, the Asterisk Realtime Architecture,
+; please read https://wiki.asterisk.org/wiki/display/AST/Realtime+Database+Configuration
+;
+;rtcachefriends=yes             ; Cache realtime friends by adding them to the internal list
+                                ; just like friends added from the config file only on a
+                                ; as-needed basis? (yes|no)
+
+;rtsavesysname=yes              ; Save systemname in realtime database at registration
+                                ; Default= no
+
+;rtupdate=yes                   ; Send registry updates to database using realtime? (yes|no)
+                                ; If set to yes, when a SIP UA registers successfully, the ip address,
+                                ; the origination port, the registration period, and the username of
+                                ; the UA will be set to database via realtime.
+                                ; If not present, defaults to 'yes'. Note: realtime peers will
+                                ; probably not function across reloads in the way that you expect, if
+                                ; you turn this option off.
+;rtautoclear=yes                ; Auto-Expire friends created on the fly on the same schedule
+                                ; as if it had just registered? (yes|no|<seconds>)
+                                ; If set to yes, when the registration expires, the friend will
+                                ; vanish from the configuration until requested again. If set
+                                ; to an integer, friends expire within this number of seconds
+                                ; instead of the registration interval.
+
+;ignoreregexpire=yes            ; Enabling this setting has two functions:
+                                ;
+                                ; For non-realtime peers, when their registration expires, the
+                                ; information will _not_ be removed from memory or the Asterisk database
+                                ; if you attempt to place a call to the peer, the existing information
+                                ; will be used in spite of it having expired
+                                ;
+                                ; For realtime peers, when the peer is retrieved from realtime storage,
+                                ; the registration information will be used regardless of whether
+                                ; it has expired or not; if it expires while the realtime peer
+                                ; is still in memory (due to caching or other reasons), the
+                                ; information will not be removed from realtime storage
+
+;----------------------------------------- SIP DOMAIN SUPPORT ------------------------
+; Incoming INVITE and REFER messages can be matched against a list of 'allowed'
+; domains, each of which can direct the call to a specific context if desired.
+; By default, all domains are accepted and sent to the default context or the
+; context associated with the user/peer placing the call.
+; REGISTER to non-local domains will be automatically denied if a domain
+; list is configured.
+;
+; Domains can be specified using:
+; domain=<domain>[,<context>]
+; Examples:
+; domain=myasterisk.dom
+; domain=customer.com,customer-context
+;
+; In addition, all the 'default' domains associated with a server should be
+; added if incoming request filtering is desired.
+; autodomain=yes
+;
+; To disallow requests for domains not serviced by this server:
+; allowexternaldomains=no
+
+;domain=mydomain.tld,mydomain-incoming
+                                ; Add domain and configure incoming context
+                                ; for external calls to this domain
+;domain=1.2.3.4                 ; Add IP address as local domain
+                                ; You can have several "domain" settings
+;allowexternaldomains=no        ; Disable INVITE and REFER to non-local domains
+                                ; Default is yes
+;autodomain=yes                 ; Turn this on to have Asterisk add local host
+                                ; name and local IP to domain list.
+
+; fromdomain=mydomain.tld       ; When making outbound SIP INVITEs to
+                                ; non-peers, use your primary domain "identity"
+                                ; for From: headers instead of just your IP
+                                ; address. This is to be polite and
+                                ; it may be a mandatory requirement for some
+                                ; destinations which do not have a prior
+                                ; account relationship with your server.
+
+;------------------------------ Advice of Charge CONFIGURATION --------------------------
+; snom_aoc_enabled = yes;     ; This options turns on and off support for sending AOC-D and
+                              ; AOC-E to snom endpoints.  This option can be used both in the
+                              ; peer and global scope.  The default for this option is off.
+
+
+;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
+; jbenable = yes              ; Enables the use of a jitterbuffer on the receiving side of a
+                              ; SIP channel. Defaults to "no". An enabled jitterbuffer will
+                              ; be used only if the sending side can create and the receiving
+                              ; side can not accept jitter. The SIP channel can accept jitter,
+                              ; thus a jitterbuffer on the receive SIP side will be used only
+                              ; if it is forced and enabled.
+
+; jbforce = no                ; Forces the use of a jitterbuffer on the receive side of a SIP
+                              ; channel. Defaults to "no".
+
+; jbmaxsize = 200             ; Max length of the jitterbuffer in milliseconds.
+
+; jbresyncthreshold = 1000    ; Jump in the frame timestamps over which the jitterbuffer is
+                              ; resynchronized. Useful to improve the quality of the voice, with
+                              ; big jumps in/broken timestamps, usually sent from exotic devices
+                              ; and programs. Defaults to 1000.
+
+; jbimpl = fixed              ; Jitterbuffer implementation, used on the receiving side of a SIP
+                              ; channel. Two implementations are currently available - "fixed"
+                              ; (with size always equals to jbmaxsize) and "adaptive" (with
+                              ; variable size, actually the new jb of IAX2). Defaults to fixed.
+
+; jbtargetextra = 40          ; This option only affects the jb when 'jbimpl = adaptive' is set.
+                              ; The option represents the number of milliseconds by which the new jitter buffer
+                              ; will pad its size. the default is 40, so without modification, the new
+                              ; jitter buffer will set its size to the jitter value plus 40 milliseconds.
+                              ; increasing this value may help if your network normally has low jitter,
+                              ; but occasionally has spikes.
+
+; jblog = no                  ; Enables jitterbuffer frame logging. Defaults to "no".
+
+;----------------------------- SIP_CAUSE reporting ---------------------------------
+; storesipcause = no          ; This option causes chan_sip to set the
+			      ; HASH(SIP_CAUSE,<channel name>) channel variable
+			      ; to the value of the last sip response.
+			      ; WARNING: enabling this option carries a
+			      ; significant performance burden. It should only
+			      ; be used in low call volume situations. This
+                              ; option defaults to "no".
+
+;-----------------------------------------------------------------------------------
+
+[authentication]
+; Global credentials for outbound calls, i.e. when a proxy challenges your
+; Asterisk server for authentication. These credentials override
+; any credentials in peer/register definition if realm is matched.
+;
+; This way, Asterisk can authenticate for outbound calls to other
+; realms. We match realm on the proxy challenge and pick an set of
+; credentials from this list
+; Syntax:
+;        auth = <user>:<secret>@<realm>
+;        auth = <user>#<md5secret>@<realm>
+; Example:
+;auth=mark:topsecret@digium.com
+;
+; You may also add auth= statements to [peer] definitions
+; Peer auth= override all other authentication settings if we match on realm
+
+
+[basic-options](!)                ; a template
+        dtmfmode=rfc2833
+        context=from-office
+        type=friend
+
+[natted-phone](!,basic-options)   ; another template inheriting basic-options
+        directmedia=no
+        host=dynamic
+
+[public-phone](!,basic-options)   ; another template inheriting basic-options
+        directmedia=yes
+
+[my-codecs](!)                    ; a template for my preferred codecs
+        disallow=all
+        allow=ilbc
+        allow=g729
+        allow=gsm
+        allow=g723
+        allow=ulaw
+
+[ulaw-phone](!)                   ; and another one for ulaw-only
+        disallow=all
+        allow=ulaw

From 0013e29c97bf07b103b0830511826baea87df7c8 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Wed, 3 Aug 2022 22:42:41 +0200
Subject: [PATCH 4/9] Install the necessary asterisk packages

---
 platon.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/platon.yml b/platon.yml
index adad5b9..30d4a6e 100644
--- a/platon.yml
+++ b/platon.yml
@@ -30,6 +30,8 @@
           - mpg123
           - mosquitto
           - i2c-tools
+          - asterisk
+          - asterisk-mp3
 
 
     - name: Set MAC address for proper DHCP recognition

From 49a5224e83a24c21a88b07f2e1fada204614f3b2 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Wed, 3 Aug 2022 22:46:12 +0200
Subject: [PATCH 5/9] Add restart handler for asterisk

---
 platon.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/platon.yml b/platon.yml
index 30d4a6e..dc57bc2 100644
--- a/platon.yml
+++ b/platon.yml
@@ -257,3 +257,9 @@
         name: rsyslog
         state: restarted
         enabled: yes
+
+    - name: restart asterisk
+      service:
+        name: asterisk
+        state: restarted
+        enabled: yes

From 9a5303c216a018fa46219fca58073bd737b1d045 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Wed, 3 Aug 2022 22:46:22 +0200
Subject: [PATCH 6/9] Set up configuration templates for Asterisk

---
 platon.yml | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/platon.yml b/platon.yml
index dc57bc2..0eefe60 100644
--- a/platon.yml
+++ b/platon.yml
@@ -245,6 +245,30 @@
         mode: "0644"
       notify: restart rsyslog
 
+
+    ### Asterisk
+
+    - name: Set up SIP settings for asterisk
+      # This uses the variable gatekeeper_sip_registration
+      ansible.builtin.template:
+        src: templates/platon/sip.conf.j2
+        dest: /etc/asterisk/sip.conf
+        owner: root
+        group: root
+        mode: "0644"
+      notify: restart asterisk
+
+    - name: Set up extensions for asterisk
+      # This uses the variables gatekeeper_user and door_open_command
+      ansible.builtin.template:
+        src: templates/platon/extensions.conf.j2
+        dest: /etc/asterisk/extensions.conf
+        owner: root
+        group: root
+        mode: "0644"
+      notify: restart asterisk
+
+
   handlers:
     - name: restart mosquitto
       service:

From e1fb88c32b422039b317207c37a550b7b58711b2 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Thu, 4 Aug 2022 00:00:11 +0200
Subject: [PATCH 7/9] Add asterisk user to the right group

---
 platon.yml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/platon.yml b/platon.yml
index 0eefe60..20569b3 100644
--- a/platon.yml
+++ b/platon.yml
@@ -268,6 +268,13 @@
         mode: "0644"
       notify: restart asterisk
 
+    - name: Ensure asterisk is in the right groups
+      ansible.builtin.user:
+        name: asterisk
+        groups: audio,i2c,gpio
+        append: yes
+      notify: restart asterisk
+
 
   handlers:
     - name: restart mosquitto

From d90e6269ca416f6d3d0e1d28290f158f9d0944fb Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Thu, 4 Aug 2022 23:30:37 +0200
Subject: [PATCH 8/9] Add the Asterisk sound files

---
 files/platon/accessgranted.gsm | Bin 0 -> 2145 bytes
 files/platon/denied.gsm        | Bin 0 -> 7986 bytes
 files/platon/granted.gsm       | Bin 0 -> 1650 bytes
 files/platon/hello.gsm         | Bin 0 -> 6204 bytes
 files/platon/welcome.gsm       | Bin 0 -> 12870 bytes
 files/platon/youcannotpass.gsm | Bin 0 -> 4290 bytes
 6 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 files/platon/accessgranted.gsm
 create mode 100644 files/platon/denied.gsm
 create mode 100644 files/platon/granted.gsm
 create mode 100644 files/platon/hello.gsm
 create mode 100644 files/platon/welcome.gsm
 create mode 100644 files/platon/youcannotpass.gsm

diff --git a/files/platon/accessgranted.gsm b/files/platon/accessgranted.gsm
new file mode 100644
index 0000000000000000000000000000000000000000..8bef92caf3eea106656870d9a0a23086fa6966f5
GIT binary patch
literal 2145
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
YTL|?RHFH9MUsn6S7X9sN{y#MQ7iC-uP5=M^

literal 0
HcmV?d00001

diff --git a/files/platon/denied.gsm b/files/platon/denied.gsm
new file mode 100644
index 0000000000000000000000000000000000000000..bb5787400527ebfbf620f5c6739721cae994d4a7
GIT binary patch
literal 7986
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

literal 0
HcmV?d00001

diff --git a/files/platon/granted.gsm b/files/platon/granted.gsm
new file mode 100644
index 0000000000000000000000000000000000000000..0d6f5bd46aa885412202032198aa23352fa44cf3
GIT binary patch
literal 1650
zcmbuASyWR80*0Y;IuFG&=V+Z%g~-X~f(xCovZ?hXIA%d@4G=;Sw%ice8jxUUg`OH*
z+JXd4*n`-6FG&!Hu|`acwHme%jA*l5NVqX(xuI-U>129lI(?X#_rA^3|MH#h?K{5*
z4+nXtVwhwlll;5m`M-e$(J(vicip9UI$3N^@RC>v+H5hRdInNsne1@3OQg`jmCR$E
z6_Zv>{9yBZ2v`Vlhw9Zzz?+Xf5_dh?diU*X>*pP_JgtHA(JULead8L4CFNd{qH(&g
z^-94Dp6+5<{yu5yt;`vL@UVC;)btD<(d30^bDV5)xlg|9JKdxgCw}MeLjbejGj+;b
zf6F@(cIalfR)nzyoo;=5-XL|-+(m}e7k<@N6IDntUjwqOdY{}($_~C3v-U&q_;XRk
z==C?iOHnOZh4dd>+yytiE)tJouw_M}hzM=?EsI6R_h5M1ZdQ625%eO!3ckKdY{Q;X
z7(Rs!#qe~Tl8#%UFfgetJh!$Q9QYK<`antZ$}gXF8PX1XHvV=r&vQu|l<)h9zF}c#
zZJpRXu{qFooLn8UX$v**GQs#Gvv}j@V^zoJoi}`^qhg{mW<c08b@(ae=4fSb?;PGb
zs<<CDfYTk-(`vLF6T?=S=qt{V?J{sRUOvmU$NU;Nw<UU&YSk&cnG2OqaY?5jT6B}O
zR6zAs@GK8s5!3dtRAs}kskG%US#Ez_D3Gl#{6Z0P`|FF#!t%$P9VE}l{xfR#rHq6s
zO&t<1O~k+a1I<-<D7Raf`c1VF?Sa*ttNADf-$~}tdC2uDPDz;1(pdi>)J-+1mZvuL
z5k~sq)N4OxCS$d<D+o_Gx5UbfMp#puZ@~Zb%d;1jf|VxWjx8WmwyNLK>hYg(RK5o6
zCu)t)2dMP<Yvt<J;8cVD*ruO?AFzkG!G*}`KYA9yo4b4M34X#$zQpGI7HZ7>))N^A
zk<))V38N(JTyT~!p%EuJx&@6#rD>Wk2`PmQOroFip7zEn-xv9Ah@k>MM<nUd0EN4)
zZ3Y(#FiB!l(h{D#_rI~sk$&?h^oMA^+Uc)P#j^G)^3Vo|xl?5*cvE5@Z5}=9+=1%Q
zn`7oj3UwB*>Bz8@O2{4i_}#gI{A}oOxX87^xj3-Q%K?%{3|2u->{mtX@Cg>7x3s3`
zP9#(AI%kFua$N){JbEi<JuUY7K#}$dAnPVJ+*5X44id`-I@B3%SU8l_37if!pRoGI
zX(6Wn6CZ?Rzh4(Y38v#+`g`t|4KUD7OmCf)3OnE0vGd}CzIH(~7eNUA3nq7+)`jp@
z&Z<C2vi52}9Jmn09I0^Rtv{~aqFrYZ{;X%-DMUE!sv%bJiLdS8zgSdG@kV$~6B{>R
zo9q~*_TonKAh)j<tr#j9+@{n%*EJ=Qjcz4}uqRiUJi*70ueZ#ooy8A+=J6?>to3Q!
zeObrP*^}7Az+~rTI{^UaMHNQCnP^XqpQh+gL%Q1<D2d7!f;Mm(SHtj?2WUTt_YfV$
z4^yB@8RtNShV(4Jj5iv2Ph{NPDq0w@Fx(Ql5KV+YgWF;!)s|!VC5NOgH0AsS=3fDi
zPtw%9y(WY7f)vIJ+s61OQcaOJV~x09w(iSo+L_!xQUElaB-1jkdRB)wG}>g3i?YW@
zmI8OTrIZ0n_!-idGo@YuBXp_rLsw7fPvyL(!pHYy8w+Hru{*Yoaq8c0GndJtlJ3?j
ziP{za$#6hKU?$}4`sN9ESFGr<KZTANB(|`7ESLX<X`l1O*<{cifLFJhQ3qvYdqq0`
znQUsMo~NvY4)pb!$<CrH4JBo<`L0{W=zZ{ejn0@QrVOguOgukmbzU9UIRf_YS!Y0V
zJlp8^%cR?swDy3EhIAdP^IOs<6jQ4XaN?doBIE33rS^SVaww;o|L&qCDXt}rBmw#S
zlSZGTX!6KbNgyMk%h>0aaYzaqCZVLGax)Q&VPMKMvKMOC#)t7npAnVjf;FRhe!a|c
z-h_(JzM5esNa#*4>_G13(c;u?44;JZo55=zypMPNqGyVh@P`)veeU+W=1ePojlxar
a%EwkH^bPtn+#@^<tIi-}F&Y1Rng0N&pH!j%

literal 0
HcmV?d00001

diff --git a/files/platon/hello.gsm b/files/platon/hello.gsm
new file mode 100644
index 0000000000000000000000000000000000000000..fbdbaceb9c3c01349e4aeff5fff9ea4238329bde
GIT binary patch
literal 6204
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

literal 0
HcmV?d00001

diff --git a/files/platon/welcome.gsm b/files/platon/welcome.gsm
new file mode 100644
index 0000000000000000000000000000000000000000..3d8e319104a2b579f56da10bfcb6c23ac7a0b90a
GIT binary patch
literal 12870
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

literal 0
HcmV?d00001

diff --git a/files/platon/youcannotpass.gsm b/files/platon/youcannotpass.gsm
new file mode 100644
index 0000000000000000000000000000000000000000..da67f1230f0d86dfb543bf6bf75dbe73c65f32ee
GIT binary patch
literal 4290
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

literal 0
HcmV?d00001


From 0d6ca7bb686188e695fd12950e4151a35b054fb0 Mon Sep 17 00:00:00 2001
From: Stefan Haun <tux@netz39.de>
Date: Fri, 5 Aug 2022 17:23:35 +0200
Subject: [PATCH 9/9] Copy Asterisk sound files

---
 platon.yml | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/platon.yml b/platon.yml
index 20569b3..6fae250 100644
--- a/platon.yml
+++ b/platon.yml
@@ -275,6 +275,20 @@
         append: yes
       notify: restart asterisk
 
+    - name: Copy sounds
+      ansible.builtin.copy:
+        src: "files/platon/{{item}}"
+        dest: "/usr/local/share/asterisk/sounds/n39/"
+        owner: root
+        group: root
+        mode: "0644"
+      loop:
+        # Check the extensions.conf.j2 template to see which files are needed
+        - hello.gsm
+        - granted.gsm
+        - denied.gsm
+      # Asterisk restart is not necessary
+
 
   handlers:
     - name: restart mosquitto