From 59ac3a693e80956e2d4f8eb3bea69ceca863b0a3 Mon Sep 17 00:00:00 2001 From: KF7EEL Date: Tue, 15 Jun 2021 12:28:44 -0700 Subject: [PATCH] working rules download, fixed XLX stuff --- bridge.py | 129 ++++++++++++++++++-------- hblink.py | 4 +- hotspot_proxy_v2.py | 204 ++++++++++++++++++++++++++++++++++++++++++ user_managment/app.py | 198 +++++++++++++++++++++++++++------------- 4 files changed, 432 insertions(+), 103 deletions(-) create mode 100644 hotspot_proxy_v2.py diff --git a/bridge.py b/bridge.py index e3f0dd7..797c252 100755 --- a/bridge.py +++ b/bridge.py @@ -152,15 +152,38 @@ def download_config(L_CONFIG_FILE, cli_file): if iterate_config[i]['MODE'] == 'MASTER' or iterate_config[i]['MODE'] == 'PROXY': corrected_config['SYSTEMS'][i]['TG1_ACL'] = config.acl_build(iterate_config[i]['TG1_ACL'], 16776415) corrected_config['SYSTEMS'][i]['TG2_ACL'] = config.acl_build(iterate_config[i]['TG2_ACL'], 16776415) + corrected_config['SYSTEMS'][i]['PASSPHRASE'] = bytes(iterate_config[i]['PASSPHRASE'], 'utf-8') if iterate_config[i]['MODE'] == 'OPENBRIDGE': corrected_config['SYSTEMS'][i]['NETWORK_ID'] = int(iterate_config[i]['NETWORK_ID']).to_bytes(4, 'big') + corrected_config['SYSTEMS'][i]['PASSPHRASE'] = bytes(iterate_config[i]['PASSPHRASE'].ljust(20,'\x00')[:20], 'utf-8') + if iterate_config[i]['MODE'] == 'PEER' or iterate_config[i]['MODE'] == 'XLXPEER': corrected_config['SYSTEMS'][i]['RADIO_ID'] = int(iterate_config[i]['RADIO_ID']).to_bytes(4, 'big') corrected_config['SYSTEMS'][i]['TG1_ACL'] = config.acl_build(iterate_config[i]['TG1_ACL'], 16776415) corrected_config['SYSTEMS'][i]['TG2_ACL'] = config.acl_build(iterate_config[i]['TG2_ACL'], 16776415) corrected_config['SYSTEMS'][i]['MASTER_SOCKADDR'] = tuple(iterate_config[i]['MASTER_SOCKADDR']) corrected_config['SYSTEMS'][i]['SOCK_ADDR'] = tuple(iterate_config[i]['SOCK_ADDR']) - if iterate_config[i]['MODE'] == 'PEER': + corrected_config['SYSTEMS'][i]['PASSPHRASE'] = bytes((iterate_config[i]['PASSPHRASE']), 'utf-8') + corrected_config['SYSTEMS'][i]['CALLSIGN'] = bytes((iterate_config[i]['CALLSIGN']).ljust(8)[:8], 'utf-8') + corrected_config['SYSTEMS'][i]['RX_FREQ']: bytes((iterate_config[i]['RX_FREQ']).ljust(9)[:9], 'utf-8') + corrected_config['SYSTEMS'][i]['TX_FREQ'] = bytes((iterate_config[i]['TX_FREQ']).ljust(9)[:9], 'utf-8') + corrected_config['SYSTEMS'][i]['TX_POWER'] = bytes((iterate_config[i]['TX_POWER']).rjust(2,'0'), 'utf-8') + corrected_config['SYSTEMS'][i]['COLORCODE'] = bytes((iterate_config[i]['COLORCODE']).rjust(2,'0'), 'utf-8') + corrected_config['SYSTEMS'][i]['LATITUDE'] = bytes((iterate_config[i]['LATITUDE']).ljust(8)[:8], 'utf-8') + corrected_config['SYSTEMS'][i]['LONGITUDE'] = bytes((iterate_config[i]['LONGITUDE']).ljust(9)[:9], 'utf-8') + corrected_config['SYSTEMS'][i]['HEIGHT'] = bytes((iterate_config[i]['HEIGHT']).rjust(3,'0'), 'utf-8') + corrected_config['SYSTEMS'][i]['LOCATION'] = bytes((iterate_config[i]['LOCATION']).ljust(20)[:20], 'utf-8') + corrected_config['SYSTEMS'][i]['DESCRIPTION'] = bytes((iterate_config[i]['DESCRIPTION']).ljust(19)[:19], 'utf-8') + corrected_config['SYSTEMS'][i]['SLOTS'] = bytes((iterate_config[i]['SLOTS']), 'utf-8') + corrected_config['SYSTEMS'][i]['URL'] = bytes((iterate_config[i]['URL']).ljust(124)[:124], 'utf-8') + corrected_config['SYSTEMS'][i]['SOFTWARE_ID'] = bytes(('HBNet DMR').ljust(40)[:40], 'utf-8') + corrected_config['SYSTEMS'][i]['PACKAGE_ID'] = bytes(('Dev').ljust(40)[:40], 'utf-8') + corrected_config['SYSTEMS'][i]['OPTIONS'] = b''.join([b'Type=HBlink;', bytes(iterate_config[i]['OPTIONS'], 'utf-8')]) + + + + + if iterate_config[i]['MODE'] == 'PEER': corrected_config['SYSTEMS'][i].update({'STATS':{ 'CONNECTION': 'NO', # NO, RTPL_SENT, AUTHENTICATED, CONFIG-SENT, YES 'CONNECTED': None, @@ -171,17 +194,17 @@ def download_config(L_CONFIG_FILE, cli_file): 'LAST_PING_TX_TIME': 0, 'LAST_PING_ACK_TIME': 0, }}) - if iterate_config[i]['MODE'] == 'XLXPEER': - corrected_config['SYSTEMS'][i].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, - }}) + if iterate_config[i]['MODE'] == 'XLXPEER': + corrected_config['SYSTEMS'][i].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, + }}) corrected_config['SYSTEMS'][i]['USE_ACL'] = iterate_config[i]['USE_ACL'] corrected_config['SYSTEMS'][i]['SUB_ACL'] = config.acl_build(iterate_config[i]['SUB_ACL'], 16776415) @@ -190,8 +213,8 @@ def download_config(L_CONFIG_FILE, cli_file): ## for i in iterate_masters: ## iterate_masters['SYSTEMS'] ## config.process_acls(corrected_config) - print(corrected_config['SYSTEMS']) - print('-------') +## print(corrected_config['SYSTEMS']) +## print('-------') return corrected_config # For exception, write blank dict except requests.ConnectionError: @@ -233,7 +256,7 @@ def hotspot_proxy(listen_port, port_start, port_stop): totalPorts = DestPortEnd - DestportStart freePorts = totalPorts - count - print("{} ports out of {} in use ({} free)".format(count,totalPorts,freePorts)) + logger.info("{} ports out of {} in use ({} free)".format(count,totalPorts,freePorts)) @@ -249,7 +272,7 @@ def hotspot_proxy(listen_port, port_start, port_stop): # target system for a unit is identified # format 'unit_id': ('SYSTEM', time) UNIT_MAP = {} - +BRIDGES = {} # Timed loop used for reporting HBP status # @@ -1321,26 +1344,34 @@ if __name__ == '__main__': peer_ids, subscriber_ids, talkgroup_ids = mk_aliases(CONFIG) # Import the ruiles file as a module, and create BRIDGES from it - spec = importlib.util.spec_from_file_location("module.name", cli_args.RULES_FILE) - rules_module = importlib.util.module_from_spec(spec) - try: - spec.loader.exec_module(rules_module) - logger.info('(ROUTER) Routing bridges file found and bridges imported: %s', cli_args.RULES_FILE) - except (ImportError, FileNotFoundError): - sys.exit('(ROUTER) TERMINATING: Routing bridges file not found or invalid: {}'.format(cli_args.RULES_FILE)) - # Attempt to use downloaded rules - if LOCAL_CONFIG['USER_MANAGER']['REMOTE_CONFIG_ENABLED']: - - # Build the routing rules file - BRIDGES = make_bridges(rules_module.BRIDGES) - # Get rule parameter for private calls - UNIT = download_rules(LOCAL_CONFIG, cli_args.CONFIG_FILE)[0] - - else: - # Build the routing rules file - BRIDGES = make_bridges(rules_module.BRIDGES) - # Get rule parameter for private calls - UNIT = rules_module.UNIT +## spec = importlib.util.spec_from_file_location("module.name", cli_args.RULES_FILE) +## rules_module = importlib.util.module_from_spec(spec) +## print(download_rules(LOCAL_CONFIG, cli_args.CONFIG_FILE)) +## try: +## spec.loader.exec_module(rules_module) +## logger.info('(ROUTER) Routing bridges file found and bridges imported: %s', cli_args.RULES_FILE) +## except (ImportError, FileNotFoundError): +## sys.exit('(ROUTER) TERMINATING: Routing bridges file not found or invalid: {}'.format(cli_args.RULES_FILE)) +## # Attempt to use downloaded rules +## if LOCAL_CONFIG['USER_MANAGER']['REMOTE_CONFIG_ENABLED']: +## +## # Build the routing rules file +## BRIDGES = make_bridges(download_rules(LOCAL_CONFIG, cli_args.CONFIG_FILE)[1]) #make_bridges(rules_module.BRIDGES) +## # Get rule parameter for private calls +## UNIT = download_rules(LOCAL_CONFIG, cli_args.CONFIG_FILE)[0] +## +## else: +## try: +## spec.loader.exec_module(rules_module) +## logger.info('(ROUTER) Routing bridges file found and bridges imported: %s', cli_args.RULES_FILE) +## except (ImportError, FileNotFoundError): +## sys.exit('(ROUTER) TERMINATING: Routing bridges file not found or invalid: {}'.format(cli_args.RULES_FILE)) +## spec = importlib.util.spec_from_file_location("module.name", cli_args.RULES_FILE) +## rules_module = importlib.util.module_from_spec(spec) +## # Build the routing rules file +## BRIDGES = make_bridges(rules_module.BRIDGES) +## # Get rule parameter for private calls +## UNIT = rules_module.UNIT # INITIALIZE THE REPORTING LOOP if CONFIG['REPORTS']['REPORT']: @@ -1375,6 +1406,7 @@ if __name__ == '__main__': 'MODE': 'MASTER', 'ENABLED': True, 'STATIC_APRS_POSITION_ENABLED': CONFIG['SYSTEMS'][i]['STATIC_APRS_POSITION_ENABLED'], + 'USE_USER_MAN': CONFIG['SYSTEMS'][i]['USE_USER_MAN'], 'REPEAT': CONFIG['SYSTEMS'][i]['REPEAT'], 'MAX_PEERS': 1, 'IP': '127.0.0.1', @@ -1393,7 +1425,29 @@ if __name__ == '__main__': # Remove original MASTER stanza to prevent errors CONFIG['SYSTEMS'].pop(i) logger.info('Generated MASTER instances for proxy set: ' + i) - + + # Attempt to use downloaded rules + if LOCAL_CONFIG['USER_MANAGER']['REMOTE_CONFIG_ENABLED']: + + # Build the routing rules file + BRIDGES = make_bridges(download_rules(LOCAL_CONFIG, cli_args.CONFIG_FILE)[1]) #make_bridges(rules_module.BRIDGES) + # Get rule parameter for private calls + UNIT = download_rules(LOCAL_CONFIG, cli_args.CONFIG_FILE)[0] + + else: + try: + spec.loader.exec_module(rules_module) + logger.info('(ROUTER) Routing bridges file found and bridges imported: %s', cli_args.RULES_FILE) + except (ImportError, FileNotFoundError): + sys.exit('(ROUTER) TERMINATING: Routing bridges file not found or invalid: {}'.format(cli_args.RULES_FILE)) + spec = importlib.util.spec_from_file_location("module.name", cli_args.RULES_FILE) + rules_module = importlib.util.module_from_spec(spec) + # Build the routing rules file + BRIDGES = make_bridges(rules_module.BRIDGES) + # Get rule parameter for private calls + UNIT = rules_module.UNIT + + for system in CONFIG['SYSTEMS']: if CONFIG['SYSTEMS'][system]['ENABLED']: if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE': @@ -1422,5 +1476,4 @@ if __name__ == '__main__': with open(CONFIG['USER_MANAGER']['BURN_FILE'], 'w') as f: f.write(str(download_burnlist(CONFIG))) - reactor.run() diff --git a/hblink.py b/hblink.py index d87589a..5a3f5dc 100755 --- a/hblink.py +++ b/hblink.py @@ -435,7 +435,7 @@ class HBSYSTEM(DatagramProtocol): # Aliased in __init__ to datagramReceived if system is a master def master_datagramReceived(self, _data, _sockaddr): - global user_db +## global user_db # Keep This Line Commented Unless HEAVILY Debugging! # logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_data)) @@ -525,7 +525,7 @@ class HBSYSTEM(DatagramProtocol): user_auth = self.ums_response['allow'] else: user_auth = False - print(user_auth) +## print(user_auth) if self._config['USE_USER_MAN'] == False: # print('False') if acl_check(_peer_id, self._CONFIG['GLOBAL']['REG_ACL']) and acl_check(_peer_id, self._config['REG_ACL']): diff --git a/hotspot_proxy_v2.py b/hotspot_proxy_v2.py new file mode 100644 index 0000000..34120a5 --- /dev/null +++ b/hotspot_proxy_v2.py @@ -0,0 +1,204 @@ +from twisted.internet.protocol import DatagramProtocol +from twisted.internet import reactor, task +from time import time +from resettabletimer import ResettableTimer +from dmr_utils3.utils import int_id +import random + +# Does anybody read this stuff? There's a PEP somewhere that says I should do this. +__author__ = 'Simon Adlem - G7RZU' +__copyright__ = 'Copyright (c) Simon Adlem, G7RZU 2020,2021' +__credits__ = 'Jon Lee, G4TSN; Norman Williams, M6NBP' +__license__ = 'GNU GPLv3' +__maintainer__ = 'Simon Adlem G7RZU' +__email__ = 'simon@gb7fr.org.uk' + +class Proxy(DatagramProtocol): + + def __init__(self,Master,ListenPort,connTrack,blackList,Timeout,Debug,DestportStart,DestPortEnd): + self.master = Master + self.connTrack = connTrack + self.peerTrack = {} + self.timeout = Timeout + self.debug = Debug + self.blackList = blackList + self.destPortStart = DestportStart + self.destPortEnd = DestPortEnd + self.numPorts = DestPortEnd - DestportStart + + + def reaper(self,_peer_id): + if self.debug: + print("dead",_peer_id) + self.transport.write(b'RPTCL'+_peer_id, ('127.0.0.1',self.peerTrack[_peer_id]['dport'])) + self.connTrack[self.peerTrack[_peer_id]['dport']] = False + del self.peerTrack[_peer_id] + + + def datagramReceived(self, data, addr): + + # HomeBrew Protocol Commands + DMRD = b'DMRD' + DMRA = b'DMRA' + MSTCL = b'MSTCL' + MSTNAK = b'MSTNAK' + MSTPONG = b'MSTPONG' + MSTN = b'MSTN' + MSTP = b'MSTP' + MSTC = b'MSTC' + RPTL = b'RPTL' + RPTPING = b'RPTPING' + RPTCL = b'RPTCL' + RPTL = b'RPTL' + RPTACK = b'RPTACK' + RPTK = b'RPTK' + RPTC = b'RPTC' + RPTP = b'RPTP' + RPTA = b'RPTA' + RPTO = b'RPTO' + + host,port = addr + + nowtime = time() + + Debug = self.debug + + #If the packet comes from the master + if host == self.master: + _command = data[:4] + + if _command == DMRD: + _peer_id = data[11:15] + elif _command == RPTA: + if data[6:10] in self.peerTrack: + _peer_id = data[6:10] + else: + _peer_id = self.connTrack[port] + elif _command == MSTN: + _peer_id = data[6:10] + self.peerTrack[_peer_id]['timer'].cancel() + self.reaper(_peer_id) + return + elif _command == MSTP: + _peer_id = data[7:11] + elif _command == MSTC: + _peer_id = data[5:9] + self.peerTrack[_peer_id]['timer'].cancel() + self.reaper(_peer_id) + return + + # _peer_id = self.connTrack[port] + if self.debug: + print(data) + if _peer_id and _peer_id in self.peerTrack: + self.transport.write(data,(self.peerTrack[_peer_id]['shost'],self.peerTrack[_peer_id]['sport'])) + #self.peerTrack[_peer_id]['timer'].reset() + return + + + + else: + _command = data[:4] + + if _command == DMRD: # DMRData -- encapsulated DMR data frame + _peer_id = data[11:15] + elif _command == DMRA: # DMRAlias -- Talker Alias information + _peer_id = _data[4:8] + elif _command == RPTL: # RPTLogin -- a repeater wants to login + _peer_id = data[4:8] + elif _command == RPTK: # Repeater has answered our login challenge + _peer_id = data[4:8] + elif _command == RPTC: # Repeater is sending it's configuraiton OR disconnecting + if data[:5] == RPTCL: # Disconnect command + _peer_id = data[5:9] + else: + _peer_id = data[4:8] # Configure Command + elif _command == RPTO: # options + _peer_id = data[4:8] + elif _command == RPTP: # RPTPing -- peer is pinging us + _peer_id = data[7:11] + else: + return + + if _peer_id in self.peerTrack: + _dport = self.peerTrack[_peer_id]['dport'] + self.peerTrack[_peer_id]['sport'] = port + self.peerTrack[_peer_id]['shost'] = host + self.transport.write(data, ('127.0.0.1',_dport)) + self.peerTrack[_peer_id]['timer'].reset() + if self.debug: + print(data) + print(_dport) + return + else: + + if int_id(_peer_id) in self.blackList: + return + #for _dport in self.connTrack: + while True: + _dport = random.randint(1,(self.numPorts - 1)) + _dport = _dport + self.destPortStart + if not self.connTrack[_dport]: + break + self.connTrack[_dport] = _peer_id + self.peerTrack[_peer_id] = {} + self.peerTrack[_peer_id]['dport'] = _dport + self.peerTrack[_peer_id]['sport'] = port + self.peerTrack[_peer_id]['shost'] = host + self.peerTrack[_peer_id]['timer'] = ResettableTimer(self.timeout,self.reaper,[_peer_id]) + self.peerTrack[_peer_id]['timer'].start() + self.transport.write(data, (self.master,_dport)) + if self.debug: + print(data) + return + + +if __name__ == '__main__': + +#*** CONFIG HERE *** + + Master = "127.0.0.1" + ListenPort = 62031 + DestportStart = 54100 + DestPortEnd = 54102 + Timeout = 30 + Stats = True + Debug = True + BlackList = [1234567] + +#******************* + + + CONNTRACK = {} + + for port in range(DestportStart,DestPortEnd+1,1): + CONNTRACK[port] = False + + + reactor.listenUDP(ListenPort,Proxy(Master,ListenPort,CONNTRACK,BlackList,Timeout,Debug,DestportStart,DestPortEnd)) + + def loopingErrHandle(failure): + print('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error innowtimed loop.\n {}'.format(failure)) + reactor.stop() + + def stats(): + count = 0 + nowtime = time() + for port in CONNTRACK: + if CONNTRACK[port]: + count = count+1 + + totalPorts = DestPortEnd - DestportStart + freePorts = totalPorts - count + + print("{} ports out of {} in use ({} free)".format(count,totalPorts,freePorts)) + + + + if Stats == True: + stats_task = task.LoopingCall(stats) + statsa = stats_task.start(30) + statsa.addErrback(loopingErrHandle) + + reactor.run() + diff --git a/user_managment/app.py b/user_managment/app.py index 44cfa55..54cdaee 100644 --- a/user_managment/app.py +++ b/user_managment/app.py @@ -348,6 +348,7 @@ def create_app(): reset = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') public_list = db.Column(db.Boolean(), nullable=False, server_default='0') + proxy = db.Column(db.Boolean(), nullable=False, server_default='0') class BridgeList(db.Model): __tablename__ = 'bridge_list' @@ -1561,12 +1562,11 @@ def create_app(): return render_template('flask_user_layout.html', markup_content = Markup(content)) def get_peer_configs(_server_name): - mmdvm_pl = mmdvmPeer.query.filter_by(server=_server_name).all() - xlx_pl = xlxPeer.query.filter_by(server=_server_name).all() + mmdvm_pl = mmdvmPeer.query.filter_by(server=_server_name).filter_by(enabled=True).all() + xlx_pl = xlxPeer.query.filter_by(server=_server_name).filter_by(enabled=True).all() ## print(mmdvm_pl) peer_config_list = {} for i in mmdvm_pl: -## print(i) ## print(i.master_ip) peer_config_list.update({i.name: { 'MODE': 'PEER', @@ -1578,32 +1578,31 @@ def create_app(): 'MASTER_SOCKADDR': (gethostbyname(i.master_ip), i.master_port), 'MASTER_IP': i.master_ip, 'MASTER_PORT': i.master_port, - 'PASSPHRASE': bytes((i.passphrase), 'utf-8'), - 'CALLSIGN': bytes((i.callsign).ljust(8)[:8], 'utf-8'), + + 'PASSPHRASE': i.passphrase, + 'CALLSIGN': i.callsign, 'RADIO_ID': int(i.radio_id), #int(i.radio_id).to_bytes(4, 'big'), - 'RX_FREQ': bytes((i.rx_freq).ljust(9)[:9], 'utf-8'), - 'TX_FREQ': bytes((i.tx_freq).ljust(9)[:9], 'utf-8'), - 'TX_POWER': bytes((i.tx_power).rjust(2,'0'), 'utf-8'), - 'COLORCODE': bytes((i.color_code).rjust(2,'0'), 'utf-8'), - 'LATITUDE': bytes((i.latitude).ljust(8)[:8], 'utf-8'), - 'LONGITUDE': bytes((i.longitude).ljust(9)[:9], 'utf-8'), - 'HEIGHT': bytes((i.height).rjust(3,'0'), 'utf-8'), - 'LOCATION': bytes((i.location).ljust(20)[:20], 'utf-8'), - 'DESCRIPTION': bytes((i.description).ljust(19)[:19], 'utf-8'), - 'SLOTS': bytes((i.slots), 'utf-8'), - 'URL': bytes((i.url).ljust(124)[:124], 'utf-8'), - 'SOFTWARE_ID': bytes((i.software_id).ljust(40)[:40], 'utf-8'), - 'PACKAGE_ID': bytes((i.package_id).ljust(40)[:40], 'utf-8'), + 'RX_FREQ': i.rx_freq, + 'TX_FREQ': i.tx_freq, + 'TX_POWER': i.tx_power, + 'COLORCODE': i.color_code, + 'LATITUDE': i.latitude, + 'LONGITUDE': i.longitude, + 'HEIGHT': i.height, + 'LOCATION': i.location, + 'DESCRIPTION': i.description, + 'SLOTS': i.slots, + 'URL': i.url, 'GROUP_HANGTIME': i.group_hangtime, - 'OPTIONS': b''.join([b'Type=HBlink;', bytes(i.options, 'utf-8')]), + 'OPTIONS': i.options, 'USE_ACL': i.use_acl, 'SUB_ACL': i.sub_acl, 'TG1_ACL': i.tg1_acl, 'TG2_ACL': i.tg2_acl }}) - for i in xlx_pl: - peer_config_list.update({i: { - 'MODE': 'XLX', + for i in xlx_pl: + peer_config_list.update({i.name: { + 'MODE': 'XLXPEER', 'ENABLED': i.enabled, 'LOOSE': i.loose, 'SOCK_ADDR': (gethostbyname(i.ip), i.port), @@ -1612,31 +1611,31 @@ def create_app(): 'MASTER_SOCKADDR': (gethostbyname(i.master_ip), i.master_port), 'MASTER_IP': i.master_ip, 'MASTER_PORT': i.master_port, - 'PASSPHRASE': bytes((i.passphrase), 'utf-8'), - 'CALLSIGN': bytes((i.callsign).ljust(8)[:8], 'utf-8'), - 'RADIO_ID': int(i.radio_id), - 'RX_FREQ': bytes((i.rx_freq).ljust(9)[:9], 'utf-8'), - 'TX_FREQ': bytes((i.tx_freq).ljust(9)[:9], 'utf-8'), - 'TX_POWER': bytes((i.tx_power).rjust(2,'0'), 'utf-8'), - 'COLORCODE': bytes((i.color_code).rjust(2,'0'), 'utf-8'), - 'LATITUDE': bytes((i.latitude).ljust(8)[:8], 'utf-8'), - 'LONGITUDE': bytes((i.longitude).ljust(9)[:9], 'utf-8'), - 'HEIGHT': bytes((i.height).rjust(3,'0'), 'utf-8'), - 'LOCATION': bytes((i.location).ljust(20)[:20], 'utf-8'), - 'DESCRIPTION': bytes((i.description).ljust(19)[:19], 'utf-8'), - 'SLOTS': bytes((i.slots), 'utf-8'), - 'URL': bytes((i.url).ljust(124)[:124], 'utf-8'), - 'SOFTWARE_ID': bytes(('HBNet DMR').ljust(40)[:40], 'utf-8'), - 'PACKAGE_ID': bytes(('Dev').ljust(40)[:40], 'utf-8'), + + 'PASSPHRASE': i.passphrase, + 'CALLSIGN': i.callsign, + 'RADIO_ID': int(i.radio_id), #int(i.radio_id).to_bytes(4, 'big'), + 'RX_FREQ': i.rx_freq, + 'TX_FREQ': i.tx_freq, + 'TX_POWER': i.tx_power, + 'COLORCODE': i.color_code, + 'LATITUDE': i.latitude, + 'LONGITUDE': i.longitude, + 'HEIGHT': i.height, + 'LOCATION': i.location, + 'DESCRIPTION': i.description, + 'SLOTS': i.slots, + 'URL': i.url, + 'OPTIONS': i.options, 'GROUP_HANGTIME': i.group_hangtime, 'XLXMODULE': i.xlxmodule, - 'OPTIONS': b''.join([b'Type=HBlink;', bytes(i.options, 'utf-8')]), 'USE_ACL': i.use_acl, 'SUB_ACL': i.sub_acl, 'TG1_ACL': i.tg1_acl, 'TG2_ACL': i.tg2_acl }}) - print((peer_config_list)) +#### print('peers') +## print('----------------') return peer_config_list def get_burnlist(): @@ -1755,33 +1754,97 @@ def create_app(): def generate_rules(_name): # generate UNIT list + print('get rules') + print(_name) xlx_p = xlxPeer.query.filter_by(server=_name).all() mmdvm_p = mmdvmPeer.query.filter_by(server=_name).all() all_m = MasterList.query.filter_by(server=_name).all() all_o = OBP.query.filter_by(server=_name).all() all_p = ProxyList.query.filter_by(server=_name).all() + rules = BridgeRules.query.filter_by(server=_name).all() UNIT = [] BRIDGES = {} + disabled = {} for i in all_m: - if i.enable_unit == True: - UNIT.append(i.name) + if i.active == False: + disabled[i.name] = i.name + else: + if i.enable_unit == True: + UNIT.append(i.name) for i in all_p: - if i.enable_unit == True: - n_systems = i.internal_stop_port - i.internal_start_port - n_count = 0 - while n_count < n_systems: - UNIT.append(i.name + '-' + str(n_count)) - n_count = n_count + 1 + if i.active == False: + disabled[i.name] = i.name + else: + if i.enable_unit == True: + n_systems = i.internal_stop_port - i.internal_start_port + n_count = 0 + while n_count < n_systems: + UNIT.append(i.name + '-' + str(n_count)) + n_count = n_count + 1 for i in all_o: - if i.enable_unit == True: - UNIT.append(i.name) + if i.enabled == False: + disabled[i.name] = i.name + else: + if i.enable_unit == True: + UNIT.append(i.name) for i in xlx_p: - if i.enable_unit == True: - UNIT.append(i.name) + if i.enabled == False: + disabled[i.name] = i.name + else: + if i.enable_unit == True: + UNIT.append(i.name) for i in mmdvm_p: - if i.enable_unit == True: - UNIT.append(i.name) - print(UNIT) + if i.enabled == False: + disabled[i.name] = i.name + else: + if i.enable_unit == True: + UNIT.append(i.name) + temp_dict = {} + # populate dict with needed bridges + for r in rules: +## print(r.bridge_name) +## b = BridgeRules.query.filter_by(server=_name).filter_by(server=_name).all() +## for d in temp_dict.items(): +## if r.bridge_name == d[0]: +## print('update rule') +## if r.bridge_name != d[0]: +## print('add dict entry and rule') + temp_dict[r.bridge_name] = [] +## print(temp_dict) + BRIDGES = temp_dict.copy() + for r in temp_dict.items(): + b = BridgeRules.query.filter_by(bridge_name=r[0]).filter_by(server=_name).all() + for s in b: + try: + if s.system_name == disabled[s.system_name]: + pass + except: + if s.timeout == '': + timeout = 0 + else: + timeout = int(s.timeout) + if s.proxy == True: + p = ProxyList.query.filter_by(server=_name).filter_by(name=s.system_name).first() + print(p.external_port) + n_systems = p.internal_stop_port - p.internal_start_port + n_count = 0 + while n_count < n_systems: + BRIDGES[r[0]].append({'SYSTEM': s.system_name + '-' + str(n_count), 'TS': s.ts, 'TGID': s.tg, 'ACTIVE': s.active, 'TIMEOUT': timeout, 'TO_TYPE': s.to_type, 'ON': ast.literal_eval(str('[' + s.on + ']')), 'OFF': ast.literal_eval(str('[' + s.off + ']')), 'RESET': ast.literal_eval(str('[' + s.reset + ']'))}) + n_count = n_count + 1 + + else: + BRIDGES[r[0]].append({'SYSTEM': s.system_name, 'TS': s.ts, 'TGID': s.tg, 'ACTIVE': s.active, 'TIMEOUT': timeout, 'TO_TYPE': s.to_type, 'ON': ast.literal_eval(str('[' + s.on + ']')), 'OFF': ast.literal_eval(str('[' + s.off + ']')), 'RESET': ast.literal_eval(str('[' + s.reset + ']'))}) + +## for d in b: +## print(b.system_name) + +## if r.bridge_name == d[0]: +## print('update rule') +## if r.bridge_name != d[0]: +## print('add dict entry and rule') + +## print(r.tg) +## print(BRIDGES) return [UNIT, BRIDGES] @@ -1838,9 +1901,9 @@ def create_app(): ## print(_name) #s = ServerList.query.filter_by(name=_name).first() # print(s.name) - i = MasterList.query.filter_by(server=_name).all() - o = OBP.query.filter_by(server=_name).all() - p = ProxyList.query.filter_by(server=_name).all() + i = MasterList.query.filter_by(server=_name).filter_by(active=True).all() + o = OBP.query.filter_by(server=_name).filter_by(enabled=True).all() + p = ProxyList.query.filter_by(server=_name).filter_by(active=True).all() print('get masters') master_config_list = {} ## master_config_list['SYSTEMS'] = {} @@ -1856,7 +1919,7 @@ def create_app(): 'MAX_PEERS': m.max_peers, 'IP': m.ip, 'PORT': m.port, - 'PASSPHRASE': bytes(m.passphrase, 'utf-8'), + 'PASSPHRASE': m.passphrase, #bytes(m.passphrase, 'utf-8'), 'GROUP_HANGTIME': m.group_hang_time, 'USE_ACL': m.use_acl, 'REG_ACL': m.reg_acl, @@ -1873,7 +1936,7 @@ def create_app(): 'NETWORK_ID': obp.network_id, #int(obp.network_id).to_bytes(4, 'big'), 'IP': gethostbyname(obp.ip), 'PORT': obp.port, - 'PASSPHRASE': bytes(obp.passphrase.ljust(20,'\x00')[:20], 'utf-8'), + 'PASSPHRASE': obp.passphrase, #bytes(obp.passphrase.ljust(20,'\x00')[:20], 'utf-8'), 'TARGET_SOCK': (obp.target_ip, obp.target_port), 'TARGET_IP': gethostbyname(obp.target_ip), 'TARGET_PORT': obp.target_port, @@ -1891,7 +1954,7 @@ def create_app(): 'STATIC_APRS_POSITION_ENABLED': pr.static_positions, 'USE_USER_MAN': pr.enable_um, 'REPEAT': pr.repeat, - 'PASSPHRASE': bytes(pr.passphrase, 'utf-8'), + 'PASSPHRASE': pr.passphrase, #bytes(pr.passphrase, 'utf-8'), 'EXTERNAL_PORT': pr.external_port, 'INTERNAL_PORT_START': pr.internal_start_port, 'INTERNAL_PORT_STOP': pr.internal_stop_port, @@ -1908,6 +1971,13 @@ def create_app(): return master_config_list def add_system_rule(_bridge_name, _system_name, _ts, _tg, _active, _timeout, _to_type, _on, _off, _reset, _server, _public_list): + proxy = ProxyList.query.filter_by(server=_server).filter_by(name=_system_name).first() + is_proxy = False + try: + if _system_name == proxy.name: + is_proxy = True + except: + pass add_system = BridgeRules( bridge_name = _bridge_name, system_name = _system_name, @@ -1920,7 +1990,8 @@ def create_app(): off = _off, reset = _reset, server = _server, - public_list = _public_list + public_list = _public_list, + proxy = is_proxy ) db.session.add(add_system) db.session.commit() @@ -4525,7 +4596,7 @@ def create_app(): return render_template('flask_user_layout.html', markup_content = Markup(content)) - @app.route('/auth', methods=['POST']) + @app.route('/svr', methods=['POST']) def auth(): hblink_req = request.json print((hblink_req)) @@ -4596,6 +4667,7 @@ def create_app(): if hblink_req['get_config']: ## try: +## print(get_peer_configs(hblink_req['get_config'])) response = jsonify( config=server_get(hblink_req['get_config']), peers=get_peer_configs(hblink_req['get_config']),