hotspot APRS position, initial commit

This commit is contained in:
KF7EEL 2022-03-15 13:54:12 -07:00
parent 09d88ed380
commit 19b32cfc67
4 changed files with 111 additions and 10 deletions

View File

@ -75,6 +75,8 @@ from socket import gethostbyname
from setproctitle import setproctitle
import copy
from pathlib import Path
@ -430,6 +432,14 @@ def config_reports(_config, _factory):
reporting.start(_config['REPORTS']['REPORT_INTERVAL'])
return report_server
# Send peer data that needs to be sent to APRS
def svrd_send_aprs_peer(_svrd_data):
_svrd_packet = SVRD
for system in CONFIG['SYSTEMS']:
if CONFIG['SYSTEMS'][system]['ENABLED']:
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
if 'PEER_APRS' in CONFIG['SYSTEMS'][system]['OTHER_OPTIONS']:
systems[system].send_system(SVRD + b'APRS' + str.encode(str(_svrd_data)))
# Send data to all OBP connections that have an encryption key. Data such as subscribers are sent to other HBNet servers.
def svrd_send_all(_svrd_data):
@ -445,8 +455,8 @@ def mirror_traffic(_data):
for system in CONFIG['SYSTEMS']:
if CONFIG['SYSTEMS'][system]['ENABLED']:
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
print(CONFIG['SYSTEMS'][system]['OTHER_OPTIONS'])
if 'MIRROR_ALL_TRAFFIC' in CONFIG['SYSTEMS'][system]['OTHER_OPTIONS']:
## print(CONFIG['SYSTEMS'][system]['OTHER_OPTIONS'])
if 'MIRROR_DATA' in CONFIG['SYSTEMS'][system]['OTHER_OPTIONS']:
systems[system].send_system(SVRD + b'MDAT' + _data)
@ -526,6 +536,7 @@ def ten_loop_func():
# Run this every minute for rule timer updates
def rule_timer_loop(unit_flood_time):
global UNIT_MAP
## print(HBSYSTEM('HOTSPOT', CONFIG, '')._peers)
logger.debug('(ROUTER) routerHBP Rule timer loop started')
_now = time()
#This is a good place to get and modify rules for users
@ -582,6 +593,17 @@ def rule_timer_loop(unit_flood_time):
if CONFIG['REPORTS']['REPORT']:
report_server.send_clients(b'bridge updated')
# Send PEER info to data gateway for APRS packet generation
try:
for system in CONFIG['SYSTEMS']:
if CONFIG['SYSTEMS'][system]['ENABLED']:
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER' or CONFIG['SYSTEMS'][system]['MODE'] == 'PROXY':
if CONFIG['SYSTEMS'][system]['STATIC_APRS_POSITION_ENABLED'] == True:
dict_data = ast.literal_eval(os.popen('cat /tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/' + system)).read())
svrd_send_aprs_peer(dict_data)
except Exception as e:
logger.error(e)
# run this every 10 seconds to trim orphaned stream ids
def stream_trimmer_loop():
@ -1593,6 +1615,7 @@ if __name__ == '__main__':
logger.info('(GLOBAL) SHUTDOWN: CONFBRIDGE IS TERMINATING WITH SIGNAL %s', str(_signal))
hblink_handler(_signal, _frame)
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
os.popen('rm /tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/*'))
reactor.stop()
# Set signal handers so that we can gracefully exit if need be
@ -1733,4 +1756,12 @@ if __name__ == '__main__':
## if LOCAL_CONFIG['WEB_SERVICE']['REMOTE_CONFIG_ENABLED']:
## with open(CONFIG['WEB_SERVICE']['BURN_FILE'], 'w') as f:
## f.write(str(download_burnlist(CONFIG)))
# Create folder so hbnet.py can access list PEER connections
print(CONFIG['LOGGER']['LOG_NAME'])
if Path('/tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/')).exists():
pass
else:
Path('/tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/')).mkdir()
reactor.run()

View File

@ -53,7 +53,6 @@ logger = logging.getLogger(__name__)
#### Modules for data gateway ###
# modules from DATA_CONFIG.py
from bitarray import bitarray
from binascii import b2a_hex as ahex
import re
##from binascii import a2b_hex as bhex
@ -79,11 +78,6 @@ try:
import maidenhead as mh
except:
logger.error('Error importing maidenhead module, make sure it is installed.')
# Module for sending email
try:
import smtplib
except:
logger.error('Error importing smtplib module, make sure it is installed.')
#Modules for APRS settings
import ast
@ -134,6 +128,8 @@ packet_assembly = {}
pistar_overflow = 0.1
peer_aprs = {}
# Keep track of what user needs which SMS format
def sms_type(sub, sms):
@ -1645,6 +1641,8 @@ def aprs_beacon_send():
aprslib.parse(beacon_packet)
aprs_send(beacon_packet)
logger.debug(beacon_packet)
peer_aprs_packets()
logger.info('Uploaded PEER APRS positions')
##### DMR data function ####
def data_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, mirror = False):
@ -1965,7 +1963,42 @@ def rule_timer_loop():
logger.error('Send que error')
logger.error(e)
def peer_aprs_packets():
for i in peer_aprs.items():
for h in i[1].items():
lat = decdeg2dms(float(h[1]['lat']))
lon = decdeg2dms(float(h[1]['lon']))
if lon[0] < 0:
lon_dir = 'W'
if lon[0] > 0:
lon_dir = 'E'
if lat[0] < 0:
lat_dir = 'S'
if lat[0] > 0:
lat_dir = 'N'
aprs_lat = str(str(re.sub('\..*|-', '', str(lat[0]))).zfill(2) + str(re.sub('\..*', '', str(lat[1])).zfill(2) + '.')) + str(re.sub('\..*', '', str(lat[2])).zfill(2)) + lat_dir
aprs_lon = str(str(re.sub('\..*|-', '', str(lon[0]))).zfill(3) + str(re.sub('\..*', '', str(lon[1])).zfill(2) + '.')) + str(re.sub('\..*', '', str(lon[2])).zfill(2)) + lon_dir
if len(str(h[0])) > 7:
ending = int(str(h[0])[-2:])
if ending in range(1, 25):
ssid = str(string.ascii_uppercase[ending - 1])
else:
ssid = 'A'
else:
ssid = 'A'
aprs_loc_packet = str(h[1]['call'] + '-' + ssid + '>APHBL3,TCPIP*:/' + str(datetime.datetime.utcnow().strftime("%H%M%Sh")) + str(aprs_lat) + '\\' + str(aprs_lon) + '&' + '/' + str(h[0]) + ' - ' + str(h[1]['description']))
logger.debug(aprs_loc_packet)
try:
aprslib.parse(aprs_loc_packet)
aprs_send(aprs_loc_packet)
except Exception as e:
logger.error(e)
##
## print(lat)
#### print(lon)
class OBP(OPENBRIDGE):
@ -1995,8 +2028,14 @@ class OBP(OPENBRIDGE):
def svrd_received(self, _mode, _data):
logger.debug('SVRD RCV')
print(_mode)
if _mode == b'UNIT':
UNIT_MAP[_data] = (self._system, time())
if _mode == b'APRS':
## print(_data)
## print(self._system)
peer_aprs[self._system] = ast.literal_eval(_data.decode('utf-8'))
if _mode == b'DATA' or _mode == b'MDAT':
## print(ahex(_data))
# DMR Data packet, sent via SVRD

View File

@ -87,6 +87,7 @@ REPORT_CLIENTS: 127.0.0.1
LOG_FILE: /tmp/hblink.log
LOG_HANDLERS: console-timed
LOG_LEVEL: DEBUG
# If running multiple HBNet servers on same host, LOG_NAME must be unique.
LOG_NAME: HBlink
# DOWNLOAD AND IMPORT SUBSCRIBER, PEER and TGID ALIASES

View File

@ -66,6 +66,9 @@ import re
# Encryption library
from cryptography.fernet import Fernet
from pathlib import Path
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
__author__ = 'Cortney T. Buffington, N0MJS'
@ -91,6 +94,17 @@ def decrypt_packet(key, message):
return token
def write_peer_file(master, peer_dict, CONFIG):
# Pull stuff for aprs out
print(peer_dict)
new_peers = {}
for d in peer_dict.items():
print(d[1])
new_peers[int_id(d[0])] = {'call': str(d[1]['CALLSIGN'].decode('utf-8')).strip(' '), 'lat':str(d[1]['LATITUDE'].decode('utf-8')), 'lon':str(d[1]['LONGITUDE'].decode('utf-8')), 'description':str(d[1]['DESCRIPTION'].decode('utf-8'))}
with open('/tmp/' + CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/' + master, 'w') as peer_file:
peer_file.write(str(new_peers))
peer_file.close()
# Timed loop used for reporting HBP status
def config_reports(_config, _factory):
def reporting_loop(_logger, _server):
@ -280,6 +294,7 @@ class OPENBRIDGE(DatagramProtocol):
class HBSYSTEM(DatagramProtocol):
def __init__(self, _name, _config, _report):
# Define a few shortcuts to make the rest of the class more readable
self._CONFIG = _config
self._system = _name
@ -434,6 +449,7 @@ class HBSYSTEM(DatagramProtocol):
# Aliased in __init__ to maintenance_loop if system is a master
def master_maintenance_loop(self):
print(self._peers)
logger.debug('(%s) Master maintenance loop started', self._system)
remove_list = []
for peer in self._peers:
@ -724,6 +740,8 @@ class HBSYSTEM(DatagramProtocol):
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
self.send_peer_loc(_peer_id, self._peers[_peer_id]['CALLSIGN'], '*', '*', '*', '*', '*', '*')
del self._peers[_peer_id]
#open, remove, and write change
write_peer_file(self._system, self._peers, self._CONFIG)
else:
_peer_id = _data[4:8] # Configure Command
@ -751,11 +769,14 @@ class HBSYSTEM(DatagramProtocol):
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'])
if 'NO_MAP' in str(_this_peer['LOCATION']):
self.send_peer_loc(_peer_id, self._peers[_peer_id]['CALLSIGN'], '*', '*', '*', '*', '*', '*')
## print(_this_peer['LOCATION'])
## pass
else:
# Function to open and write dict here
write_peer_file(self._system, self._peers, self._CONFIG)
self.send_peer_loc(_peer_id, _this_peer['CALLSIGN'], _this_peer['LATITUDE'], _this_peer['LONGITUDE'], _this_peer['URL'], _this_peer['DESCRIPTION'], _this_peer['LOCATION'], str(_this_peer['PACKAGE_ID']) + ' - ' + str(_this_peer['SOFTWARE_ID']))
else:
self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr)
@ -784,6 +805,8 @@ class HBSYSTEM(DatagramProtocol):
## self.mmdvm_cmd(_data)
if 'NO_MAP' in str(_data[8:]):
self.send_peer_loc(_peer_id, self._peers[_peer_id]['CALLSIGN'], '*', '*', '*', '*', '*', '*')
elif 'NO_MAP' not in str(_data[8:]):
write_peer_file(self._system, self._peers, self._CONFIG)
self.transport.write(b''.join([RPTACK, _peer_id]), _sockaddr)
elif _command == DMRA:
@ -1073,6 +1096,7 @@ if __name__ == '__main__':
logger.info('(GLOBAL) SHUTDOWN: HBLINK IS TERMINATING WITH SIGNAL %s', str(_signal))
hblink_handler(_signal, _frame)
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
os.popen('rm /tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/*'))
reactor.stop()
# Set signal handers so that we can gracefully exit if need be
@ -1104,4 +1128,10 @@ if __name__ == '__main__':
with open(CONFIG['WEB_SERVICE']['BURN_FILE'], 'w') as f:
f.write(str(download_burnlist(CONFIG)))
# Create folder so hbnet.py can access list PEER connections
if Path('/tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/')).exists():
pass
else:
Path('/tmp/' + (CONFIG['LOGGER']['LOG_NAME'] + '_PEERS/')).mkdir()
reactor.run()