hotspot APRS position, initial commit
This commit is contained in:
parent
09d88ed380
commit
19b32cfc67
35
bridge.py
35
bridge.py
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
30
hblink.py
30
hblink.py
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue