merged into branch
This commit is contained in:
commit
d55a23a42f
@ -1,3 +1,9 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
# In this fork, APRS beaconing of peers is set on a per master configuration. Also, private-call-dev has been merged with master. Now with GPS decoding and APRS location reports for Anytone radios.
|
||||||
|
|
||||||
|
This is my "flavor" of HBLink3 that I use in production.
|
||||||
|
|
||||||
---
|
---
|
||||||
### FOR SUPPORT, DISCUSSION, GETTING INVOLVED ###
|
### FOR SUPPORT, DISCUSSION, GETTING INVOLVED ###
|
||||||
|
|
||||||
|
17
config.py
Executable file → Normal file
17
config.py
Executable file → Normal file
@ -26,6 +26,9 @@ updated if the items in the main configuraiton file (usually hblink.cfg)
|
|||||||
change.
|
change.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# Added config option for APRS in the master config section
|
||||||
|
# Modified by KF7EEL - 10-15-2020
|
||||||
|
|
||||||
import configparser
|
import configparser
|
||||||
import sys
|
import sys
|
||||||
import const
|
import const
|
||||||
@ -104,6 +107,7 @@ def build_config(_config_file):
|
|||||||
|
|
||||||
CONFIG = {}
|
CONFIG = {}
|
||||||
CONFIG['GLOBAL'] = {}
|
CONFIG['GLOBAL'] = {}
|
||||||
|
CONFIG['APRS'] = {}
|
||||||
CONFIG['REPORTS'] = {}
|
CONFIG['REPORTS'] = {}
|
||||||
CONFIG['LOGGER'] = {}
|
CONFIG['LOGGER'] = {}
|
||||||
CONFIG['ALIASES'] = {}
|
CONFIG['ALIASES'] = {}
|
||||||
@ -122,6 +126,15 @@ def build_config(_config_file):
|
|||||||
'TG1_ACL': config.get(section, 'TGID_TS1_ACL'),
|
'TG1_ACL': config.get(section, 'TGID_TS1_ACL'),
|
||||||
'TG2_ACL': config.get(section, 'TGID_TS2_ACL')
|
'TG2_ACL': config.get(section, 'TGID_TS2_ACL')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
elif section == 'APRS':
|
||||||
|
CONFIG['APRS'].update({
|
||||||
|
'ENABLED': config.getboolean(section, 'ENABLED'),
|
||||||
|
'CALLSIGN': config.get(section, 'CALLSIGN'),
|
||||||
|
'REPORT_INTERVAL': config.getint(section, 'REPORT_INTERVAL'),
|
||||||
|
'SERVER': config.get(section, 'SERVER'),
|
||||||
|
'MESSAGE': config.get(section, 'MESSAGE')
|
||||||
|
})
|
||||||
|
|
||||||
elif section == 'REPORTS':
|
elif section == 'REPORTS':
|
||||||
CONFIG['REPORTS'].update({
|
CONFIG['REPORTS'].update({
|
||||||
@ -182,7 +195,7 @@ def build_config(_config_file):
|
|||||||
'SOFTWARE_ID': bytes(config.get(section, 'SOFTWARE_ID').ljust(40)[:40], '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'),
|
'PACKAGE_ID': bytes(config.get(section, 'PACKAGE_ID').ljust(40)[:40], 'utf-8'),
|
||||||
'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'),
|
'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'),
|
||||||
'OPTIONS': b''.join([b'Type=HBlink;', bytes(config.get(section, 'OPTIONS'), 'utf-8')]),
|
'OPTIONS': bytes(config.get(section, 'OPTIONS'), 'utf-8'),
|
||||||
'USE_ACL': config.getboolean(section, 'USE_ACL'),
|
'USE_ACL': config.getboolean(section, 'USE_ACL'),
|
||||||
'SUB_ACL': config.get(section, 'SUB_ACL'),
|
'SUB_ACL': config.get(section, 'SUB_ACL'),
|
||||||
'TG1_ACL': config.get(section, 'TGID_TS1_ACL'),
|
'TG1_ACL': config.get(section, 'TGID_TS1_ACL'),
|
||||||
@ -249,6 +262,7 @@ def build_config(_config_file):
|
|||||||
CONFIG['SYSTEMS'].update({section: {
|
CONFIG['SYSTEMS'].update({section: {
|
||||||
'MODE': config.get(section, 'MODE'),
|
'MODE': config.get(section, 'MODE'),
|
||||||
'ENABLED': config.getboolean(section, 'ENABLED'),
|
'ENABLED': config.getboolean(section, 'ENABLED'),
|
||||||
|
'APRS_ENABLED': config.getboolean(section, 'APRS_ENABLED'),
|
||||||
'REPEAT': config.getboolean(section, 'REPEAT'),
|
'REPEAT': config.getboolean(section, 'REPEAT'),
|
||||||
'MAX_PEERS': config.getint(section, 'MAX_PEERS'),
|
'MAX_PEERS': config.getint(section, 'MAX_PEERS'),
|
||||||
'IP': gethostbyname(config.get(section, 'IP')),
|
'IP': gethostbyname(config.get(section, 'IP')),
|
||||||
@ -322,3 +336,4 @@ if __name__ == '__main__':
|
|||||||
return not _acl[0]
|
return not _acl[0]
|
||||||
|
|
||||||
print(acl_check(b'\x00\x01\x37', CONFIG['GLOBAL']['TG1_ACL']))
|
print(acl_check(b'\x00\x01\x37', CONFIG['GLOBAL']['TG1_ACL']))
|
||||||
|
|
||||||
|
14
hblink-SAMPLE.cfg
Executable file → Normal file
14
hblink-SAMPLE.cfg
Executable file → Normal file
@ -46,6 +46,19 @@ SUB_ACL: DENY:1
|
|||||||
TGID_TS1_ACL: PERMIT:ALL
|
TGID_TS1_ACL: PERMIT:ALL
|
||||||
TGID_TS2_ACL: PERMIT:ALL
|
TGID_TS2_ACL: PERMIT:ALL
|
||||||
|
|
||||||
|
# APRS - BY IU7IGU
|
||||||
|
# Enabling "APRS" will configure APRS-Beaconing of Master's connection
|
||||||
|
# like repeater and hotspots.
|
||||||
|
# REPORT_INTERVAL in Minute (ALLOW only > 3 Minutes)
|
||||||
|
# CALLSIGN: Callsign that will pubblish data on aprs server
|
||||||
|
# MESSAGE: This message will print on APRS description together RX and TX Frequency
|
||||||
|
|
||||||
|
[APRS]
|
||||||
|
ENABLED: False
|
||||||
|
REPORT_INTERVAL: 5
|
||||||
|
CALLSIGN:HB1LNK-11
|
||||||
|
SERVER:euro.aprs2.net
|
||||||
|
MESSAGE:Connesso ad HBLINK
|
||||||
|
|
||||||
# NOT YET WORKING: NETWORK REPORTING CONFIGURATION
|
# NOT YET WORKING: NETWORK REPORTING CONFIGURATION
|
||||||
# Enabling "REPORT" will configure a socket-based reporting
|
# Enabling "REPORT" will configure a socket-based reporting
|
||||||
@ -154,6 +167,7 @@ TGID_ACL: PERMIT:ALL
|
|||||||
[MASTER-1]
|
[MASTER-1]
|
||||||
MODE: MASTER
|
MODE: MASTER
|
||||||
ENABLED: True
|
ENABLED: True
|
||||||
|
APRS_ENABLED: False
|
||||||
REPEAT: True
|
REPEAT: True
|
||||||
MAX_PEERS: 10
|
MAX_PEERS: 10
|
||||||
EXPORT_AMBE: False
|
EXPORT_AMBE: False
|
||||||
|
171
hblink.py
Executable file → Normal file
171
hblink.py
Executable file → Normal file
@ -27,6 +27,9 @@ works stand-alone before troubleshooting any applications that use it. It has
|
|||||||
sufficient logging to be used standalone as a troubleshooting application.
|
sufficient logging to be used standalone as a troubleshooting application.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# Added config option for APRS in the master config section. Will only send packets to APRS-IS if each master is enabled.
|
||||||
|
# Modified by KF7EEL - 10-15-2020
|
||||||
|
|
||||||
# Specifig functions from modules we need
|
# Specifig functions from modules we need
|
||||||
from binascii import b2a_hex as ahex
|
from binascii import b2a_hex as ahex
|
||||||
from binascii import a2b_hex as bhex
|
from binascii import a2b_hex as bhex
|
||||||
@ -35,6 +38,9 @@ from hashlib import sha256, sha1
|
|||||||
from hmac import new as hmac_new, compare_digest
|
from hmac import new as hmac_new, compare_digest
|
||||||
from time import time
|
from time import time
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
import aprslib
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
# Twisted is pretty important, so I keep it separate
|
# Twisted is pretty important, so I keep it separate
|
||||||
from twisted.internet.protocol import DatagramProtocol, Factory, Protocol
|
from twisted.internet.protocol import DatagramProtocol, Factory, Protocol
|
||||||
@ -66,6 +72,8 @@ __email__ = 'n0mjs@me.com'
|
|||||||
# Global variables used whether we are a module or __main__
|
# Global variables used whether we are a module or __main__
|
||||||
systems = {}
|
systems = {}
|
||||||
|
|
||||||
|
open("nom_aprs","w").close
|
||||||
|
|
||||||
# Timed loop used for reporting HBP status
|
# Timed loop used for reporting HBP status
|
||||||
def config_reports(_config, _factory):
|
def config_reports(_config, _factory):
|
||||||
def reporting_loop(_logger, _server):
|
def reporting_loop(_logger, _server):
|
||||||
@ -80,10 +88,10 @@ def config_reports(_config, _factory):
|
|||||||
|
|
||||||
reporting = task.LoopingCall(reporting_loop, logger, report_server)
|
reporting = task.LoopingCall(reporting_loop, logger, report_server)
|
||||||
reporting.start(_config['REPORTS']['REPORT_INTERVAL'])
|
reporting.start(_config['REPORTS']['REPORT_INTERVAL'])
|
||||||
|
|
||||||
return report_server
|
return report_server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully by disconnecting from the masters and peers.
|
# Shut ourselves down gracefully by disconnecting from the masters and peers.
|
||||||
def hblink_handler(_signal, _frame):
|
def hblink_handler(_signal, _frame):
|
||||||
for system in systems:
|
for system in systems:
|
||||||
@ -104,6 +112,7 @@ def acl_check(_id, _acl):
|
|||||||
# OPENBRIDGE CLASS
|
# OPENBRIDGE CLASS
|
||||||
#************************************************
|
#************************************************
|
||||||
|
|
||||||
|
|
||||||
class OPENBRIDGE(DatagramProtocol):
|
class OPENBRIDGE(DatagramProtocol):
|
||||||
def __init__(self, _name, _config, _report):
|
def __init__(self, _name, _config, _report):
|
||||||
# Define a few shortcuts to make the rest of the class more readable
|
# Define a few shortcuts to make the rest of the class more readable
|
||||||
@ -112,7 +121,9 @@ class OPENBRIDGE(DatagramProtocol):
|
|||||||
self._report = _report
|
self._report = _report
|
||||||
self._config = self._CONFIG['SYSTEMS'][self._system]
|
self._config = self._CONFIG['SYSTEMS'][self._system]
|
||||||
self._laststrid = deque([], 20)
|
self._laststrid = deque([], 20)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def dereg(self):
|
def dereg(self):
|
||||||
logger.info('(%s) is mode OPENBRIDGE. No De-Registration required, continuing shutdown', self._system)
|
logger.info('(%s) is mode OPENBRIDGE. No De-Registration required, continuing shutdown', self._system)
|
||||||
|
|
||||||
@ -474,8 +485,19 @@ class HBSYSTEM(DatagramProtocol):
|
|||||||
and self._peers[_peer_id]['SOCKADDR'] == _sockaddr:
|
and self._peers[_peer_id]['SOCKADDR'] == _sockaddr:
|
||||||
logger.info('(%s) Peer is closing down: %s (%s)', self._system, self._peers[_peer_id]['CALLSIGN'], int_id(_peer_id))
|
logger.info('(%s) Peer is closing down: %s (%s)', self._system, self._peers[_peer_id]['CALLSIGN'], int_id(_peer_id))
|
||||||
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
|
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
|
||||||
|
#if self._CONFIG['APRS']['ENABLED']:
|
||||||
|
if self._config['APRS_ENABLED'] == True:
|
||||||
|
fn = 'nom_aprs'
|
||||||
|
f = open(fn)
|
||||||
|
output = []
|
||||||
|
for line in f:
|
||||||
|
if not str(int_id(_peer_id)) in line:
|
||||||
|
output.append(line)
|
||||||
|
f.close()
|
||||||
|
f = open(fn, 'w')
|
||||||
|
f.writelines(output)
|
||||||
|
f.close()
|
||||||
del self._peers[_peer_id]
|
del self._peers[_peer_id]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
_peer_id = _data[4:8] # Configure Command
|
_peer_id = _data[4:8] # Configure Command
|
||||||
if _peer_id in self._peers \
|
if _peer_id in self._peers \
|
||||||
@ -502,6 +524,127 @@ class HBSYSTEM(DatagramProtocol):
|
|||||||
|
|
||||||
self.send_peer(_peer_id, b''.join([RPTACK, _peer_id]))
|
self.send_peer(_peer_id, b''.join([RPTACK, _peer_id]))
|
||||||
logger.info('(%s) Peer %s (%s) has sent repeater configuration', self._system, _this_peer['CALLSIGN'], _this_peer['RADIO_ID'])
|
logger.info('(%s) Peer %s (%s) has sent repeater configuration', self._system, _this_peer['CALLSIGN'], _this_peer['RADIO_ID'])
|
||||||
|
#APRS IMPLEMENTATION
|
||||||
|
conta = 0
|
||||||
|
lista_blocco=['ysf', 'xlx', 'nxdn', 'dstar', 'echolink','p25', 'svx']
|
||||||
|
#if self._CONFIG['SYSTEMS']['APRS_ENABLED']['ENABLED'] and self._CONFIG['APRS']['ENABLED'] and not str(_this_peer['CALLSIGN'].decode('UTF-8')).replace(' ', '').isalpha() :
|
||||||
|
# Check if master has APRS enabled instead of global.
|
||||||
|
if self._config['APRS_ENABLED'] and not str(_this_peer['CALLSIGN'].decode('UTF-8')).replace(' ', '').isalpha() :
|
||||||
|
file = open("nom_aprs","r")
|
||||||
|
linee = file.readlines()
|
||||||
|
file.close()
|
||||||
|
for link in lista_blocco:
|
||||||
|
if int(str(_this_peer['CALLSIGN'].decode('UTF-8')).replace(' ', '').find(link.upper())) == 0:
|
||||||
|
conta = conta + 1
|
||||||
|
if len(linee) > 0:
|
||||||
|
logging.info('Leggo')
|
||||||
|
for linea in linee:
|
||||||
|
dati_l = linea.split(':')
|
||||||
|
if str(_this_peer['RADIO_ID']) == str(dati_l[1]):
|
||||||
|
conta = conta + 1
|
||||||
|
|
||||||
|
if conta == 0:
|
||||||
|
file=open("nom_aprs",'a')
|
||||||
|
if len(str(_this_peer['RADIO_ID'])) > 7:
|
||||||
|
id_pr=int(str(_this_peer['RADIO_ID'])[-2:])
|
||||||
|
callsign_u=str(_this_peer['CALLSIGN'].decode('UTF-8'))+"-"+str(id_pr)
|
||||||
|
file.write(callsign_u.replace(' ', '')+ ":"+ str(_this_peer['RADIO_ID']) +":"+ str(_this_peer['RX_FREQ'].decode('UTF-8')) + ":" + str(_this_peer['TX_FREQ'].decode('UTF-8'))+ ":" + str(_this_peer['LATITUDE'].decode('UTF-8')) + ":" + str(_this_peer['LONGITUDE'].decode('UTF-8')) + "\n")
|
||||||
|
file.close()
|
||||||
|
else:
|
||||||
|
file.write(str(_this_peer['CALLSIGN'].decode('UTF-8')).replace(' ', '')+ ":"+ str(_this_peer['RADIO_ID']) +":"+ str(_this_peer['RX_FREQ'].decode('UTF-8')) + ":" + str(_this_peer['TX_FREQ'].decode('UTF-8'))+ ":" + str(_this_peer['LATITUDE'].decode('UTF-8')) + ":" + str(_this_peer['LONGITUDE'].decode('UTF-8')) + "\n")
|
||||||
|
file.close()
|
||||||
|
else:
|
||||||
|
if conta == 0:
|
||||||
|
file=open("nom_aprs",'a')
|
||||||
|
if len(str(_this_peer['RADIO_ID'])) > 7:
|
||||||
|
id_pr=int(str(_this_peer['RADIO_ID'])[-2:])
|
||||||
|
callsign_u=str(_this_peer['CALLSIGN'].decode('UTF-8'))+"-"+str(id_pr)
|
||||||
|
file.write(callsign_u.replace(' ', '')+ ":"+ str(_this_peer['RADIO_ID']) +":"+ str(_this_peer['RX_FREQ'].decode('UTF-8')) + ":" + str(_this_peer['TX_FREQ'].decode('UTF-8'))+ ":" + str(_this_peer['LATITUDE'].decode('UTF-8')) + ":" + str(_this_peer['LONGITUDE'].decode('UTF-8')) + "\n")
|
||||||
|
file.close()
|
||||||
|
else:
|
||||||
|
file.write(str(_this_peer['CALLSIGN'].decode('UTF-8')).replace(' ', '')+ ":"+ str(_this_peer['RADIO_ID']) +":"+ str(_this_peer['RX_FREQ'].decode('UTF-8')) + ":" + str(_this_peer['TX_FREQ'].decode('UTF-8'))+ ":" + str(_this_peer['LATITUDE'].decode('UTF-8')) + ":" + str(_this_peer['LONGITUDE'].decode('UTF-8')) + "\n")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
def sendAprs():
|
||||||
|
AIS = aprslib.IS(str(self._CONFIG['APRS']['CALLSIGN']), passwd=aprslib.passcode(str(self._CONFIG['APRS']['CALLSIGN'])), host=str(self._CONFIG['APRS']['SERVER']), port=14580)
|
||||||
|
AIS.connect()
|
||||||
|
f = open('nom_aprs', 'r')
|
||||||
|
lines = f.readlines()
|
||||||
|
if lines:
|
||||||
|
for line in lines:
|
||||||
|
if line != ' ':
|
||||||
|
lat_verso = ''
|
||||||
|
lon_verso = ''
|
||||||
|
dati = line.split(":")
|
||||||
|
d1_c = int(float(dati[4]))
|
||||||
|
d2_c = int(float(dati[5]))
|
||||||
|
|
||||||
|
if d1_c < 0:
|
||||||
|
d1 = abs(d1_c)
|
||||||
|
dm1=abs(float(dati[4])) - d1
|
||||||
|
dm1_s= float(dm1) * 60
|
||||||
|
dm1_u="{:.4f}".format(dm1_s)
|
||||||
|
if d1 < 10 and d1 > -10:
|
||||||
|
lat_utile='0'+str(d1)+str(dm1_u)
|
||||||
|
else:
|
||||||
|
lat_utile = str(d1)+str(dm1_u)
|
||||||
|
lat_verso = 'S'
|
||||||
|
else:
|
||||||
|
d1 = int(float(dati[4]))
|
||||||
|
dm1=float(dati[4]) - d1
|
||||||
|
dm1_s= float(dm1) * 60
|
||||||
|
dm1_u="{:.4f}".format(dm1_s)
|
||||||
|
if d1 < 10 and d1 > -10:
|
||||||
|
lat_utile='0'+str(d1)+str(dm1_u)
|
||||||
|
else:
|
||||||
|
lat_utile = str(d1)+str(dm1_u)
|
||||||
|
lat_verso = 'N'
|
||||||
|
|
||||||
|
|
||||||
|
if d2_c < 0:
|
||||||
|
d2=abs(d2_c)
|
||||||
|
dm2=abs(float(dati[5])) - d2
|
||||||
|
dm2_s= float(dm2) * 60
|
||||||
|
dm2_u="{:.3f}".format(dm2_s)
|
||||||
|
if d2 < 10 and d2 > -10:
|
||||||
|
lon_utile = '00'+str(d2)+str(dm2_u)
|
||||||
|
elif d2 < 100:
|
||||||
|
lon_utile = '0'+str(d2)+str(dm2_u)
|
||||||
|
else:
|
||||||
|
lon_utile = str(d2)+str(dm2_s)
|
||||||
|
lon_verso = 'W'
|
||||||
|
|
||||||
|
else:
|
||||||
|
d2=int(float(dati[5]))
|
||||||
|
dm2=float(dati[5]) - d2
|
||||||
|
dm2_s= float(dm2) * 60
|
||||||
|
dm2_u="{:.3f}".format(dm2_s)
|
||||||
|
if d2 < 10 and d2 > -10:
|
||||||
|
lon_utile = '00'+str(d2)+str(dm2_u)
|
||||||
|
elif d2 < 100:
|
||||||
|
lon_utile = '0'+str(d2)+str(dm2_u)
|
||||||
|
else:
|
||||||
|
lon_utile = str(d2)+str(dm2_u)
|
||||||
|
lon_verso = 'E'
|
||||||
|
|
||||||
|
rx_utile = dati[2][0:3]+'.'+dati[2][3:]
|
||||||
|
tx_utile = dati[3][0:3]+'.'+dati[3][3:]
|
||||||
|
|
||||||
|
# Modified latitude and longitude strings from original, kept getting "uncompressed location" error from aprs.fi. Also will add Color Code to status, not yet working.
|
||||||
|
AIS.sendall(str(dati[0])+">APRS,TCPIP*,qAC,"+str(self._CONFIG['APRS']['CALLSIGN'])+":!"+str(lat_utile)[:7]+lat_verso+"/"+str(lon_utile)[:8]+lon_verso+"r"+str(self._CONFIG['APRS']['MESSAGE'])+' RX: '+str(rx_utile)[:8]+' TX: '+str(tx_utile)[:8]) # + ' CC: ' + str(_this_peer['COLORCODE']).decode('UTF-8'))
|
||||||
|
#logging.info(str(dati[0])+">APRS,TCPIP*,qAC,"+str(self._CONFIG['APRS']['CALLSIGN'])+":!"+str(lat_utile)[:7]+lat_verso+"/"+str(lon_utile)[:8]+lon_verso+"r"+str(self._CONFIG['APRS']['MESSAGE'])+' RX: '+str(rx_utile)[:8]+' TX: '+str(tx_utile)[:8] + ' CC:' + str(_this_peer['COLORCODE']))
|
||||||
|
logging.info('APRS INVIATO / APRS Packet Sent')
|
||||||
|
|
||||||
|
if conta == 0:
|
||||||
|
if self._CONFIG['APRS']['REPORT_INTERVAL'] > 3:
|
||||||
|
l=task.LoopingCall(sendAprs)
|
||||||
|
l.start(float(int(self._CONFIG['APRS']['REPORT_INTERVAL']*60)))
|
||||||
|
else:
|
||||||
|
l=task.LoopingCall(sendAprs)
|
||||||
|
l.start(5*60)
|
||||||
|
logger.info('Report Time APRS to short')
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
|
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
|
||||||
logger.warning('(%s) Peer info from Radio ID that has not logged in: %s', self._system, int_id(_peer_id))
|
logger.warning('(%s) Peer info from Radio ID that has not logged in: %s', self._system, int_id(_peer_id))
|
||||||
@ -519,18 +662,6 @@ class HBSYSTEM(DatagramProtocol):
|
|||||||
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
|
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
|
||||||
logger.warning('(%s) Ping from Radio ID that is not logged in: %s', self._system, int_id(_peer_id))
|
logger.warning('(%s) Ping from Radio ID that is not logged in: %s', self._system, int_id(_peer_id))
|
||||||
|
|
||||||
elif _command == RPTO:
|
|
||||||
_peer_id = _data[4:8]
|
|
||||||
if _peer_id in self._peers \
|
|
||||||
and self._peers[_peer_id]['CONNECTION'] == 'YES' \
|
|
||||||
and self._peers[_peer_id]['SOCKADDR'] == _sockaddr:
|
|
||||||
logger.info('(%s) Peer %s (%s) has send options: %s', self._system, self._peers[_peer_id]['CALLSIGN'], int_id(_peer_id), _data[8:])
|
|
||||||
self.transport.write(b''.join([RPTACK, _peer_id]), _sockaddr)
|
|
||||||
|
|
||||||
elif _command == DMRA:
|
|
||||||
_peer_id = _data[4:8]
|
|
||||||
logger.info('(%s) Recieved DMR Talker Alias from peer %s, subscriber %s', self._system, self._peers[_peer_id]['CALLSIGN'], int_id(_rf_src))
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error('(%s) Unrecognized command. Raw HBP PDU: %s', self._system, ahex(_data))
|
logger.error('(%s) Unrecognized command. Raw HBP PDU: %s', self._system, ahex(_data))
|
||||||
|
|
||||||
@ -660,7 +791,6 @@ class HBSYSTEM(DatagramProtocol):
|
|||||||
self._stats['CONNECTION'] = 'YES'
|
self._stats['CONNECTION'] = 'YES'
|
||||||
self._stats['CONNECTED'] = time()
|
self._stats['CONNECTED'] = time()
|
||||||
logger.info('(%s) Connection to Master Completed', self._system)
|
logger.info('(%s) Connection to Master Completed', self._system)
|
||||||
|
|
||||||
# If we are an XLX, send the XLX module request here.
|
# If we are an XLX, send the XLX module request here.
|
||||||
if self._config['MODE'] == 'XLXPEER':
|
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'], int(4000), self._config['MASTER_SOCKADDR'])
|
||||||
@ -781,6 +911,8 @@ if __name__ == '__main__':
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
import aprslib
|
||||||
|
import threading
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
@ -802,12 +934,12 @@ if __name__ == '__main__':
|
|||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
logger = log.config_logging(CONFIG['LOGGER'])
|
logger = log.config_logging(CONFIG['LOGGER'])
|
||||||
logger.info('\n\nCopyright (c) 2013, 2014, 2015, 2016, 2018, 2019, 2020\n\tThe Regents of the K0USY Group. All rights reserved.\n')
|
logger.info('APRS IMPLEMENTATION BY IU7IGU email: iu7igu@yahoo.com \n APRS per master config by KF7EEL - KF7EEL@qsl.net \n\nCopyright (c) 2013, 2014, 2015, 2016, 2018, 2019, 2020\n\tThe Regents of the K0USY Group. All rights reserved.')
|
||||||
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')
|
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')
|
||||||
|
|
||||||
# Set up the signal handler
|
# Set up the signal handler
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('(GLOBAL) SHUTDOWN: HBLINK IS TERMINATING WITH SIGNAL %s', str(_signal))
|
logger.info('(GLOBAL) SHUTDOWN: HBLINK IS TERMINATING WITH SIGNAL %s', str(_signal))
|
||||||
hblink_handler(_signal, _frame)
|
hblink_handler(_signal, _frame)
|
||||||
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
|
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
@ -833,7 +965,10 @@ if __name__ == '__main__':
|
|||||||
systems[system] = OPENBRIDGE(system, CONFIG, report_server)
|
systems[system] = OPENBRIDGE(system, CONFIG, report_server)
|
||||||
else:
|
else:
|
||||||
systems[system] = HBSYSTEM(system, CONFIG, report_server)
|
systems[system] = HBSYSTEM(system, CONFIG, report_server)
|
||||||
|
logger.info(CONFIG['SYSTEMS'][system]['APRS_ENABLED'])
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
|
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
|
||||||
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
|
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
|
||||||
|
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,3 +3,4 @@ bitarray>=0.8.1
|
|||||||
Twisted>=16.3.0
|
Twisted>=16.3.0
|
||||||
dmr_utils3>=0.1.19
|
dmr_utils3>=0.1.19
|
||||||
configparser>=3.0.0
|
configparser>=3.0.0
|
||||||
|
aprslib>=0.6.42
|
||||||
|
Loading…
Reference in New Issue
Block a user