commit 4a9fe79689726621f47b0ef1b827fd98a38b8f0e Author: Simon Date: Sun Sep 5 02:29:32 2021 +0100 Initial working build diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7b91426 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM debian:bullseye-slim + +COPY entrypoint /entrypoint +COPY config /opt/ + +RUN useradd -u 54000 radio && \ + apt-get update && \ + apt-get install -y git gcc g++ musl-dev python2 wget make && \ + cd /opt && \ + wget https://bootstrap.pypa.io/pip/2.7/get-pip.py && \ + python2 ./get-pip.py && \ + pip install twisted && \ + git clone https://github.com/hacknix/DMRlink.git && \ + cd /opt/DMRlink && \ + git checkout IPSC_Bridge && \ + sh ./mk-dmrlink && \ + cd .. && \ + git clone https://github.com/hacknix/HBLink.git && \ + cd HBLink && \ + git checkout HB_Bridge && \ + sh ./mk-required && \ + cd .. && \ + git clone https://github.com/hacknix/DMRGateway.git && \ + cd DMRGateway && \ + git reset --hard 6e89e4922f8c5eb7ec3797729a82137d70bc8940 && \ + make && \ + apt-get remove -y musl-dev gcc g++ make git wget && \ + apt-get -y autoremove && \ + apt-get -y purge && \ + rm -rvf /var/cache/apt/archives/* && \ + chown 54000 /opt/* -R && \ + chmod 777 /opt/ -R + +USER radio + +ENTRYPOINT [ "/entrypoint" ] diff --git a/config/DMRGateway.ini b/config/DMRGateway.ini new file mode 100644 index 0000000..d0c39ab --- /dev/null +++ b/config/DMRGateway.ini @@ -0,0 +1,178 @@ +[General] +Timeout=10 +# RFTimeout=10 +# NetTimeout=7 +RptProtocol=old +RptAddress=127.0.0.1 +RptPort=64032 +#Rpt1Address=127.0.0.1 +#Rpt1Port=62032 +#Rpt2Address=127.0.0.1 +#Rpt2Port=64032 +LocalAddress=127.0.0.1 +LocalPort=64031 +#LocalPort1=62031 +#LocalPort2=64031 +Split=2 +RuleTrace=1 +Daemon=0 +Debug=0 + +[Log] +# Logging levels, 0=No logging +DisplayLevel=1 +FileLevel=1 +FilePath=. +FileRoot=DMRGateway +FileRotate=1 + +[Voice] +Enabled=1 +Language=en_GB +Directory=./Audio + +[Info] +Latitude=0.0 +Longitude=0.0 +Height=0 +Location=Nowhere +Description=Multi-Mode Repeater +URL=www.google.co.uk + +[XLX Network] +Enabled=0 +File=XLXHosts.txt +Port=62030 +Password=passw0rd +ReloadTime=60 +# Local=3351 +Slot=1 +TG=6 +Base=64000 +Startup=950 +Relink=10 +Debug=0 +#Allow user linking control using Private Calls +UserControl=1 +#Override default module for startup reflector +#Module=A + +# FreeDMR +[DMR Network 1] +Enabled=1 +Name=FreeDMR +Address={{DMRG_TARGET}} +Port=62031 +TypeRewrite=2,91,2,91,4966 +TypeRewrite=2,5058,2,5058,4932 +TypeRewrite=2,5058,2,5058,4932 +TypeRewrite=2,9991,2,9991,225008 +TypeRewrite=2,235000,2,235000,1000 +TypeRewrite=2,236000,2,236000,764000 +TypeRewrite=2,5000,2,5000 +TypeRewrite=2,4000,2,4000 + +#East Midlands Slot 1 + +#TGRewrite=1,9,1,23590,1 +#TGRewrite=2,9,2,9,1 + +PassAllTG=1 +PassAllTG=2 + + + +Password=passw0rd +Location=1 +Debug=0 + + + + + + + + + + + + + + + + + + +# DMR+ +[DMR Network 2] +Enabled=0 +Name=DMR+ +Address=44.131.4.1 +Port=55555 +# Local=3352 +# Reflector TG on to slot 2 TG8 +TGRewrite=2,8,2,9,1 +# Echo on slot 2 TG9990 +TGRewrite=2,9990,2,9990,1 +# Reflector control command slot 2 84000->4000 to 85000->5000 +PCRewrite=2,84000,2,4000,1001 +# Pass all of the other talk group traffic on slot 1 and slot 2 +PassAllTG=1 +PassAllTG=2 +Password=PASSWORD +Location=0 +Debug=0 + +# TGIF Network +[DMR Network 3] +Enabled=0 +Name=TGIF_Network +TGRewrite0=1,1,2,1,9999998 +SrcRewrite0=2,1,1,1,9999998 +Address=tgif.network +Password=passw0rd +Port=62031 +Location=0 +Debug=0 + +# Local HBLink 1 network +[DMR Network 4] +Enabled=0 +Name=HBLink 1 +Address=44.131.4.2 +Port=55555 +# Local=3352 +# Local area TG on to slot 2 TG11 +TGRewrite=2,11,2,11,1 +Password=PASSWORD +Location=0 +Debug=0 + +# Local HBLink 2 network +[DMR Network 5] +Enabled=0 +Name=HBLink 2 +Address=44.131.4.3 +Port=55555 +# Local=3352 +# Local area TG on to slot 2 TG11 +TGRewrite=2,11,2,11,1 +Password=PASSWORD +Location=0 +Debug=0 + +[GPSD] +Enable=0 +Address=127.0.0.1 +Port=2947 + +[APRS] +Enable=0 +Address=127.0.0.1 +Port=8673 +Description=APRS Description +Suffix=3 + +[Dynamic TG Control] +Enabled=1 +Port=3769 diff --git a/config/HB_Bridge.cfg b/config/HB_Bridge.cfg new file mode 100644 index 0000000..7f98b14 --- /dev/null +++ b/config/HB_Bridge.cfg @@ -0,0 +1,18 @@ +################################################ +# HB_Bridge configuration file. +################################################ + +[DEFAULTS] +gateway = 127.0.0.1 # IP address of Partner Application (IPSC_Bridge, Analog_Bridge) +fromGatewayPort = 31000 # Port HB_Bridge is listening on for data (HB_Bridge <--- Partner) +toGatewayPort = 31003 # Port Partner is listening on for data (HB_Bridge ---> Partner) + + + + +[RULES] +# Name = Old TG, New TG, New Slot +#TG_SE = 3174, 3174, 2 +#TG_NA = 3,3,1 +#TG_ATL = 8,8,1 +#TG_WW = 1,1,1 diff --git a/config/IPSC_Bridge.cfg b/config/IPSC_Bridge.cfg new file mode 100644 index 0000000..2e59ae1 --- /dev/null +++ b/config/IPSC_Bridge.cfg @@ -0,0 +1,11 @@ +################################## +# IPSC_Bridge configuration file # +################################## + +# DEFAULTS - General settings. These values are +# inherited in each subsequent section (defined by section value). + +[DEFAULTS] +gateway = 127.0.0.1 # IP address of Partner Application (HB_Bridge, Analog_Bridge) +fromGatewayPort = 31003 # Port IPSC_Bridge is listening on for data (IPSC_Bridge <--- Partner) +toGatewayPort = 31000 # Port Partner is listening on for data (IPSC_Bridge ---> Partner) diff --git a/config/dmrlink.cfg b/config/dmrlink.cfg new file mode 100644 index 0000000..57c37fb --- /dev/null +++ b/config/dmrlink.cfg @@ -0,0 +1,192 @@ +# DMRLink SAMPLE CONFIGURATION FILE +# +# Rename to dmrlink.cfg and add your information +# +# minor tweaks to match install for use by DMRGateway +# N4IRS +# +# + +# GLOBAL CONFIGURATION ITEMS +# +[GLOBAL] +PATH: /opt/IPSC_Bridge/ + + +# NETWORK REPORTING CONFIGURATION +# Enabling "REPORT_NETWORKS" will cause a reporting action for +# IPSC each time the periodic reporting loop runs, that period is +# specified by "REPORT_INTERVAL" in seconds. Possible values +# for "REPORT_NETWORKS" are: +# +# PRINT - a pretty print (STDOUT) of the data structure +# "PRINT_PEERS_INC_MODE" - Boolean to include mode bits +# "PRINT_PEERS_INC_FLAGS" - Boolean to include flag bits +# +# NETWORK - This is the right way to do it. Opens a TCP socket +# listener. The protocol is still in its infancy, but the +# idea is that dmrlink will talk to another application +# to send event and status updates. Of course, the big +# goal here is a web dashboard that doesn't live on the +# dmrlink machine itself. +# +# PRINT should only be used for debugging; it sends prettily formatted +# stuff to STDOUT. The others send the internal data structure of the +# IPSC instance and let some program on the other end sort it out. +# +# REPORT_RCM - If True, and REPORT_NETWORKS = 'NETWORK', will send RCM +# Packets to connected reporting clients. This also requires +# individual IPSC systems to have RCM and CON_APP both set 'True' +# +# REPORT_INTERVAL - Seconds between reports +# REPORT_PORT - TCP port to listen on if "REPORT_NETWORKS" = NETWORK +# REPORT_CLIENTS - comma separated list of IPs you will allow clients +# to connect on. +# +[REPORTS] +REPORT_NETWORKS: +REPORT_RCM: +REPORT_INTERVAL: 60 +REPORT_PORT: 4321 +REPORT_CLIENTS: 127.0.0.1, 192.168.1.1 +PRINT_PEERS_INC_MODE: 0 +PRINT_PEERS_INC_FLAGS: 0 + + +# SYSTEM LOGGER CONFIGURAITON +# This allows the logger to be configured without chaning the individual +# python logger stuff in dmrlink.py. LOG_FILE should be a complete +# path/filename for *your* system -- use /dev/null for non-file handlers. +# LOG_HANDERLS may be any of the following, please, no spaces in the +# list if you use several: +# null +# console +# console-timed +# file +# file-timed +# syslog +# LOG_LEVEL may be any of the standard syslog logging levels, though +# as of now, DEBUG, INFO, WARNING and CRITICAL are the only ones +# used. +# +[LOGGER] +LOG_FILE: /tmp/dmrlink.log +LOG_HANDLERS: console-timed,file-timed +LOG_LEVEL: INFO +LOG_NAME: DMRlink + + +# DOWNLOAD AND IMPORT SUBSCRIBER, PEER and TGID ALIASES +# Ok, not the TGID, there's no master list I know of to download +# This is intended as a facility for other applcations built on top of +# DMRlink to use, and will NOT be used in DMRlink directly. +# STALE_DAYS is the number of days since the last download before we +# download again. Don't be an ass and change this to less than a few days. +[ALIASES] +TRY_DOWNLOAD: False +LOCAL_FILE: False +PATH: ./ +PEER_FILE: peer_ids.json +SUBSCRIBER_FILE: subscriber_ids.json +TGID_FILE: talkgroup_ids.json +PEER_URL: https://www.radioid.net/static/rptrs.json +SUBSCRIBER_URL: https://www.radioid.net/static/users.json +STALE_DAYS: 7 + + +# CONFIGURATION FOR IPSC NETWORKS +# Please read these closely - catastrophic results could result by setting +# certain flags for things DMRlink cannot do. +# +# [NAME] The name you want to use to identify the IPSC instance (use +# something better than "IPSC1"...) +# ENABLED: Should we communicate with this network? Handy if you need to +# shut one down but don't want to lose the config +# RADIO_ID: This is the radio ID that DMRLink should use to communicate +# IP: This is the local IPv4 address to listen on. It may be left +# blank if you do not need or wish to specify. It is mostly +# useful when DMRlink uses multiple interfaces to serve as an +# application gateway/proxy from private and/or VPN networks +# to the real world. +# PORT: This is the UDP source port for DMRLink to use for this +# PSC network, must be unique!!! +# ALIVE_TIMER: Seconds between keep-alive transmissions +# MAX_MISSED: How many missed keep-alives before we remove a peer +# PEER_OPER: This signals the master and peers whether or not we are +# operational. True is the only thing that makes sense. +# IPSC_MODE: May be 'DIGITAL', 'ANALOG', or 'NONE'. Digital is really the +# only thing that makes sense. +# TSx_LINK: Is this time slot linked? +# CSBK_CALL: Should be False, we cannot process these, but may be useful +# for debugging. +# RCM: Repeater Call Monitoring - don't unable unless you plan to +# actually use it, this creates extra network traffic. +# CON_APP: Third Party Console App - exactly what DMRlink is, should +# be set to True, and must be if you intend to process RCM +# packets (like with network-based reporting) +# XNL_CALL: Can cause problems if not set to False, DMRlink does not +# process XCMP/XNL calls. +# XNL_MASTER: Obviously, should also be False, see XNL_CALL. +# DATA_CALL: Process data calls. True if you want to process data calls +# VOICE_CALL: Process voice calls. True if you want to process voice calls +# MASTER_PEER: True if DMRlink will be the master, False if we're a peer +# AUTH_ENABLED: Do we use authenticated IPSC? +# AUTH_KEY: The Authentication key (up to 40 hex characters) +# MASTER_IP: IP address of the IPSC master (ignored if DMRlink is the master) +# MASTER_PORT: UDP port of the IPSC master (ignored if DMRlink is the master) +# GROUP_HANGTIME: Group hangtime, per DMR configuration +# +# ...Repeat the block for each IPSC network to join. +# + +[SAMPLE_PEER] +ENABLED: False +RADIO_ID: 12345 +IP: +PORT: 50000 +ALIVE_TIMER: 5 +MAX_MISSED: 20 +PEER_OPER: True +IPSC_MODE: DIGITAL +TS1_LINK: True +TS2_LINK: True +CSBK_CALL: False +RCM: False +CON_APP: False +XNL_CALL: False +XNL_MASTER: False +DATA_CALL: True +VOICE_CALL: True +MASTER_PEER: False +AUTH_ENABLED: True +AUTH_KEY: 1A2B3C +MASTER_IP: 1.2.3.4 +MASTER_PORT: 50000 +GROUP_HANGTIME: 5 + + +[DEFAULTS] +ENABLED: True +RADIO_ID: {{IPSC_RADIO_ID}} +IP: +PORT: 55000 +ALIVE_TIMER: 10 +MAX_MISSED: 20 +PEER_OPER: True +IPSC_MODE: DIGITAL +TS1_LINK: {{IPSC_TS1}} +TS2_LINK: {{IPSC_TS2}} +CSBK_CALL: False +RCM: False +CON_APP: False +XNL_CALL: False +XNL_MASTER: False +DATA_CALL: True +VOICE_CALL: True +MASTER_PEER: {{IPSC_MASTER_PEER}} +AUTH_ENABLED: False +AUTH_KEY: +# Below not used for a Master +MASTER_IP: {{IPSC_MASTER_IP}} +MASTER_PORT: {{IPSC_MASTER_PORT}} +GROUP_HANGTIME: 5 diff --git a/config/hblink.cfg b/config/hblink.cfg new file mode 100644 index 0000000..a9ac222 --- /dev/null +++ b/config/hblink.cfg @@ -0,0 +1,116 @@ +# PROGRAM-WIDE PARAMETERS GO HERE +# PATH - working path for files, leave it alone unless you NEED to change it +# PING_TIME - the interval that clients will ping the master, and re-try registraion +# - how often the Master maintenance loop runs +# MAX_MISSED - how many pings are missed before we give up and re-register +# - number of times the master maintenance loop runs before de-registering a client +[GLOBAL] +PATH: ./ +PING_TIME: 5 +MAX_MISSED: 3 + +# SYSTEM LOGGER CONFIGURAITON +# This allows the logger to be configured without chaning the individual +# python logger stuff. LOG_FILE should be a complete path/filename for *your* +# system -- use /dev/null for non-file handlers. +# LOG_HANDERLS may be any of the following, please, no spaces in the +# list if you use several: +# null +# console +# console-timed +# file +# file-timed +# syslog +# LOG_LEVEL may be any of the standard syslog logging levels, though +# as of now, DEBUG, INFO, WARNING and CRITICAL are the only ones +# used. +# +[LOGGER] +LOG_FILE: /tmp/hblink.log +LOG_HANDLERS: console-timed +LOG_LEVEL: DEBUG +LOG_NAME: HBlink + +# DOWNLOAD AND IMPORT SUBSCRIBER, PEER and TGID ALIASES +# Ok, not the TGID, there's no master list I know of to download +# This is intended as a facility for other applcations built on top of +# HBlink to use, and will NOT be used in HBlink directly. +# STALE_DAYS is the number of days since the last download before we +# download again. Don't be an ass and change this to less than a few days. +[ALIASES] +TRY_DOWNLOAD: False +PATH: ./ +PEER_FILE: peer_ids.json +SUBSCRIBER_FILE: subscriber_ids.json +TGID_FILE: talkgroup_ids.json +PEER_URL: https://www.radioid.net/static/rptrs.json +SUBSCRIBER_URL: https://www.radioid.net/static/users.json +STALE_DAYS: 7 + +# EXPORT AMBE DATA +# This is for exporting AMBE audio frames to an an "external" process for +# decoding or other nefarious actions. +[AMBE] +EXPORT_IP: 127.0.0.1 +EXPORT_PORT: 1234 + +# MASTER INSTANCES - DUPLICATE SECTION FOR MULTIPLE MASTERS +# HomeBrew Protocol Master instances go here. +# IP may be left blank if there's one interface on your system. +# Port should be the port you want this master to listen on. It must be unique +# and unused by anything else. +# Repeat - if True, the master repeats traffic to clients, False, it does nothing. +[MASTER-1] +MODE: MASTER +ENABLED: False +REPEAT: True +EXPORT_AMBE: False +IP: +PORT: 54000 +PASSPHRASE: s3cr37w0rd +GROUP_HANGTIME: 5 + +# CLIENT INSTANCES - DUPLICATE SECTION FOR MULTIPLE CLIENTS +# There are a LOT of errors in the HB Protocol specifications on this one! +# MOST of these items are just strings and will be properly dealt with by the program +# The TX & RX Frequencies are 9-digit numbers, and are the frequency in Hz. +# Latitude is an 8-digit unsigned floating point number. +# Longitude is a 9-digit signed floating point number. +# Height is in meters +# Setting Loose to True relaxes the validation on packets received from the master. +# This will allow HBlink to connect to a non-compliant system such as XLXD, DMR+ etc. + +[DMRGATEWAY] +MODE: CLIENT +ENABLED: True +LOOSE: True +EXPORT_AMBE: False +IP: +PORT: 64032 +MASTER_IP: 127.0.0.1 +MASTER_PORT: 64031 +PASSPHRASE: PASSWORD +CALLSIGN: {{HB_CALLSIGN}} +RADIO_ID: {{HB_RADIO_ID}} +RX_FREQ: {{HB_RX_FREQ}} +TX_FREQ: {{HB_TX_FREQ}} +TX_POWER: {{HB_TX_POWER}} +COLORCODE: {{HB_COLORCODE}} +SLOTS: 3 +LATITUDE: {{HB_LAT}} +LONGITUDE: {{HB_LON}} +HEIGHT: {{HB_HEIGHT}} +LOCATION: {{HB_LOCATION}} +DESCRIPTION: Motorola repeater +URL: https://freedmr.uk +SOFTWARE_ID: 20170620 +PACKAGE_ID: MMDVM_FreeDMR +GROUP_HANGTIME: 5 +OPTIONS: {{HB_OPTIONS}} + + + + + + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c6dc0d4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3.3' +services: + FreeDMR-Mytera: + container_name: FreeDMR-IPSC + # volumes: + # - './DMRGateway.ini:/opt/hytera-stack/DMRGateway.ini' + ports: + - '62005:62005/udp' + - '62006:62006/udp' + - '62007:62007/udp' + image: 'hacknix/freedmr:FreeDMR-IPSC' + restart: "unless-stopped" diff --git a/entrypoint b/entrypoint new file mode 100755 index 0000000..efb6cbe --- /dev/null +++ b/entrypoint @@ -0,0 +1,33 @@ +#!/bin/sh + +#Substitute enivronment variables into files +sed -i "s/{{IPSC_MASTER_PEER}}/$IPSC_MASTER_PEER/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_MASTER_PEER}}/$IPSC_MASTER_PEER/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_MASTER_IP}}/$IPSC_MASTER_IP/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_MASTER_PORT}}/$IPSC_MASTER_PORT/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_MASTER_PEER}}/$IPSC_MASTER_PEER/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_TS1}}/$IPSC_TS1/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_TS2}}/$IPSC_TS2/" /opt/dmrlink.cfg +sed -i "s/{{IPSC_RADIO_ID}}/$IPSC_RADIO_ID/" /opt/dmrlink.cfg + +sed -i "s/{{HB_CALLSIGN}}/$HB_CALLSIGN/" /opt/hblink.cfg +sed -i "s/{{HB_RADIO_ID}}/$HB_RADIO_ID/" /opt/hblink.cfg +sed -i "s/{{HB_RX_FREQ}}/$HB_RX_FREQ/" /opt/hblink.cfg +sed -i "s/{{HB_TX_FREQ}}/$HB_TX_FREQ/" /opt/hblink.cfg +sed -i "s/{{HB_TX_POWER}}/$HB_TX_POWER/" /opt/hblink.cfg +sed -i "s/{{HB_COLORCODE}}/$HB_COLORCODE/" /opt/hblink.cfg +sed -i "s/{{HB_LAT}}/$HB_LAT/" /opt/hblink.cfg +sed -i "s/{{HB_LON}}/$HB_LON/" /opt/hblink.cfg +sed -i "s/{{HB_HEIGHT}}/$HB_HEIGHT/" /opt/hblink.cfg +sed -i "s/{{HB_LOCATION}}/$HB_LOCATION/" /opt/hblink.cfg +sed -i "s/{{HB_OPTIONS}}/$HB_OPTIONS/" /opt/hblink.cfg + +sed -i "s/{{DMRG_TARGET}}/$DMRG_TARGET/" /opt/DMRGateway.ini + +#Run processes +cd /opt/DMRlink/ +python /opt/DMRlink/IPSC_Bridge.py -c /opt/dmrlink.cfg -b /opt/IPSC_Bridge.cfg & +cd /opt/HBLink +python /opt/HBLink/HB_Bridge.py -c /opt/hblink.cfg -b /opt/HB_Bridge.cfg & +cd /opt/DMRGateway +/opt/DMRGateway/DMRGateway /opt/DMRGateway.ini