Updates to tidy up handling of low-level TG filter.

Also, remove the obsolete protocol versions 2 and 3

and some further tidying up.

Squashed commit of the following:

commit 7b13b9f046
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 19:01:33 2023 +0000

    SERVER_ID is bytes!

commit cee3bc76fb
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 18:50:06 2023 +0000

    frog

commit 82432b9c2c
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 18:49:53 2023 +0000

    fred

commit 6601573c7f
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 18:39:08 2023 +0000

    Stringly

commit 28fa37f828
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 18:30:37 2023 +0000

    self

commit 3e6d28d4dd
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 18:23:42 2023 +0000

    Fix trace

commit a15901dc79
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 18:21:30 2023 +0000

    Tweak config file used in install script

commit 654ec135ca
Merge: f75ff26 d4e3922
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 17:48:22 2023 +0000

    Merge branch 'master' into testing

commit f75ff26cfa
Merge: c0b5216 48339d3
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 17:46:07 2023 +0000

    Merge branch 'master' into testing

commit c0b5216e5a
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 11:04:45 2023 +0000

    more config work

commit c79ce0551d
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 00:54:56 2023 +0000

    ib

commit 294a09c8f1
Author: Simon <simon@gb7fr.org.uk>
Date:   Sun Jan 29 00:50:36 2023 +0000

    Enable minimal config and tidy up global ACL

commit d1dc58d46f
Author: Simon <simon@gb7fr.org.uk>
Date:   Sat Jan 28 23:12:41 2023 +0000

    Deprecate protocol versions 2 and 3
api
Simon 3 years ago
parent d4e3922dc2
commit 2517d3ac21

@ -0,0 +1,42 @@
#This empty config file will use defaults for everything apart from OBP and HBP config
#This is usually a sensible choice.
[GLOBAL]
SERVER_ID: 0000
[REPORTS]
[LOGGER]
[ALIASES]
[ALLSTAR]
[SYSTEM]
MODE: MASTER
ENABLED: True
REPEAT: True
MAX_PEERS: 1
EXPORT_AMBE: False
IP: 127.0.0.1
PORT: 54000
PASSPHRASE:
GROUP_HANGTIME: 5
USE_ACL: True
REG_ACL: DENY:1
SUB_ACL: DENY:1
TGID_TS1_ACL: PERMIT:ALL
TGID_TS2_ACL: PERMIT:ALL
DEFAULT_UA_TIMER: 60
SINGLE_MODE: True
VOICE_IDENT: True
TS1_STATIC:
TS2_STATIC:
DEFAULT_REFLECTOR: 0
ANNOUNCEMENT_LANGUAGE: en_GB
GENERATOR: 100
ALLOW_UNREG_ID: False
PROXY_CONTROL: True
OVERRIDE_IDENT_TG:

@ -9,7 +9,7 @@ TGID_TS1_ACL: PERMIT:ALL
TGID_TS2_ACL: PERMIT:ALL
GEN_STAT_BRIDGES: True
ALLOW_NULL_PASSPHRASE: True
ANNOUNCEMENT_LANGUAGES: en_GB,en_US,es_ES,fr_FR,de_DE,dk_DK,it_IT,no_NO,pl_PL,se_SE,pt_PT,cy_GB,el_GR,CW
ANNOUNCEMENT_LANGUAGES:
SERVER_ID: 0000
DATA_GATEWAY: False
VALIDATE_SERVER_IDS: True

@ -2536,7 +2536,7 @@ if __name__ == '__main__':
if cli_args.LOG_LEVEL:
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
logger = log.config_logging(CONFIG['LOGGER'])
logger.info('\n\nCopyright (c) 2020, 2021, 2022 Simon G7RZU simon@gb7fr.org.uk')
logger.info('\n\nCopyright (c) 2020, 2021, 2022, 2023 Simon G7RZU simon@gb7fr.org.uk')
logger.info('Copyright (c) 2013, 2014, 2015, 2016, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n')
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')

@ -182,7 +182,7 @@ def build_config(_config_file):
'TGID_URL': config.get(section, 'TGID_URL', fallback='https://freedmr-lh.gb7fr.org.uk/json/talkgroup_ids.json'),
'STALE_TIME': config.getint(section, 'STALE_DAYS', fallback=1) * 86400,
'SUB_MAP_FILE': config.get(section, 'SUB_MAP_FILE', fallback='sub_map.pkl'),
'LOCAL_SUBSCRIBER_FILE': config.get(section, 'LOCAL_SUBSCRIBER_FILE', fallback=''),
'LOCAL_SUBSCRIBER_FILE': config.get(section, 'LOCAL_SUBSCRIBER_FILE', fallback='local_subscribers.json'),
'SERVER_ID_URL': config.get(section, 'SERVER_ID_URL', fallback='https://freedmr-lh.gb7fr.org.uk/json/server_ids.tsv'),
'SERVER_ID_FILE': config.get(section, 'SERVER_ID_FILE', fallback='server_ids.tsv'),
'CHECKSUM_URL': config.get(section, 'CHECKSUM_URL', fallback='https://freedmr-lh.gb7fr.org.uk/file_checksums.json'),
@ -304,52 +304,55 @@ def build_config(_config_file):
elif config.get(section, 'MODE') == 'MASTER':
CONFIG['SYSTEMS'].update({section: {
'MODE': config.get(section, 'MODE'),
'ENABLED': config.getboolean(section, 'ENABLED'),
'REPEAT': config.getboolean(section, 'REPEAT'),
'MAX_PEERS': config.getint(section, 'MAX_PEERS'),
'IP': config.get(section, 'IP'),
'PORT': config.getint(section, 'PORT'),
'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE'), 'utf-8'),
'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'),
'USE_ACL': config.getboolean(section, 'USE_ACL'),
'REG_ACL': config.get(section, 'REG_ACL'),
'SUB_ACL': config.get(section, 'SUB_ACL'),
'TG1_ACL': config.get(section, 'TGID_TS1_ACL'),
'TG2_ACL': config.get(section, 'TGID_TS2_ACL'),
'DEFAULT_UA_TIMER': config.getint(section, 'DEFAULT_UA_TIMER'),
'SINGLE_MODE': config.getboolean(section, 'SINGLE_MODE'),
'VOICE_IDENT': config.getboolean(section, 'VOICE_IDENT'),
'TS1_STATIC': config.get(section,'TS1_STATIC'),
'TS2_STATIC': config.get(section,'TS2_STATIC'),
'ENABLED': config.getboolean(section, 'ENABLED', fallback=True ),
'REPEAT': config.getboolean(section, 'REPEAT', fallback=True),
'MAX_PEERS': config.getint(section, 'MAX_PEERS', fallback=1),
'IP': config.get(section, 'IP', fallback='127.0.0.1'),
'PORT': config.getint(section, 'PORT', fallback=54000),
'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE', fallback=''), 'utf-8'),
'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME',fallback=5),
'USE_ACL': config.getboolean(section, 'USE_ACL', fallback=False),
'REG_ACL': config.get(section, 'REG_ACL', fallback=''),
'SUB_ACL': config.get(section, 'SUB_ACL', fallback=''),
'TG1_ACL': config.get(section, 'TGID_TS1_ACL', fallback=''),
'TG2_ACL': config.get(section, 'TGID_TS2_ACL', fallback=''),
'DEFAULT_UA_TIMER': config.getint(section, 'DEFAULT_UA_TIMER', fallback=10),
'SINGLE_MODE': config.getboolean(section, 'SINGLE_MODE', fallback=True),
'VOICE_IDENT': config.getboolean(section, 'VOICE_IDENT', fallback=True),
'TS1_STATIC': config.get(section,'TS1_STATIC', fallback=''),
'TS2_STATIC': config.get(section,'TS2_STATIC', fallback=''),
'DEFAULT_REFLECTOR': config.getint(section, 'DEFAULT_REFLECTOR'),
'GENERATOR': config.getint(section, 'GENERATOR'),
'ANNOUNCEMENT_LANGUAGE': config.get(section, 'ANNOUNCEMENT_LANGUAGE'),
'ALLOW_UNREG_ID': config.getboolean(section,'ALLOW_UNREG_ID'),
'PROXY_CONTROL' : config.getboolean(section,'PROXY_CONTROL'),
'OVERRIDE_IDENT_TG': config.get(section, 'OVERRIDE_IDENT_TG')
'GENERATOR': config.getint(section, 'GENERATOR', fallback=100),
'ANNOUNCEMENT_LANGUAGE': config.get(section, 'ANNOUNCEMENT_LANGUAGE', fallback='en_GB'),
'ALLOW_UNREG_ID': config.getboolean(section,'ALLOW_UNREG_ID', fallback=False),
'PROXY_CONTROL' : config.getboolean(section,'PROXY_CONTROL', fallback=True),
'OVERRIDE_IDENT_TG': config.get(section, 'OVERRIDE_IDENT_TG', fallback=False)
}})
CONFIG['SYSTEMS'][section].update({'PEERS': {}})
elif config.get(section, 'MODE') == 'OPENBRIDGE':
CONFIG['SYSTEMS'].update({section: {
'MODE': config.get(section, 'MODE'),
'ENABLED': config.getboolean(section, 'ENABLED'),
'ENABLED': config.getboolean(section, 'ENABLED', fallback=True),
'NETWORK_ID': config.getint(section, 'NETWORK_ID').to_bytes(4, 'big'),
#'OVERRIDE_SERVER_ID': config.getint(section, 'OVERRIDE_SERVER_ID').to_bytes(4, 'big'),
'IP': config.get(section, 'IP'),
'IP': config.get(section, 'IP', fallback=''),
'PORT': config.getint(section, 'PORT'),
'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE').ljust(20,'\x00')[:20], 'utf-8'),
#'TARGET_SOCK': (gethostbyname(config.get(section, 'TARGET_IP')), config.getint(section, 'TARGET_PORT')),
'TARGET_IP': config.get(section, 'TARGET_IP'),
'TARGET_PORT': config.getint(section, 'TARGET_PORT'),
'USE_ACL': config.getboolean(section, 'USE_ACL'),
'SUB_ACL': config.get(section, 'SUB_ACL'),
'TG1_ACL': config.get(section, 'TGID_ACL'),
'USE_ACL': config.getboolean(section, 'USE_ACL', fallback=False),
'SUB_ACL': config.get(section, 'SUB_ACL', fallback=''),
'TG1_ACL': config.get(section, 'TGID_ACL', fallback=''),
'TG2_ACL': 'PERMIT:ALL',
'RELAX_CHECKS': config.getboolean(section, 'RELAX_CHECKS'),
'ENHANCED_OBP': config.getboolean(section, 'ENHANCED_OBP'),
'VER' : config.getint(section, 'PROTO_VER')
'RELAX_CHECKS': config.getboolean(section, 'RELAX_CHECKS', fallback=True),
'ENHANCED_OBP': config.getboolean(section, 'ENHANCED_OBP',fallback=True),
'VER' : config.getint(section, 'PROTO_VER', fallback=5)
}})
if CONFIG['SYSTEMS'][section]['VER'] in (0,2,3) or CONFIG['SYSTEMS'][section]['VER'] > 5:
sys.exit('(%s) PROTO_VER not valid',section)
try:

@ -70,66 +70,32 @@ chown 54000:54000 /etc/freedmr/json &&
echo Install /etc/freedmr/freedmr.cfg ...
cat << EOF > /etc/freedmr/freedmr.cfg
#This empty config file will use defaults for everything apart from OBP and HBP config
#This is usually a sensible choice.
#I have moved to a config like this to encourage servers to use the accepted defaults
#unless you really know what you are doing.
[GLOBAL]
PATH: ./
PING_TIME: 10
MAX_MISSED: 3
USE_ACL: True
REG_ACL: DENY:0-100000
SUB_ACL: DENY:0-100000
TGID_TS1_ACL: PERMIT:ALL
TGID_TS2_ACL: PERMIT:ALL
GEN_STAT_BRIDGES: True
ALLOW_NULL_PASSPHRASE: True
ANNOUNCEMENT_LANGUAGES:
#If you join the FreeDMR network, you need to add your ServerID Here.
SERVER_ID: 0
DATA_GATEWAY: False
VALIDATE_SERVER_IDS: True
[REPORTS]
REPORT: True
REPORT_INTERVAL: 60
REPORT_PORT: 4321
REPORT_CLIENTS: *
[LOGGER]
LOG_FILE: /dev/null
LOG_HANDLERS: console-timed
LOG_LEVEL: INFO
LOG_NAME: FreeDMR
[ALIASES]
TRY_DOWNLOAD: True
PATH: ./json/
PEER_FILE: peer_ids.json
SUBSCRIBER_FILE: subscriber_ids.json
TGID_FILE: talkgroup_ids.json
PEER_URL: https://freedmr-lh.gb7fr.org.uk/json/peer_ids.json
SUBSCRIBER_URL: https://freedmr-lh.gb7fr.org.uk/json/subscriber_ids.json
TGID_URL: https://freedmr-lh.gb7fr.org.uk/json/talkgroup_ids.json
LOCAL_SUBSCRIBER_FILE: local_subcriber_ids.json
STALE_DAYS: 1
SUB_MAP_FILE: sub_map.pkl
SERVER_ID_URL: https://freedmr-lh.gb7fr.org.uk/json/server_ids.tsv
SERVER_ID_FILE: server_ids.tsv
CHECKSUM_URL: https://freedmr-lh.gb7fr.org.uk/file_checksums.json
CHECKSUM_FILE: file_checksums.json
#Control server shared allstar instance via dial / AMI
[ALLSTAR]
ENABLED: false
USER:admin
PASS: password
SERVER: asl.example.com
PORT: 5038
NODE: 11111
#This is an example OpenBridgeProtocol (OBP) or FreeBridgeProtocol (FBP) configuration
#If you joing FreeDMR, you will be given a config like this to paste in
[OBP-TEST]
MODE: OPENBRIDGE
ENABLED: False
IP:
PORT: 62044
#The ID which you expect to see sent from the other end of the link.
NETWORK_ID: 1
PASSPHRASE: mypass
TARGET_IP:
@ -137,11 +103,17 @@ TARGET_PORT: 62044
USE_ACL: True
SUB_ACL: DENY:1
TGID_ACL: PERMIT:ALL
#Should always be true if using docker.
RELAX_CHECKS: True
#True for FBP, False for OBP
ENHANCED_OBP: True
PROTO_VER: 2
#PROTO_VER should be 5 for FreeDMR servers using FBP
#1 for other servers using OBP
PROTO_VER: 5
#This defines parameters for repeater/hotspot connections
#via HomeBrewProtocol (HBP)
#I don't recommend changing most of this unless you know what you are doing
[SYSTEM]
MODE: MASTER
ENABLED: True
@ -169,6 +141,7 @@ ALLOW_UNREG_ID: False
PROXY_CONTROL: True
OVERRIDE_IDENT_TG:
#Echo (Loro / Parrot) server
[ECHO]
MODE: PEER
ENABLED: True

@ -201,20 +201,10 @@ class OPENBRIDGE(DatagramProtocol):
self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT']))
elif 'VER' in self._config and self._config['VER'] == 3:
_packet = b''.join([DMRF,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:]])
_h = blake2b(key=self._config['PASSPHRASE'], digest_size=16)
_h.update(_packet)
_hash = _h.digest()
_packet = b''.join([_packet,time_ns().to_bytes(8,'big'), _hops, _hash])
self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT']))
logger.error('(%s) protocol version 3 no longer supported',self._system)
elif 'VER' in self._config and self._config['VER'] == 2:
_packet = b''.join([DMRF,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:], time_ns().to_bytes(8,'big')])
_h = blake2b(key=self._config['PASSPHRASE'], digest_size=16)
_h.update(_packet)
_hash = _h.digest()
_packet = b''.join([_packet,_hops, _hash])
self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT']))
logger.error('(%s) protocol version 2 no longer supported',self._system)
# KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
#logger.debug('(%s) TX Packet to OpenBridge %s:%s -- %s %s', self._system, self._config['TARGET_IP'], self._config['TARGET_PORT'], _packet, _hash)
else:
@ -486,122 +476,39 @@ class OPENBRIDGE(DatagramProtocol):
self.send_bcsq(_dst_id,_stream_id)
return
#Low-level TG filtering
if _call_type != 'unit':
_int_dst_id = int_id(_dst_id)
if _int_dst_id <= 79 or (_int_dst_id >= 9990 and _int_dst_id <= 9999) or _int_dst_id == 900999:
if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER', self._system, int_id(_stream_id), _int_dst_id)
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
# ACL Processing
if self._CONFIG['GLOBAL']['USE_ACL']:
if not acl_check(_rf_src, self._CONFIG['GLOBAL']['SUB_ACL']):
if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY GLOBAL TS1 ACL', self._system, int_id(_stream_id), int_id(_rf_src))
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
if _slot == 1 and not acl_check(_dst_id, self._CONFIG['GLOBAL']['TG1_ACL']):
if _int_dst_id <= 79:
if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY GLOBAL TS1 ACL', self._system, int_id(_stream_id), int_id(_dst_id))
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER (local to repeater)', self._system, int_id(_stream_id), _int_dst_id)
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
if self._config['USE_ACL']:
if not acl_check(_rf_src, self._config['SUB_ACL']):
if (_int_dst_id >= 9990 and _int_dst_id <= 9999) or _int_dst_id == 900999:
if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY SYSTEM ACL', self._system, int_id(_stream_id), int_id(_rf_src))
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER (local to server)', self._system, int_id(_stream_id), _int_dst_id)
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
if not acl_check(_dst_id, self._config['TG1_ACL']):
if (_int_dst_id >= 92 and _int_dst_id <= 199) and int(str(int.from_bytes(_source_server,'big'))[:4]) != int(str(int.from_bytes(self._CONFIG['GLOBAL']['SERVER_ID'],'big'))[:4]):
if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s ON TGID %s BY SYSTEM ACL', self._system, int_id(_stream_id), int_id(_dst_id))
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER (local to server main ID)', self._system, int_id(_stream_id), _int_dst_id)
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
_data = b''.join([DMRD,_data[4:]])
_hops = _inthops.to_bytes(1,'big')
# Userland actions -- typically this is the function you subclass for an application
self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops,_source_server,_ber,_rssi,_source_rptr)
#Silently treat a DMRD packet like a keepalive - this is because it's traffic and the
#Other end may not have enabled ENAHNCED_OBP
self._config['_bcka'] = time()
else:
h,p = _sockaddr
logger.warning('(%s) FreeBridge HMAC failed, packet discarded - OPCODE: %s DATA: %s HMAC LENGTH: %s HMAC: %s SRC IP: %s SRC PORT: %s', self._system, _packet[:4], repr(_packet[:69]), len(_packet[69:]), repr(_packet[61:]),h,p)
elif _packet[:4] == DMRF:
_data = _packet[:53]
_timestamp = _packet[53:60]
_hops = _packet[61]
_hash = _packet[62:]
#_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest()
_h = blake2b(key=self._config['PASSPHRASE'], digest_size=16)
if 'VER' in self._config and self._config['VER'] > 2:
_h.update(_packet[:53])
elif 'VER' in self._config and self._config['VER'] == 2:
_h.update(_packet[:61])
_ckhs = _h.digest()
if compare_digest(_hash, _ckhs) and (_sockaddr == self._config['TARGET_SOCK'] or self._config['RELAX_CHECKS']):
_peer_id = _data[11:15]
if self._config['NETWORK_ID'] != _peer_id:
if _stream_id not in self._laststrid:
logger.error('(%s) OpenBridge packet discarded because NETWORK_ID: %s Does not match sent Peer ID: %s', self._system, int_id(self._config['NETWORK_ID']), int_id(_peer_id))
self._laststrid.append(_stream_id)
return
_seq = _data[4]
_rf_src = _data[5:8]
_dst_id = _data[8:11]
_int_dst_id = int_id(_dst_id)
_bits = _data[15]
_slot = 2 if (_bits & 0x80) else 1
#_call_type = 'unit' if (_bits & 0x40) else 'group'
if _bits & 0x40:
_call_type = 'unit'
elif (_bits & 0x23) == 0x23:
_call_type = 'vcsbk'
else:
_call_type = 'group'
_frame_type = (_bits & 0x30) >> 4
_dtype_vseq = (_bits & 0xF) # data, 1=voice header, 2=voice terminator; voice, 0=burst A ... 5=burst F
_stream_id = _data[16:20]
#logger.debug('(%s) DMRD - Seqence: %s, RF Source: %s, Destination ID: %s', self._system, int_id(_seq), int_id(_rf_src), int_id(_dst_id))
#Don't do anything if we are STUNned
if 'STUN' in self._CONFIG:
if (_int_dst_id >= 80 and _int_dst_id <= 89) or (_int_dst_id >= 800 and _int_dst_id <= 899) and int(str(int.from_bytes(_source_server,'big'))[:3]) != int(str(int.from_bytes(self._CONFIG['GLOBAL']['SERVER_ID'],'big'))[:3]):
if _stream_id not in self._laststrid:
logger.warning('(%s) Bridge STUNned, discarding', self._system)
self._laststrid.append(_stream_id)
return
#Increment max hops
_inthops = _hops +1
if _inthops > 10:
logger.warning('(%s) MAX HOPS exceed, dropping. Hops: %s, DST: %s', self._system, _inthops, _int_dst_id)
self.send_bcsq(_dst_id,_stream_id)
return
#Low-level TG filtering
if _call_type != 'unit':
_int_dst_id = int_id(_dst_id)
if _int_dst_id <= 79 or (_int_dst_id >= 9990 and _int_dst_id <= 9999) or _int_dst_id == 900999:
if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER', self._system, int_id(_stream_id), _int_dst_id)
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER (local to MCC)', self._system, int_id(_stream_id), _int_dst_id)
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
# ACL Processing
if self._CONFIG['GLOBAL']['USE_ACL']:
@ -630,23 +537,22 @@ class OPENBRIDGE(DatagramProtocol):
self.send_bcsq(_dst_id,_stream_id)
self._laststrid.append(_stream_id)
return
#Remove timestamp from data. For now dmrd_received does not expect it
#Leaving it in screws up the AMBE data
#_data = b''.join([_data[:5],_data[12:]])
_data = b''.join([DMRD,_data[4:]])
_hops = _inthops.to_bytes(1,'big')
# Userland actions -- typically this is the function you subclass for an application
self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops)
self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops,_source_server,_ber,_rssi,_source_rptr)
#Silently treat a DMRD packet like a keepalive - this is because it's traffic and the
#Other end may not have enabled ENAHNCED_OBP
self._config['_bcka'] = time()
else:
h,p = _sockaddr
logger.warning('(%s) FreeBridge HMAC failed, packet discarded - OPCODE: %s DATA: %s HMAC LENGTH: %s HMAC: %s SRC IP: %s SRC PORT: %s', self._system, _packet[:4], repr(_packet[:61]), len(_packet[61:]), repr(_packet[61:]),h,p)
logger.warning('(%s) FreeBridge HMAC failed, packet discarded - OPCODE: %s DATA: %s HMAC LENGTH: %s HMAC: %s SRC IP: %s SRC PORT: %s', self._system, _packet[:4], repr(_packet[:69]), len(_packet[69:]), repr(_packet[61:]),h,p)
elif _packet[:4] == DMRF:
logger.error('(%s) Protocol versions 2 and 3 no longer supported',self._system)
if self._config['ENHANCED_OBP']:
if _packet[:2] == BC: # Bridge Control packet (Extended OBP)
@ -703,7 +609,9 @@ class OPENBRIDGE(DatagramProtocol):
if compare_digest(_hash, _ckhs):
logger.trace('(%s) *ProtoControl* BCVE Version received, Ver: %s',self._system,_ver)
if _ver > self._config['VER']:
if _ver == 2 or _ver == 3 or _ver > 5:
logger.info('(%s) *ProtoControl* BCVE Version not supported, Ver: %s',self._system,_ver)
elif _ver > self._config['VER']:
logger.info('(%s) *ProtoControl* BCVE Version upgrade, Ver: %s',self._system,_ver)
self._config['VER'] = _ver
elif _ver == self._config['VER']:
@ -927,7 +835,6 @@ class HBSYSTEM(DatagramProtocol):
# Extract the command, which is various length, all but one 4 significant characters -- RPTCL
_command = _data[:4]
if _command == DMRD: # DMRData -- encapsulated DMR data frame
_peer_id = _data[11:15]
if _peer_id in self._peers \

Loading…
Cancel
Save

Powered by TurnKey Linux.