From 687ddf11a9f7416cc35c3724d6b6a1c5151d50ae Mon Sep 17 00:00:00 2001 From: Millaguie Date: Sat, 13 Apr 2019 19:59:03 +0200 Subject: [PATCH 01/14] Docker support --- Dockerfile | 32 ++++++++++++++++++++++++++++++++ README.md | 26 ++++++++++++++++++++++++++ entrypoint | 10 ++++++++++ 3 files changed, 68 insertions(+) create mode 100644 Dockerfile create mode 100644 entrypoint diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..14b55f0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +FROM python:3.7-slim-stretch + +RUN apt update && \ + apt install -y git && \ + cd /usr/src/ && \ + git clone https://github.com/n0mjs710/dmr_utils3 && \ + cd /usr/src/dmr_utils3 && \ + ./install.sh && \ + rm -rf /var/lib/apt/lists/* && \ + cd /opt && \ + rm -rf /usr/src/dmr_utils3 && \ + git clone https://github.com/n0mjs710/hblink3 + +RUN cd /opt/hblink3/ && \ + sed -i s/.*python.*//g requirements.txt && \ + pip install --no-cache-dir -r requirements.txt + + +ADD entrypoint /entrypoint + +RUN adduser -u 54000 radio && \ + adduser radio radio && \ + chmod 755 /entrypoint && \ + chown radio:radio /entrypoint && \ + chown radio /opt/hblink3 + +RUN chmod 755 /entrypoint + +USER radio +EXPOSE 54000 + +ENTRYPOINT [ "/entrypoint" ] diff --git a/README.md b/README.md index bb9c0f9..a04b2f4 100755 --- a/README.md +++ b/README.md @@ -24,6 +24,32 @@ None. The owners of this work make absolutely no warranty, express or implied. U **PRE-REQUISITE KNOWLEDGE:** This document assumes the reader is familiar with Linux/UNIX, the Python programming language and DMR. +**Using docker version** + +To use with provided docker configuration you will need: +* A private repository with your configuration files (all .cfg files in repo will be copyed to the application root directory on start) +* A service user able to read your private repository +* A server with docker installed +* Follow this simple steps: + +Build your own image from source + +```bash + +docker build . -t millaguie/hblink:3.0.0 + +``` + +Or user a prebuilt one in docker hub: millaguie/hblink:3.0.0 + +Wake up your container + +```bash +touch /var/log/hblink.log +chown 65000 /var/log/hblink.log + run -v /var/log/hblink.log:/var/log/hblink.log -e GIT_USER=$USER -e GIT_PASSWORD=$PASSWORD -e GIT_REPO=$URL_TO_REPO_WITHOUT_HTTPS:// -p 54000:54000 millaguie/hblink:3.0.0 + ``` + **MORE DOCUMENTATION TO COME** ***0x49 DE N0MJS*** diff --git a/entrypoint b/entrypoint new file mode 100644 index 0000000..84a03e2 --- /dev/null +++ b/entrypoint @@ -0,0 +1,10 @@ +#!/bin/sh + +mkdir -p /var/tmp/config +cd /var/tmp/config +git clone https://${GIT_USER}:${GIT_PASSWORD}@${GIT_REPO} + +DIR=$(echo ${GIT_REPO}| sed s/.git$//g | sed s#^.*/##g) + +cp -a /var/tmp/config/${DIR}/*cfg /opt/hblink3/ +python /opt/hblink3/hblink.py From 8519f86fd3bdd713985929d08b686dab9032d99f Mon Sep 17 00:00:00 2001 From: Millaguie Date: Sat, 13 Apr 2019 20:03:40 +0200 Subject: [PATCH 02/14] Improve english --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a04b2f4..40cbe72 100755 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ This document assumes the reader is familiar with Linux/UNIX, the Python program **Using docker version** -To use with provided docker configuration you will need: -* A private repository with your configuration files (all .cfg files in repo will be copyed to the application root directory on start) -* A service user able to read your private repository +To work with provided docker setup you will need: +* A private repository with your configuration files (all .cfg files in repo will be copyed to the application root directory on start up) +* A service user able to read your private repository (or be brave and publish your configuration, or be really brave and give your username and password to the docker) * A server with docker installed * Follow this simple steps: From 3218a5f6bb0f8f7b4390b1c0f7f2d1b8e6d5bdee Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Mon, 6 May 2019 21:34:15 -0500 Subject: [PATCH 03/14] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 40cbe72..7c9191f 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +## ADDITIONAL TERMS OF THE SOFTWARE LICENSE: THIS SOFTWARE IS EXPLICITLY LICENSED TO BYRG REPETERS ONLY ON AN INDIVIDUAL CASE BASIS. ALL EXISTING USE BY BYRG IS HEREBY REVOKED UNTIL EXPLICITLY PERMITTED BY THE COPYRIGHT HOLDER ## --- ### FOR SUPPORT, DISCUSSION, GETTING INVOLVED ### From b668130727de23a34f046c2e9fc10c8af138366b Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Mon, 6 May 2019 21:37:23 -0500 Subject: [PATCH 04/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7c9191f..f6ae811 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## ADDITIONAL TERMS OF THE SOFTWARE LICENSE: THIS SOFTWARE IS EXPLICITLY LICENSED TO BYRG REPETERS ONLY ON AN INDIVIDUAL CASE BASIS. ALL EXISTING USE BY BYRG IS HEREBY REVOKED UNTIL EXPLICITLY PERMITTED BY THE COPYRIGHT HOLDER ## +## ADDITIONAL TERMS OF THE SOFTWARE LICENSE: THIS SOFTWARE IS EXPLICITLY LICENSED TO BYRG ONLY ON AN INDIVIDUAL CASE BASIS. ALL EXISTING USE BY BYRG IS HEREBY REVOKED UNTIL EXPLICITLY PERMITTED BY THE COPYRIGHT HOLDER ## --- ### FOR SUPPORT, DISCUSSION, GETTING INVOLVED ### From e47c2a328dc9aabecc47572cedd8fe66e426f76b Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Mon, 6 May 2019 22:19:44 -0500 Subject: [PATCH 05/14] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f6ae811..40cbe72 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -## ADDITIONAL TERMS OF THE SOFTWARE LICENSE: THIS SOFTWARE IS EXPLICITLY LICENSED TO BYRG ONLY ON AN INDIVIDUAL CASE BASIS. ALL EXISTING USE BY BYRG IS HEREBY REVOKED UNTIL EXPLICITLY PERMITTED BY THE COPYRIGHT HOLDER ## --- ### FOR SUPPORT, DISCUSSION, GETTING INVOLVED ### From dce6674875448d9c6735ad2e69ed06d47c65c1f2 Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Mon, 6 May 2019 22:20:15 -0500 Subject: [PATCH 06/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40cbe72..565a25f 100755 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ chown 65000 /var/log/hblink.log ***0x49 DE N0MJS*** -Copyright (C) 2016-2017 Cortney T. Buffington, N0MJS n0mjs@me.com +Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS n0mjs@me.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. From ad2813db58c5229b3fe5c11427176908df8e181f Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Thu, 9 May 2019 09:31:21 -0500 Subject: [PATCH 07/14] RadioID changes --- hblink-SAMPLE.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hblink-SAMPLE.cfg b/hblink-SAMPLE.cfg index 2df6fb9..6611016 100755 --- a/hblink-SAMPLE.cfg +++ b/hblink-SAMPLE.cfg @@ -101,8 +101,8 @@ PATH: ./ PEER_FILE: peer_ids.json SUBSCRIBER_FILE: subscriber_ids.json TGID_FILE: talkgroup_ids.json -PEER_URL: https://www.radioid.net/api/dmr/repeater/?country=united%%20states -SUBSCRIBER_URL: https://www.radioid.net/api/dmr/user/?country=united%%20states +PEER_URL: https://www.radioid.net/static/rptrs.json +SUBSCRIBER_URL: https://www.radioid.net/static/users.json STALE_DAYS: 7 # OPENBRIDGE INSTANCES - DUPLICATE SECTION FOR MULTIPLE CONNECTIONS From 24c201ffc2f82e83bd20484b5e9aef4a45750a8e Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Wed, 19 Jun 2019 07:32:44 +0000 Subject: [PATCH 08/14] Add basic XLX support --- config.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++- hblink-SAMPLE.cfg | 32 +++++++++++++++++++++++++++++++ hblink.py | 7 +++++++ install.sh | 6 ++++++ requirements.txt | 1 - rules_SAMPLE.py | 2 ++ 6 files changed, 94 insertions(+), 2 deletions(-) create mode 100755 install.sh diff --git a/config.py b/config.py index 5de0d69..3efe39f 100755 --- a/config.py +++ b/config.py @@ -198,7 +198,53 @@ def build_config(_config_file): 'LAST_PING_TX_TIME': 0, 'LAST_PING_ACK_TIME': 0, }}) - + + if config.get(section, 'MODE') == 'XLXPEER': + CONFIG['SYSTEMS'].update({section: { + 'MODE': config.get(section, 'MODE'), + 'ENABLED': config.getboolean(section, 'ENABLED'), + 'LOOSE': config.getboolean(section, 'LOOSE'), + 'SOCK_ADDR': (gethostbyname(config.get(section, 'IP')), config.getint(section, 'PORT')), + 'IP': gethostbyname(config.get(section, 'IP')), + 'PORT': config.getint(section, 'PORT'), + 'MASTER_SOCKADDR': (gethostbyname(config.get(section, 'MASTER_IP')), config.getint(section, 'MASTER_PORT')), + 'MASTER_IP': gethostbyname(config.get(section, 'MASTER_IP')), + 'MASTER_PORT': config.getint(section, 'MASTER_PORT'), + 'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE'), 'utf-8'), + 'CALLSIGN': bytes(config.get(section, 'CALLSIGN').ljust(8)[:8], 'utf-8'), + 'RADIO_ID': config.getint(section, 'RADIO_ID').to_bytes(4, 'big'), + 'RX_FREQ': bytes(config.get(section, 'RX_FREQ').ljust(9)[:9], 'utf-8'), + 'TX_FREQ': bytes(config.get(section, 'TX_FREQ').ljust(9)[:9], 'utf-8'), + 'TX_POWER': bytes(config.get(section, 'TX_POWER').rjust(2,'0'), 'utf-8'), + 'COLORCODE': bytes(config.get(section, 'COLORCODE').rjust(2,'0'), 'utf-8'), + 'LATITUDE': bytes(config.get(section, 'LATITUDE').ljust(8)[:8], 'utf-8'), + 'LONGITUDE': bytes(config.get(section, 'LONGITUDE').ljust(9)[:9], 'utf-8'), + 'HEIGHT': bytes(config.get(section, 'HEIGHT').rjust(3,'0'), 'utf-8'), + 'LOCATION': bytes(config.get(section, 'LOCATION').ljust(20)[:20], 'utf-8'), + 'DESCRIPTION': bytes(config.get(section, 'DESCRIPTION').ljust(19)[:19], 'utf-8'), + 'SLOTS': bytes(config.get(section, 'SLOTS'), 'utf-8'), + 'URL': bytes(config.get(section, 'URL').ljust(124)[:124], 'utf-8'), + 'SOFTWARE_ID': bytes(config.get(section, 'SOFTWARE_ID').ljust(40)[:40], 'utf-8'), + 'PACKAGE_ID': bytes(config.get(section, 'PACKAGE_ID').ljust(40)[:40], 'utf-8'), + 'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'), + 'XLXMODULE': config.getint(section, 'XLXMODULE'), + 'OPTIONS': '', + 'USE_ACL': config.getboolean(section, 'USE_ACL'), + 'SUB_ACL': config.get(section, 'SUB_ACL'), + 'TG1_ACL': config.get(section, 'TGID_TS1_ACL'), + 'TG2_ACL': config.get(section, 'TGID_TS2_ACL') + }}) + CONFIG['SYSTEMS'][section].update({'XLXSTATS': { + 'CONNECTION': 'NO', # NO, RTPL_SENT, AUTHENTICATED, CONFIG-SENT, YES + 'CONNECTED': None, + 'PINGS_SENT': 0, + 'PINGS_ACKD': 0, + 'NUM_OUTSTANDING': 0, + 'PING_OUTSTANDING': False, + 'LAST_PING_TX_TIME': 0, + 'LAST_PING_ACK_TIME': 0, + }}) + elif config.get(section, 'MODE') == 'MASTER': CONFIG['SYSTEMS'].update({section: { 'MODE': config.get(section, 'MODE'), diff --git a/hblink-SAMPLE.cfg b/hblink-SAMPLE.cfg index 6611016..a743373 100755 --- a/hblink-SAMPLE.cfg +++ b/hblink-SAMPLE.cfg @@ -207,3 +207,35 @@ USE_ACL: True SUB_ACL: DENY:1 TGID_TS1_ACL: PERMIT:ALL TGID_TS2_ACL: PERMIT:ALL + +[XLX-1] +MODE: XLXPEER +ENABLED: True +LOOSE: False +EXPORT_AMBE: False +IP: +PORT: 54002 +MASTER_IP: 172.16.1.1 +MASTER_PORT: 62030 +PASSPHRASE: passw0rd +CALLSIGN: W1ABC +RADIO_ID: 312000 +RX_FREQ: 449000000 +TX_FREQ: 444000000 +TX_POWER: 25 +COLORCODE: 1 +SLOTS: 1 +LATITUDE: 38.0000 +LONGITUDE: -095.0000 +HEIGHT: 75 +LOCATION: Anywhere, USA +DESCRIPTION: This is a cool repeater +URL: www.w1abc.org +SOFTWARE_ID: 20170620 +PACKAGE_ID: MMDVM_HBlink +GROUP_HANGTIME: 5 +XLXMODULE: 4004 +USE_ACL: True +SUB_ACL: DENY:1 +TGID_TS1_ACL: PERMIT:ALL +TGID_TS2_ACL: PERMIT:ALL diff --git a/hblink.py b/hblink.py index 2693981..e22bdb6 100755 --- a/hblink.py +++ b/hblink.py @@ -224,6 +224,13 @@ class HBSYSTEM(DatagramProtocol): self.datagramReceived = self.peer_datagramReceived self.dereg = self.peer_dereg + elif self._config['MODE'] == 'XLXPEER': + self._stats = self._config['XLXSTATS'] + self.send_system = self.send_master + self.maintenance_loop = self.peer_maintenance_loop + self.datagramReceived = self.peer_datagramReceived + self.dereg = self.peer_dereg + def startProtocol(self): # Set up periodic loop for tracking pings from peers. Run every 'PING_TIME' seconds self._system_maintenance = task.LoopingCall(self.maintenance_loop) diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..c47b9db --- /dev/null +++ b/install.sh @@ -0,0 +1,6 @@ +#! /bin/bash + +# Install the required support programs +apt-get install python3 python3-pip -y +pip3 install -r requirements.txt + diff --git a/requirements.txt b/requirements.txt index 7bb55eb..730b1c4 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -python>=3.5.0 bitstring>=3.1.5 bitarray>=0.8.1 Twisted>=16.3.0 diff --git a/rules_SAMPLE.py b/rules_SAMPLE.py index 3781e57..a3c3701 100755 --- a/rules_SAMPLE.py +++ b/rules_SAMPLE.py @@ -15,7 +15,9 @@ configuration file. * SYSTEM - The name of the sytem as listed in the main hblink configuration file (e.g. hblink.cfg) This MUST be the exact same name as in the main config file!!! * TS - Timeslot used for matching traffic to this confernce bridge + XLX connections should *ALWAYS* use TS 2 only. * TGID - Talkgroup ID used for matching traffic to this conference bridge + XLX connections should *ALWAYS* use TG 9 only. * ON and OFF are LISTS of Talkgroup IDs used to trigger this system off and on. Even if you only want one (as shown in the ON example), it has to be in list format. None can be handled with an empty list, such as " 'ON': [] ". From aa7fea86bab59f1eea2d829997bd2d2da8112452 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Wed, 19 Jun 2019 12:15:21 +0000 Subject: [PATCH 09/14] Add packet generation for XLX master module selection --- hblink.py | 26 ++++++++++++++++++++++++++ requirements.txt | 1 + 2 files changed, 27 insertions(+) diff --git a/hblink.py b/hblink.py index e22bdb6..42d2c2b 100755 --- a/hblink.py +++ b/hblink.py @@ -290,6 +290,28 @@ class HBSYSTEM(DatagramProtocol): # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! # logger.debug('(%s) TX Packet to %s:%s -- %s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT'], ahex(_packet)) + def send_xlxmaster(self, radio, xlx, mastersock): + radio3 = int.from_bytes(radio, 'big').to_bytes(3, 'big') + radio4 = int.from_bytes(radio, 'big').to_bytes(4, 'big') + xlx3 = xlx.to_bytes(3, 'big') + streamid = bytearray.fromhex('6df88f36') + for packetnr in range(5): + if packetnr < 3: + # First 3 packets, voice start, stream type e1 + strmtype = 225 + payload = bytearray.fromhex('4f2e00b501ae3a001c40a0c1cc7dff57d75df5d5065026f82880bd616f13f185890000') + else: + # Last 2 packets, voice end, stream type e2 + strmtype = 226 + payload = bytearray.fromhex('4f410061011e3a781c30a061ccbdff57d75df5d2534425c02fe0b1216713e885ba0000') + packetnr1 = packetnr.to_bytes(1, 'big') + strmtype1 = strmtype.to_bytes(1, 'big') + _packet = b''.join([DMRD, packetnr1, radio3, xlx3, radio4, strmtype1, streamid, payload]) + self.transport.write(_packet, mastersock) + # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! + #logger.info('(%s) XLX Module Change Packet: %s', self._system, ahex(_packet)) + return + def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data): pass @@ -638,6 +660,10 @@ class HBSYSTEM(DatagramProtocol): self._stats['CONNECTION'] = 'YES' self._stats['CONNECTED'] = time() logger.info('(%s) Connection to Master Completed', self._system) + # If we are an XLX, send the XLX module request here. + if self._config['MODE'] == 'XLXPEER': + self.send_xlxmaster(self._config['RADIO_ID'], self._config['XLXMODULE'], self._config['MASTER_SOCKADDR']) + logger.info('(%s) Sending XLX Module request', self._system) else: self._stats['CONNECTION'] = 'NO' logger.error('(%s) Master ACK Contained wrong ID - Connection Reset', self._system) diff --git a/requirements.txt b/requirements.txt index 730b1c4..3d17f35 100755 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ bitstring>=3.1.5 bitarray>=0.8.1 Twisted>=16.3.0 dmr_utils3>=0.1.19 +configparser>=3.0.0 From bce4e0177534cd0ba1ec123161dddbfc89a1ec2d Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Wed, 19 Jun 2019 14:49:52 +0000 Subject: [PATCH 10/14] Randomisation of the Stream ID --- hblink.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hblink.py b/hblink.py index 42d2c2b..f1f440a 100755 --- a/hblink.py +++ b/hblink.py @@ -33,7 +33,7 @@ from binascii import a2b_hex as bhex from random import randint from hashlib import sha256, sha1 from hmac import new as hmac_new, compare_digest -from time import time +from time import time, sleep from collections import deque # Twisted is pretty important, so I keep it separate @@ -294,7 +294,9 @@ class HBSYSTEM(DatagramProtocol): radio3 = int.from_bytes(radio, 'big').to_bytes(3, 'big') radio4 = int.from_bytes(radio, 'big').to_bytes(4, 'big') xlx3 = xlx.to_bytes(3, 'big') - streamid = bytearray.fromhex('6df88f36') + streamid = randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big') + # Wait for .5 secs for the XLX to log us in + sleep(.500) for packetnr in range(5): if packetnr < 3: # First 3 packets, voice start, stream type e1 @@ -307,9 +309,10 @@ class HBSYSTEM(DatagramProtocol): packetnr1 = packetnr.to_bytes(1, 'big') strmtype1 = strmtype.to_bytes(1, 'big') _packet = b''.join([DMRD, packetnr1, radio3, xlx3, radio4, strmtype1, streamid, payload]) + sleep(.100) self.transport.write(_packet, mastersock) # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! - #logger.info('(%s) XLX Module Change Packet: %s', self._system, ahex(_packet)) + #logger.debug('(%s) XLX Module Change Packet: %s', self._system, ahex(_packet)) return def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data): From 02c605dab75494659f43354d4e70a1a629d8c1fe Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Wed, 19 Jun 2019 15:03:29 +0000 Subject: [PATCH 11/14] Removed timers, add disconnect/reconnect to make the conntion more reliable --- hblink.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hblink.py b/hblink.py index f1f440a..9a61fdd 100755 --- a/hblink.py +++ b/hblink.py @@ -33,7 +33,7 @@ from binascii import a2b_hex as bhex from random import randint from hashlib import sha256, sha1 from hmac import new as hmac_new, compare_digest -from time import time, sleep +from time import time from collections import deque # Twisted is pretty important, so I keep it separate @@ -296,7 +296,6 @@ class HBSYSTEM(DatagramProtocol): xlx3 = xlx.to_bytes(3, 'big') streamid = randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big') # Wait for .5 secs for the XLX to log us in - sleep(.500) for packetnr in range(5): if packetnr < 3: # First 3 packets, voice start, stream type e1 @@ -309,7 +308,6 @@ class HBSYSTEM(DatagramProtocol): packetnr1 = packetnr.to_bytes(1, 'big') strmtype1 = strmtype.to_bytes(1, 'big') _packet = b''.join([DMRD, packetnr1, radio3, xlx3, radio4, strmtype1, streamid, payload]) - sleep(.100) self.transport.write(_packet, mastersock) # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! #logger.debug('(%s) XLX Module Change Packet: %s', self._system, ahex(_packet)) @@ -665,6 +663,7 @@ class HBSYSTEM(DatagramProtocol): logger.info('(%s) Connection to Master Completed', self._system) # If we are an XLX, send the XLX module request here. if self._config['MODE'] == 'XLXPEER': + self.send_xlxmaster(self._config['RADIO_ID'], int(4000), self._config['MASTER_SOCKADDR']) self.send_xlxmaster(self._config['RADIO_ID'], self._config['XLXMODULE'], self._config['MASTER_SOCKADDR']) logger.info('(%s) Sending XLX Module request', self._system) else: From eba5174dc1c92d4d667707236ccde1da0d3dbdb2 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Fri, 21 Jun 2019 17:14:16 +0100 Subject: [PATCH 12/14] Update hblink-SAMPLE.cfg XLX needs LOOSE = True - making the sample reflect that. --- hblink-SAMPLE.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hblink-SAMPLE.cfg b/hblink-SAMPLE.cfg index a743373..a3b616c 100755 --- a/hblink-SAMPLE.cfg +++ b/hblink-SAMPLE.cfg @@ -211,7 +211,7 @@ TGID_TS2_ACL: PERMIT:ALL [XLX-1] MODE: XLXPEER ENABLED: True -LOOSE: False +LOOSE: True EXPORT_AMBE: False IP: PORT: 54002 From 9291ff175a3487e036e90017e00210ad8d482776 Mon Sep 17 00:00:00 2001 From: Steve Zingman Date: Wed, 17 Jul 2019 22:26:35 -0400 Subject: [PATCH 13/14] Fix typo --- const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/const.py b/const.py index 34c8ac8..09c6ff3 100755 --- a/const.py +++ b/const.py @@ -52,7 +52,7 @@ HBPF_SLT_VTERM = 0x2 # HomeBrew Protocol Commands DMRD = b'DMRD' MSTCL = b'MSTCL' -MSTNAK = b'MSTNAC' +MSTNAK = b'MSTNAK' MSTPONG = b'MSTPONG' MSTN = b'MSTN' MSTP = b'MSTP' From 1117eb7022c359b2741af4f4972a3385675401b7 Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Fri, 23 Aug 2019 09:07:08 -0500 Subject: [PATCH 14/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 565a25f..32e57c9 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ DVSwitch@groups.io **UPDATES:** -**PURPOSE:** Thanks to the work of Jonathan Naylor, G4KLX; Hans Barthen, DL5DI; Torsten Shultze, DG1HT we have an open protocol for internetworking DMR repeaters. Unfortunately, there's no generic client and/or master stacks. This project is to build an open-source, python-based implementation. This is a non-commercial license. Atribution is *required* if you use it. +**PURPOSE:** Thanks to the work of Jonathan Naylor, G4KLX; Hans Barthen, DL5DI; Torsten Shultze, DG1HT we have an open protocol for internetworking DMR repeaters. Unfortunately, there's no generic client and/or master stacks. This project is to build an open-source, python-based implementation. You are free to use this software however you want, however we ask that you provide attribution in some public venue (such as project, club, organization web site). This helps us see where the software is in use and track how it is used. For those who will ask: This is a piece of software that implements an open-source, amateur radio networking protocol. It is not a network. It is not indended to be a network. It is not intended to replace or circumvent a network. People do those things, code doesn't.