Mostly kinda works now

This commit is contained in:
n0mjs710 2019-01-04 15:32:13 -06:00
parent 2860ec6847
commit 77d19f65ed
11 changed files with 55 additions and 122518 deletions

2
.gitignore vendored
View File

@ -93,3 +93,5 @@ hblink.cfg
*.config *.config
*.bak *.bak
rules.py rules.py
subscriber_ids.csv
peer_ids.csv

View File

@ -46,7 +46,7 @@ from twisted.internet import reactor, task
# Things we import from the main hblink module # Things we import from the main hblink module
from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, config_reports, mk_aliases from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, config_reports, mk_aliases
from dmr_utils.utils import hex_str_3, int_id, get_alias from dmr_utils.utils import bytes_3, int_id, get_alias
from dmr_utils import decode, bptc, const from dmr_utils import decode, bptc, const
import hb_config import hb_config
import hb_log import hb_log

View File

@ -43,7 +43,7 @@ from twisted.internet import reactor, task
# Things we import from the main hblink module # Things we import from the main hblink module
from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases
from dmr_utils3.utils import hex_str_3, int_id, get_alias from dmr_utils3.utils import bytes_3, int_id, get_alias
from dmr_utils3 import decode, bptc, const from dmr_utils3 import decode, bptc, const
import config import config
import log import log
@ -107,11 +107,11 @@ def make_bridges(_hb_confbridge_bridges):
if _system['SYSTEM'] not in CONFIG['SYSTEMS']: if _system['SYSTEM'] not in CONFIG['SYSTEMS']:
sys.exit('ERROR: Conference bridges found for system not configured main configuration') sys.exit('ERROR: Conference bridges found for system not configured main configuration')
_system['TGID'] = hex_str_3(_system['TGID']) _system['TGID'] = bytes_3(_system['TGID'])
for i, e in enumerate(_system['ON']): for i, e in enumerate(_system['ON']):
_system['ON'][i] = hex_str_3(_system['ON'][i]) _system['ON'][i] = bytes_3(_system['ON'][i])
for i, e in enumerate(_system['OFF']): for i, e in enumerate(_system['OFF']):
_system['OFF'][i] = hex_str_3(_system['OFF'][i]) _system['OFF'][i] = bytes_3(_system['OFF'][i])
_system['TIMEOUT'] = _system['TIMEOUT']*60 _system['TIMEOUT'] = _system['TIMEOUT']*60
if _system['ACTIVE'] == True: if _system['ACTIVE'] == True:
_system['TIMER'] = time() + _system['TIMEOUT'] _system['TIMER'] = time() + _system['TIMEOUT']
@ -151,7 +151,7 @@ def rule_timer_loop():
logger.debug('Conference Bridge NO ACTION: System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID'])) logger.debug('Conference Bridge NO ACTION: System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
report_server.send_clients('bridge updated') report_server.send_clients(b'bridge updated')
# run this every 10 seconds to trim orphaned stream ids # run this every 10 seconds to trim orphaned stream ids
@ -169,7 +169,7 @@ def stream_trimmer_loop():
logger.info('(%s) *TIME OUT* RX STREAM ID: %s SUB: %s TGID %s, TS %s, Duration: %s', \ logger.info('(%s) *TIME OUT* RX STREAM ID: %s SUB: %s TGID %s, TS %s, Duration: %s', \
system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_RFS']), int_id(_slot['RX_TGID']), slot, _slot['RX_TIME'] - _slot['RX_START']) system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_RFS']), int_id(_slot['RX_TGID']), slot, _slot['RX_TIME'] - _slot['RX_START'])
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_PEER']), int_id(_slot['RX_RFS']), slot, int_id(_slot['RX_TGID']), _slot['RX_TIME'] - _slot['RX_START'])) systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_PEER']), int_id(_slot['RX_RFS']), slot, int_id(_slot['RX_TGID']), _slot['RX_TIME'] - _slot['RX_START']).encode(encoding='utf-8', errors='ignore'))
for slot in range(1,3): for slot in range(1,3):
_slot = systems[system].STATUS[slot] _slot = systems[system].STATUS[slot]
@ -178,7 +178,7 @@ def stream_trimmer_loop():
logger.info('(%s) *TIME OUT* TX STREAM ID: %s SUB: %s TGID %s, TS %s, Duration: %s', \ logger.info('(%s) *TIME OUT* TX STREAM ID: %s SUB: %s TGID %s, TS %s, Duration: %s', \
system, int_id(_slot['TX_STREAM_ID']), int_id(_slot['TX_RFS']), int_id(_slot['TX_TGID']), slot, _slot['TX_TIME'] - _slot['TX_START']) system, int_id(_slot['TX_STREAM_ID']), int_id(_slot['TX_RFS']), int_id(_slot['TX_TGID']), slot, _slot['TX_TIME'] - _slot['TX_START'])
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[system]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['TX_STREAM_ID']), int_id(_slot['TX_PEER']), int_id(_slot['TX_RFS']), slot, int_id(_slot['TX_TGID']), _slot['TX_TIME'] - _slot['TX_START'])) systems[system]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['TX_STREAM_ID']), int_id(_slot['TX_PEER']), int_id(_slot['TX_RFS']), slot, int_id(_slot['TX_TGID']), _slot['TX_TIME'] - _slot['TX_START']).encode(encoding='utf-8', errors='ignore'))
# OBP systems # OBP systems
# We can't delete items from a dicationry that's being iterated, so we have to make a temporarly list of entrys to remove later # We can't delete items from a dicationry that's being iterated, so we have to make a temporarly list of entrys to remove later
@ -194,7 +194,7 @@ def stream_trimmer_loop():
logger.info('(%s) *TIME OUT* STREAM ID: %s SUB: %s PEER: %s TGID: %s TS 1 Duration: %s', \ logger.info('(%s) *TIME OUT* STREAM ID: %s SUB: %s PEER: %s TGID: %s TS 1 Duration: %s', \
system, int_id(stream_id), get_alias(int_id(_system['RFS']), subscriber_ids), get_alias(int_id(_config['NETWORK_ID']), peer_ids), get_alias(int_id(_system['TGID']), talkgroup_ids), _system['LAST'] - _system['START']) system, int_id(stream_id), get_alias(int_id(_system['RFS']), subscriber_ids), get_alias(int_id(_config['NETWORK_ID']), peer_ids), get_alias(int_id(_system['TGID']), talkgroup_ids), _system['LAST'] - _system['START'])
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(stream_id), int_id(_config['NETWORK_ID']), int_id(_system['RFS']), 1, int_id(_system['TGID']), _system['LAST'] - _system['START'])) systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(stream_id), int_id(_config['NETWORK_ID']), int_id(_system['RFS']), 1, int_id(_system['TGID']), _system['LAST'] - _system['START']).encode(encoding='utf-8', errors='ignore'))
removed = systems[system].STATUS.pop(stream_id) removed = systems[system].STATUS.pop(stream_id)
else: else:
logger.error('(%s) Attemped to remove OpenBridge Stream ID %s not in the Stream ID list: %s', system, int_id(stream_id), [id for id in systems[system].STATUS]) logger.error('(%s) Attemped to remove OpenBridge Stream ID %s not in the Stream ID list: %s', system, int_id(stream_id), [id for id in systems[system].STATUS])
@ -236,7 +236,7 @@ class routerOBP(OPENBRIDGE):
logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \ logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot) self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id))) self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore'))
self.STATUS[_stream_id]['LAST'] = pkt_time self.STATUS[_stream_id]['LAST'] = pkt_time
@ -283,7 +283,7 @@ class routerOBP(OPENBRIDGE):
_tmp_bits = _bits & ~(1 << 7) _tmp_bits = _bits & ~(1 << 7)
# Assemble transmit HBP packet header # Assemble transmit HBP packet header
_tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + chr(_tmp_bits) + _data[16:20] _tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + _tmp_bits.to_bytes(1, 'big') + _data[16:20]
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT # MUST RE-WRITE DESTINATION TGID IF DIFFERENT
@ -350,7 +350,7 @@ class routerOBP(OPENBRIDGE):
logger.debug('(%s) Generating TX FULL and EMB LCs for HomeBrew destination: System: %s, TS: %s, TGID: %s', self._system, _target['SYSTEM'], _target['TS'], int_id(_target['TGID'])) logger.debug('(%s) Generating TX FULL and EMB LCs for HomeBrew destination: System: %s, TS: %s, TGID: %s', self._system, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
logger.info('(%s) Conference Bridge: %s, Call Bridged to HBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID'])) logger.info('(%s) Conference Bridge: %s, Call Bridged to HBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']))) systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID'])).encode(encoding='utf-8', errors='ignore'))
# Set other values for the contention handler to test next time there is a frame to forward # Set other values for the contention handler to test next time there is a frame to forward
_target_status[_target['TS']]['TX_TIME'] = pkt_time _target_status[_target['TS']]['TX_TIME'] = pkt_time
@ -363,7 +363,7 @@ class routerOBP(OPENBRIDGE):
_tmp_bits = _bits _tmp_bits = _bits
# Assemble transmit HBP packet header # Assemble transmit HBP packet header
_tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + chr(_tmp_bits) + _data[16:20] _tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + _tmp_bits.to_bytes(1, 'big') + _data[16:20]
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT # MUST RE-WRITE DESTINATION TGID IF DIFFERENT
@ -377,12 +377,12 @@ class routerOBP(OPENBRIDGE):
elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM: elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM:
dmrbits = _target_status[_target['TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_T_LC'][98:197] dmrbits = _target_status[_target['TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_T_LC'][98:197]
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), 1)) systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), 1).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC) # Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]: elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264] dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264]
dmrpkt = dmrbits.tobytes() dmrpkt = dmrbits.tobytes()
_tmp_data = _tmp_data + dmrpkt + '\x00\x00' # Add two bytes of nothing since OBP doesn't include BER & RSSI bytes #_data[53:55] _tmp_data = _tmp_data + dmrpkt + b'\x00\x00' # Add two bytes of nothing since OBP doesn't include BER & RSSI bytes #_data[53:55]
# Transmit the packet to the destination system # Transmit the packet to the destination system
systems[_target['SYSTEM']].send_system(_tmp_data) systems[_target['SYSTEM']].send_system(_tmp_data)
@ -396,7 +396,7 @@ class routerOBP(OPENBRIDGE):
logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \ logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration) self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration)) self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration).encode(encoding='utf-8', errors='ignore'))
removed = self.STATUS.pop(_stream_id) removed = self.STATUS.pop(_stream_id)
logger.debug('(%s) OpenBridge sourced call stream end, remove terminated Stream ID: %s', self._system, int_id(_stream_id)) logger.debug('(%s) OpenBridge sourced call stream end, remove terminated Stream ID: %s', self._system, int_id(_stream_id))
if not removed: if not removed:
@ -483,7 +483,7 @@ class routerHBP(HBSYSTEM):
logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \ logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot) self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id))) self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore'))
# If we can, use the LC from the voice header as to keep all options intact # If we can, use the LC from the voice header as to keep all options intact
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD: if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
@ -539,7 +539,7 @@ class routerHBP(HBSYSTEM):
_tmp_bits = _bits & ~(1 << 7) _tmp_bits = _bits & ~(1 << 7)
# Assemble transmit HBP packet header # Assemble transmit HBP packet header
_tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + chr(_tmp_bits) + _data[16:20] _tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + _tmp_bits.to_bytes(1, 'big') + _data[16:20]
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT # MUST RE-WRITE DESTINATION TGID IF DIFFERENT
@ -585,8 +585,8 @@ class routerHBP(HBSYSTEM):
logger.info('(%s) Call not routed for subscriber %s, call route in progress on target: HBSystem: %s, TS: %s, TGID: %s, SUB: %s', self._system, int_id(_rf_src), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['TX_TGID']), int_id(_target_status[_target['TS']]['TX_RFS'])) logger.info('(%s) Call not routed for subscriber %s, call route in progress on target: HBSystem: %s, TS: %s, TGID: %s, SUB: %s', self._system, int_id(_rf_src), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['TX_TGID']), int_id(_target_status[_target['TS']]['TX_RFS']))
continue continue
# Is this a new call stream? # Is this a new call stream?
if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']) or (_target_status[_target['TS']]['TX_RFS'] != _rf_src) or (_target_status[_target['TS']]['TX_TGID'] != _target['TGID']): if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
# Record the DST TGID and Stream ID # Record the DST TGID and Stream ID
_target_status[_target['TS']]['TX_START'] = pkt_time _target_status[_target['TS']]['TX_START'] = pkt_time
_target_status[_target['TS']]['TX_TGID'] = _target['TGID'] _target_status[_target['TS']]['TX_TGID'] = _target['TGID']
@ -601,7 +601,7 @@ class routerHBP(HBSYSTEM):
logger.debug('(%s) Generating TX FULL and EMB LCs for HomeBrew destination: System: %s, TS: %s, TGID: %s', self._system, _target['SYSTEM'], _target['TS'], int_id(_target['TGID'])) logger.debug('(%s) Generating TX FULL and EMB LCs for HomeBrew destination: System: %s, TS: %s, TGID: %s', self._system, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
logger.info('(%s) Conference Bridge: %s, Call Bridged to HBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID'])) logger.info('(%s) Conference Bridge: %s, Call Bridged to HBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']))) systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID'])).encode(encoding='utf-8', errors='ignore'))
# Set other values for the contention handler to test next time there is a frame to forward # Set other values for the contention handler to test next time there is a frame to forward
_target_status[_target['TS']]['TX_TIME'] = pkt_time _target_status[_target['TS']]['TX_TIME'] = pkt_time
@ -614,7 +614,7 @@ class routerHBP(HBSYSTEM):
_tmp_bits = _bits _tmp_bits = _bits
# Assemble transmit HBP packet header # Assemble transmit HBP packet header
_tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + chr(_tmp_bits) + _data[16:20] _tmp_data = _data[:8] + _target['TGID'] + _data[11:15] + _tmp_bits.to_bytes(1, 'big') + _data[16:20]
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET # MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT # MUST RE-WRITE DESTINATION TGID IF DIFFERENT
@ -628,7 +628,7 @@ class routerHBP(HBSYSTEM):
elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM: elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM:
dmrbits = _target_status[_target['TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_T_LC'][98:197] dmrbits = _target_status[_target['TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_T_LC'][98:197]
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), 1)) systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), 1).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC) # Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]: elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264] dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264]
@ -647,7 +647,7 @@ class routerHBP(HBSYSTEM):
logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \ logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %s', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration) self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration)) self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration).encode(encoding='utf-8', errors='ignore'))
# #
# Begin in-band signalling for call end. This has nothign to do with routing traffic directly. # Begin in-band signalling for call end. This has nothign to do with routing traffic directly.
@ -721,10 +721,13 @@ class routerHBP(HBSYSTEM):
class confbridgeReportFactory(reportFactory): class confbridgeReportFactory(reportFactory):
def send_bridge(self): def send_bridge(self):
serialized = pickle.dumps(BRIDGES, protocol=pickle.HIGHEST_PROTOCOL) serialized = pickle.dumps(BRIDGES, protocol=2) #.decode("utf-8", errors='ignore')
self.send_clients(REPORT_OPCODES['BRIDGE_SND']+serialized) self.send_clients(REPORT_OPCODES['BRIDGE_SND']+serialized)
def send_bridgeEvent(self, _data): def send_bridgeEvent(self, _data):
if isinstance(_data, str):
print('bridge event was a string')
#_data = _data.decode('utf-8', error='ignore')
self.send_clients(REPORT_OPCODES['BRDG_EVENT']+_data) self.send_clients(REPORT_OPCODES['BRDG_EVENT']+_data)
@ -772,7 +775,7 @@ if __name__ == '__main__':
# Set signal handers so that we can gracefully exit if need be # Set signal handers so that we can gracefully exit if need be
for sig in [signal.SIGINT, signal.SIGTERM]: for sig in [signal.SIGINT, signal.SIGTERM]:
signal.signal(sig, sig_handler) signal.signal(sig, sig_handler)
# Create the name-number mapping dictionaries # Create the name-number mapping dictionaries
peer_ids, subscriber_ids, talkgroup_ids = mk_aliases(CONFIG) peer_ids, subscriber_ids, talkgroup_ids = mk_aliases(CONFIG)
@ -806,6 +809,5 @@ if __name__ == '__main__':
stream_trimmer_task = task.LoopingCall(stream_trimmer_loop) stream_trimmer_task = task.LoopingCall(stream_trimmer_loop)
stream_trimmer = stream_trimmer_task.start(5) stream_trimmer = stream_trimmer_task.start(5)
stream_trimmer.addErrback(loopingErrHandle) stream_trimmer.addErrback(loopingErrHandle)
reactor.run() reactor.run()

View File

@ -30,7 +30,7 @@ import configparser
import sys import sys
import const import const
from socket import gethostbyname from socket import gethostbyname
# Does anybody read this stuff? There's a PEP somewhere that says I should do this. # Does anybody read this stuff? There's a PEP somewhere that says I should do this.
__author__ = 'Cortney T. Buffington, N0MJS' __author__ = 'Cortney T. Buffington, N0MJS'
@ -222,7 +222,7 @@ def build_config(_config_file):
'NETWORK_ID': config.getint(section, 'NETWORK_ID').to_bytes(4, 'big'), 'NETWORK_ID': config.getint(section, 'NETWORK_ID').to_bytes(4, 'big'),
'IP': gethostbyname(config.get(section, 'IP')), 'IP': gethostbyname(config.get(section, 'IP')),
'PORT': config.getint(section, 'PORT'), 'PORT': config.getint(section, 'PORT'),
'PASSPHRASE': config.get(section, 'PASSPHRASE').ljust(20,'\x00')[:20], '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_SOCK': (gethostbyname(config.get(section, 'TARGET_IP')), config.getint(section, 'TARGET_PORT')),
'TARGET_IP': gethostbyname(config.get(section, 'TARGET_IP')), 'TARGET_IP': gethostbyname(config.get(section, 'TARGET_IP')),
'TARGET_PORT': config.getint(section, 'TARGET_PORT'), 'TARGET_PORT': config.getint(section, 'TARGET_PORT'),

View File

@ -39,6 +39,9 @@ ID_MAX = 16776415
# Timers # Timers
STREAM_TO = .360 STREAM_TO = .360
# Options from the LC - used for late entry
LC_OPT = b'\x00\x00\x20'
# HomeBrew Protocol Frame Types # HomeBrew Protocol Frame Types
HBPF_VOICE = 0x0 HBPF_VOICE = 0x0
HBPF_VOICE_SYNC = 0x1 HBPF_VOICE_SYNC = 0x1
@ -50,7 +53,7 @@ HBPF_SLT_VTERM = 0x2
DMRD = b'DMRD' DMRD = b'DMRD'
MSTCL = b'MSTCL' MSTCL = b'MSTCL'
MSTNAK = b'MSTNAC' MSTNAK = b'MSTNAC'
MSTPONG = b'MSTPONG' MSTPONG = b'MSTPONG'
MSTN = b'MSTN' MSTN = b'MSTN'
MSTP = b'MSTP' MSTP = b'MSTP'
MSTC = b'MSTC' MSTC = b'MSTC'
@ -67,4 +70,4 @@ RPTO = b'RPTO'
# Higheset peer ID permitted by HBP # Higheset peer ID permitted by HBP
PEER_MAX = 4294967295 PEER_MAX = 4294967295

View File

@ -49,7 +49,7 @@ from twisted.internet import reactor, task
import log import log
import config import config
from const import * from const import *
from dmr_utils3.utils import int_id, hex_str_4, try_download, mk_id_dict from dmr_utils3.utils import int_id, bytes_4, try_download, mk_id_dict
# Imports for the reporting server # Imports for the reporting server
import pickle as pickle import pickle as pickle
@ -141,7 +141,7 @@ class OPENBRIDGE(DatagramProtocol):
# Keep This Line Commented Unless HEAVILY Debugging! # Keep This Line Commented Unless HEAVILY Debugging!
#logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_packet)) #logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_packet))
if _packet[:4] == 'DMRD': # DMRData -- encapsulated DMR data frame if _packet[:4] == b'DMRD': # DMRData -- encapsulated DMR data frame
_data = _packet[:53] _data = _packet[:53]
_hash = _packet[53:] _hash = _packet[53:]
_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() _ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest()
@ -151,7 +151,7 @@ class OPENBRIDGE(DatagramProtocol):
_seq = _data[4] _seq = _data[4]
_rf_src = _data[5:8] _rf_src = _data[5:8]
_dst_id = _data[8:11] _dst_id = _data[8:11]
_bits = int_id(_data[15]) _bits = _data[15]
_slot = 2 if (_bits & 0x80) else 1 _slot = 2 if (_bits & 0x80) else 1
#_call_type = 'unit' if (_bits & 0x40) else 'group' #_call_type = 'unit' if (_bits & 0x40) else 'group'
if _bits & 0x40: if _bits & 0x40:
@ -414,7 +414,7 @@ class HBSYSTEM(DatagramProtocol):
'PACKAGE_ID': '', 'PACKAGE_ID': '',
}}) }})
logger.info('(%s) Repeater Logging in with Radio ID: %s, %s:%s', self._system, int_id(_peer_id), _sockaddr[0], _sockaddr[1]) logger.info('(%s) Repeater Logging in with Radio ID: %s, %s:%s', self._system, int_id(_peer_id), _sockaddr[0], _sockaddr[1])
_salt_str = hex_str_4(self._peers[_peer_id]['SALT']) _salt_str = bytes_4(self._peers[_peer_id]['SALT'])
self.send_peer(_peer_id, RPTACK + _salt_str) self.send_peer(_peer_id, RPTACK + _salt_str)
self._peers[_peer_id]['CONNECTION'] = 'CHALLENGE_SENT' self._peers[_peer_id]['CONNECTION'] = 'CHALLENGE_SENT'
logger.info('(%s) Sent Challenge Response to %s for login: %s', self._system, int_id(_peer_id), self._peers[_peer_id]['SALT']) logger.info('(%s) Sent Challenge Response to %s for login: %s', self._system, int_id(_peer_id), self._peers[_peer_id]['SALT'])
@ -433,7 +433,7 @@ class HBSYSTEM(DatagramProtocol):
_this_peer = self._peers[_peer_id] _this_peer = self._peers[_peer_id]
_this_peer['LAST_PING'] = time() _this_peer['LAST_PING'] = time()
_sent_hash = _data[8:] _sent_hash = _data[8:]
_salt_str = hex_str_4(_this_peer['SALT']) _salt_str = bytes_4(_this_peer['SALT'])
_calc_hash = bhex(sha256(_salt_str+self._config['PASSPHRASE']).hexdigest()) _calc_hash = bhex(sha256(_salt_str+self._config['PASSPHRASE']).hexdigest())
if _sent_hash == _calc_hash: if _sent_hash == _calc_hash:
_this_peer['CONNECTION'] = 'WAITING_CONFIG' _this_peer['CONNECTION'] = 'WAITING_CONFIG'
@ -708,7 +708,7 @@ class reportFactory(Factory):
client.sendString(_message) client.sendString(_message)
def send_config(self): def send_config(self):
serialized = pickle.dumps(self._config['SYSTEMS'], protocol=2) #pickle.HIGHEST_PROTOCOL) serialized = pickle.dumps(self._config['SYSTEMS'], protocol=2) #.decode('utf-8', errors='ignore') #pickle.HIGHEST_PROTOCOL)
self.send_clients(REPORT_OPCODES['CONFIG_SND']+serialized) self.send_clients(REPORT_OPCODES['CONFIG_SND']+serialized)
@ -772,7 +772,7 @@ if __name__ == '__main__':
logger = log.config_logging(CONFIG['LOGGER']) logger = log.config_logging(CONFIG['LOGGER'])
logger.info('\n\nCopyright (c) 2013, 2014, 2015, 2016, 2018\n\tThe Founding Members of the K0USY Group. All rights reserved.\n') logger.info('\n\nCopyright (c) 2013, 2014, 2015, 2016, 2018\n\tThe Founding Members of the K0USY Group. All rights reserved.\n')
logger.debug('Logging system started, anything from here on gets logged') logger.debug('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('SHUTDOWN: HBLINK IS TERMINATING WITH SIGNAL %s', str(_signal)) logger.info('SHUTDOWN: HBLINK IS TERMINATING WITH SIGNAL %s', str(_signal))
@ -799,5 +799,5 @@ if __name__ == '__main__':
systems[system] = HBSYSTEM(system, CONFIG, report_server) systems[system] = HBSYSTEM(system, CONFIG, report_server)
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('%s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system]) logger.debug('%s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
reactor.run() reactor.run()

View File

@ -36,7 +36,7 @@ from twisted.internet import reactor, task
# Things we import from the main hblink module # Things we import from the main hblink module
from hblink import HBSYSTEM, systems, hblink_handler, reportFactory, REPORT_OPCODES, config_reports, mk_aliases from hblink import HBSYSTEM, systems, hblink_handler, reportFactory, REPORT_OPCODES, config_reports, mk_aliases
from dmr_utils.utils import hex_str_3, int_id, get_alias from dmr_utils.utils import bytes_3, int_id, get_alias
from dmr_utils import decode, bptc, const from dmr_utils import decode, bptc, const
import hb_config import hb_config
import hb_log import hb_log

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,12 @@
# Opcodes for the network-based reporting protocol # Opcodes for the network-based reporting protocol
REPORT_OPCODES = { REPORT_OPCODES = {
'CONFIG_REQ': '\x00', 'CONFIG_REQ': b'\x00',
'CONFIG_SND': '\x01', 'CONFIG_SND': b'\x01',
'BRIDGE_REQ': '\x02', 'BRIDGE_REQ': b'\x02',
'BRIDGE_SND': '\x03', 'BRIDGE_SND': b'\x03',
'CONFIG_UPD': '\x04', 'CONFIG_UPD': b'\x04',
'BRIDGE_UPD': '\x05', 'BRIDGE_UPD': b'\x05',
'LINK_EVENT': '\x06', 'LINK_EVENT': b'\x06',
'BRDG_EVENT': '\x07', 'BRDG_EVENT': b'\x07',
} }

View File

@ -1,21 +0,0 @@
'''
THIS EXAMPLE WILL NOT WORK AS IT IS - YOU MUST SPECIFY YOUR OWN VALUES!!!
'''
BRIDGES = {
'KANSAS': [
{'SYSTEM': 'PLYMOUTH', 'TS': 2, 'TGID': 3120, 'ACTIVE': True, 'TIMEOUT': 2, 'TO_TYPE': 'NONE', 'ON': [2,], 'OFF': [9,]},
],
'BYRG': [
{'SYSTEM': 'PLYMOUTH', 'TS': 1, 'TGID': 3100, 'ACTIVE': True, 'TIMEOUT': 2, 'TO_TYPE': 'NONE', 'ON': [3,], 'OFF': [8,]},
],
'ENGLISH': [
{'SYSTEM': 'PLYMOUTH', 'TS': 1, 'TGID': 13, 'ACTIVE': True, 'TIMEOUT': 2, 'TO_TYPE': 'NONE', 'ON': [4,], 'OFF': [7,]},
]
}
if __name__ == '__main__':
from pprint import pprint
pprint(BRIDGES)

File diff suppressed because it is too large Load Diff