# FieldPOC A simple to use, good enough phone system for medium sized DECT networks. ## Setup FieldPOC requires a Mitel SIP DECT phone system, i.e. RFP L43 WLAN. Make sure you have the equipment, else this software is quit useless. Get a computer, i.e. an APU Board, and install Archlinux on it. This can be a VM too, but you have to adapt stuff. ### Config Create a file `fieldpoc_config.json`. This is your FieldPOC config in JSON format. You will add details to it with each step. ### Networking We assume you use two network interfaces `enp2s0` and `enp3s0`. Configuration examples are for systemd-networkd. ``` systemctl enable --now systemd-networkd.service ``` Your FieldPOC box will act as a normal DHCP Client on `enp2s0`. This is the interface you connect to the internet and where you may connect to the box via SSH. `/etc/systemd/network/20-wired.network` ``` [Match] Name=enp2s0 [Network] DHCP=yes ``` The other interface `enp3s0` will be the DECT network. This is the network where you connect your RFPs. We will run a dedicated DHCP Server on this network. `/etc/systemd/network/30-dect.network` ``` [Match] Name=enp3s0 [Network] Address=10.222.222.1/24 ``` As the DHCP Server for this network we use `kea`. ``` pacman -S kea ``` `/etc/kea/kea-dhcp4.conf` ``` { "Dhcp4": { "interfaces-config": { "interfaces": [ "enp3s0" ] }, "lease-database": { "name": "/var/lib/kea/dhcp4.leases", "persist": true, "type": "memfile" }, "option-def": [ { "code": 43, "encapsulate": "sipdect", "name": "vendor-encapsulated-options", "space": "dhcp4", "type": "empty" }, { "code": 10, "name": "ommip1", "space": "sipdect", "type": "ipv4-address" }, { "code": 19, "name": "ommip2", "space": "sipdect", "type": "ipv4-address" }, { "code": 14, "name": "syslogip", "space": "sipdect", "type": "ipv4-address" }, { "code": 15, "name": "syslogport", "space": "sipdect", "type": "int16" }, { "code": 224, "name": "magic_str", "space": "dhcp4", "type": "string" } ], "subnet4": [ { "option-data": [ { "data": "10.222.222.1", "name": "routers" } ], "pools": [ { "pool": "10.222.222.100 - 10.222.222.200" } ], "reservations": [ { "hostname": "", "hw-address": "", "ip-address": "10.222.222.11", "option-data": [ { "data": "", "name": "host-name" }, { "name": "vendor-encapsulated-options" }, { "data": "10.222.222.11", "name": "ommip1", "space": "sipdect" }, { "data": "OpenMobilitySIP-DECT", "name": "magic_str" } ] } ], "subnet": "10.222.222.0/24" } ] } } ``` Start the service. ``` systemctl enable --now kea-dhcp4 ``` ### Database ``` pacman -S postgresql ``` Init database. ``` su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'" ``` ``` systemctl enable --now postgresql ``` Open SQL shell ``` sudo -u postgres psql ``` Create database and user for routing engine. Change the password. ``` CREATE USER fieldpoc WITH PASSWORD 'fieldpoc'; CREATE DATABASE fieldpoc WITH OWNER fieldpoc; ``` Add the database credetials to your `fieldpoc_config.json`. ``` { "database": { "host": "127.0.0.1", "username": "fieldpoc", "password": "fieldpoc", "database": "fieldpoc" } } ``` ### Phone Server ``` pacman -S yate ``` Remove all files in `/etc/yate/` and add the following instead: #### Dialout SIP connection `accfile.conf` ``` [dialout] enabled=yes protocol=sip registrar=10.222.222.254 username=dialout password=xxx ``` #### Call deduplication `cdrbuild.conf` ``` [parameters] X-Eventphone-Id=false ``` #### Yate remote control socket `extmodule.conf` ``` [listener fieldpoc] type=tcp addr=127.0.0.1 port=5039 ``` Add the information for the remote control socket to `fieldpoc_config.json`: ``` { "yate": { "host": "127.0.0.1", "port": 5039 } } ``` #### Database connection Replace credentials with the ones you have choosen. `pgsqldb.conf` ``` [default] host=127.0.0.1 database=fieldpoc user=fieldpoc password=fieldpoc ``` #### Call routing `regexroute.conf` ``` [default] ${username}^$=-;error=noauth ^iocaste$=goto dialin ^99991001$=tone/dial ^99991002$=tone/busy ^99991003$=tone/ring ^99991004$=tone/specdial ^99991005$=tone/congestion ^99991006$=tone/outoforder ^99991007$=tone/milliwatt ^99991008$=tone/info ^.*$=line/\0;line=dialout [dialin] ${sip_x-called}^.*$=lateroute/\1 ``` #### User registration `register.conf` ``` [general] expires=30 user.auth=yes user.register=yes user.unregister=yes engine.timer=yes ;call.preroute=no call.cdr=yes linetracker=yes [default] priority=10 account=default [user.auth] query=SELECT password FROM users WHERE username='${username}' AND password IS NOT NULL AND password<>'' AND type='user' LIMIT 1; result=password [user.register] query=INSERT INTO registrations (username, location, oconnection_id, expires) VALUES ('${username}', '${data}', '${oconnection_id}', NOW() + INTERVAL '${expires} s') ON CONFLICT ON CONSTRAINT uniq_registrations DO UPDATE SET expires = NOW() + INTERVAL '${expires} s' [user.unregister] query=DELETE FROM registrations WHERE (username = '${username}' AND location = '${data}' AND oconnection_id = '${connection_id}') OR ('${username}' = '' AND '${data}' = '' AND oconnection_id = '${connection_id}') [engine.timer] query=DELETE FROM registrations WHERE expires<=CURRENT_TIMESTAMP; [call.cdr] critical=no [linetracker] critical=yes initquery=UPDATE users SET inuse=0 WHERE inuse is not NULL;DELETE from active_calls; cdr_initialize=UPDATE users SET inuse=inuse+1 WHERE username='${external}';INSERT INTO active_calls SELECT username, x_eventphone_id FROM (SELECT '${external}' as username, '${X-Eventphone-Id}' as x_eventphone_id, '${direction}' as direction) as active_call WHERE x_eventphone_id != '' AND x_eventphone_id IS NOT NULL and direction = 'outgoing'; cdr_finalize=UPDATE users SET inuse=(CASE WHEN inuse>0 THEN inuse-1 ELSE 0 END) WHERE username='${external}';DELETE FROM active_calls WHERE username = '${external}' AND x_eventphone_id = '${X-Eventphone-Id}' AND '${direction}' = 'outgoing'; ``` ### DECT Just choose one of your RFPs as your OMM. Find out the MAC address and fill it in the according fields in the kea config before. To be able to have secure sip connections between the OMM and yate, generate a 16-characters long hexadecimal sip-secret. Create a privileged user account and add the credentials to `fieldpoc_config.json`: ``` { "omm": { "host": "10.222.222.11", "username": "omm", "password": "" "sipsecret": "" } } ``` ### FieldPOC Make sure Python is installed. ``` pacman -S python ``` Install FieldPOC: ``` pip install git+https://git.clerie.de/clerie/fieldpoc@main ``` FieldPOC provides a telnet socket for debugging and state mangement, add config for this to `fieldpoc_config.json` too: ``` { "controller": { "host": "127.0.0.1", "port": 9437 } } ``` ## Usage ### Init Some datastructures have get prepared once: ``` fieldpoc -c /path/to/fieldpoc_config.json -e /path/to/fieldpoc_extensions.json --init ``` ### Run ``` fieldpoc -c /path/to/fieldpoc_config.json -e /path/to/fieldpoc_extensions.json ``` ## Debug Show log messages: ``` fieldpoc -c /path/to/fieldpoc_config.json -e /path/to/fieldpoc_extensions.json --debug ``` ## Development setup Make sure you have [mitel_ommclient2](https://git.clerie.de/clerie/mitel_ommclient2) in your Python modules path. Add user credentials to your OMM to `fieldpoc_config.json`. Edit `fieldpoc_extensions.json` to meet your preferences. Start FieldPOC: ``` python -m fieldpoc.run ``` List some options: ``` python -m fieldpoc.run --help ```