From f2a8fdf79b0063ff9c02db433ca96b574bd9134c Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Fri, 26 Aug 2016 21:31:20 -0500 Subject: [PATCH] update call routing --- hb_router.py | 57 +++++++++++++++++++++++++++++++-------------- hb_routing_rules.py | 4 ++-- hblink.py | 24 +++++++++++++++---- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/hb_router.py b/hb_router.py index 7a3e149..adefffa 100755 --- a/hb_router.py +++ b/hb_router.py @@ -67,30 +67,51 @@ __status__ = 'pre-alpha' class routerMASTER(HBMASTER): - def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _data): - for rule in RULES[self._master]['GROUP_VOICE']: - _target = rule['DST_NET'] - if _target in RULES: - systems[_target].send_system(_data) - logger.debug('(%s) Packet routed %s to system: %s', self._master, CONFIG[_target]['MODE'], _target) + def dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data): + _bits = int_id(_data[15]) + + if _call_type == 'group': + for rule in RULES[self._master]['GROUP_VOICE']: + _target = rule['DST_NET'] + if (rule['SRC_GROUP'] == _dst_id and rule['SRC_TS'] == _slot and rule['ACTIVE'] == True): + if RULE['SRC_TS'] != RULE['DST_TS']: + _tmp_bits = _bits ^ 1 << 7 + else: + _tmp_bits = _bits + _tmp_data = _data[:8] + rule['DST_GROUP'] + _data[12:15] + chr(bits) + _data[16:] + print(h(_tmp_data)) + print(h(_tmp_data)) + systems[_target].send_system(_tmp_data) - else: - logger.debug('(%s) Packet router found no target for packet. Destination was: %s on target network %s', self._master, _dst_id, _target) - continue + logger.debug('(%s) Packet routed %s to system: %s', self._master, CONFIG[_target]['MODE'], _target) + else: + logger.debug('(%s) Packet router found no target for packet. Destination was: %s on target network %s', self._master, _dst_id, _target) + continue class routerCLIENT(HBCLIENT): - def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _data): - for rule in RULES[self._client]['GROUP_VOICE']: - _target = rule['DST_NET'] - if _target in RULES: - system[_target].send_system(_data) - logger.debug('(%s) Packet routed to %s system: %s', self._client, CONFIG[_target]['MODE'], _target) + def dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data): + _bits = int_id(_data[15]) + + if _call_type == 'group': + for rule in RULES[self._client]['GROUP_VOICE']: + _target = rule['DST_NET'] + if (rule['SRC_GROUP'] == _dst_id and rule['SRC_TS'] == _slot and rule['ACTIVE'] == True): + if RULE['SRC_TS'] != RULE['DST_TS']: + _tmp_bits = _bits ^ 1 << 7 + else: + _tmp_bits = _bits + _tmp_data = _data[:8] + rule['DST_GROUP'] + _data[12:15] + chr(bits) + _data[16:] + print(h(_tmp_data)) + print(h(_tmp_data)) + systems[_target].send_system(_tmp_data) + + logger.debug('(%s) Packet routed to %s system: %s', self._client, CONFIG[_target]['MODE'], _target) - else: - logger.debug('(%s) Packet router found no target for packet. Destination was: %s on target network %s', self._client, _dst_id, _target) - continue + else: + logger.debug('(%s) Packet router found no target for packet. Destination was: %s on target network %s', self._client, _dst_id, _target) + continue #************************************************ # MAIN PROGRAM LOOP STARTS HERE diff --git a/hb_routing_rules.py b/hb_routing_rules.py index 164a495..932b7e5 100644 --- a/hb_routing_rules.py +++ b/hb_routing_rules.py @@ -2,7 +2,7 @@ RULES = { 'MASTER-1': { 'GROUP_HANGTIME': 5, 'GROUP_VOICE': [ - {'NAME': 'STATEWIDE', 'ACTIVE': False, 'ON': [8,], 'OFF': [9,10], 'SRC_TS': 1, 'SRC_GROUP': 1, 'DST-TYPE': 'CLIENT', 'DST_NET': 'REPEATER-1', 'DST_TS': 2, 'DST_GROUP': 2}, + {'NAME': 'STATEWIDE', 'DST_NET': 'REPEATER-1', 'SRC_TS': 2, 'SRC_GROUP': 3120, 'DST_TS': 2, 'DST_GROUP': 3120, 'ACTIVE': True, 'TO_TYPE': 'ON', 'TIMEOUT': 2, 'ON': [8,], 'OFF': [9,10]}, # When DMRD received on this MASTER, Time Slot 1, Talk Group 1; send to CLIENT-1 on Time Slot 2 Talk Group 2 # This rule is NOT enabled by default # This rule can be enabled by transmitting on TGID 8 @@ -13,7 +13,7 @@ RULES = { 'REPEATER-1': { 'GROUP_HANGTIME': 5, 'GROUP_VOICE': [ - {'NAME': 'STATEWIDE', 'ACTIVE': False, 'ON': [8,], 'OFF': [9,10], 'SRC_TS': 1, 'SRC_GROUP': 1, 'DST-TYPE': 'MASTER', 'DST_NET': 'MASTER-1', 'DST_TS': 2, 'DST_GROUP': 2}, + {'NAME': 'STATEWIDE', 'DST_NET': 'MASTER-1', 'SRC_TS': 2, 'SRC_GROUP': 3120, 'DST_TS': 2, 'DST_GROUP': 3120, 'ACTIVE': True, 'TO_TYPE': 'ON', 'TIMEOUT': 2, 'ON': [8,], 'OFF': [9,10]}, # When DMRD received on this CLIENT, Time Slot 1, Talk Group 1; send to MASTER-1 on Time Slot 2 Talk Group 2 # This rule is NOT enabled by default # This rule can be enabled by transmitting on TGID 8 diff --git a/hblink.py b/hblink.py index 0d1f359..2011bcc 100755 --- a/hblink.py +++ b/hblink.py @@ -203,7 +203,7 @@ class HBMASTER(DatagramProtocol): # regardless of the system type (MASTER or CLIENT) send_system = send_clients - def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _data): + def dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data): pass def datagramReceived(self, _data, (_host, _port)): @@ -223,7 +223,7 @@ class HBMASTER(DatagramProtocol): _rf_src = _data[5:8] _dst_id = _data[8:11] _bits = int_id(_data[15]) - _slot = 2 if (_bits & 0x40) else 1 + _slot = 2 if (_bits & 0x80) else 1 _call_type = 'group' if (_bits & 0x40) else 'unit' _raw_frame_type = (_bits & 0x30) >> 4 if _raw_frame_type == 0b00: @@ -250,7 +250,7 @@ class HBMASTER(DatagramProtocol): logger.debug('(%s) Packet repeated to client: %s', self._master, int_id(_client)) # Userland actions -- typically this is the function you subclass for an application - self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _data) + self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data) elif _command == 'RPTL': # RPTLogin -- a repeater wants to login _radio_id = _data[4:8] @@ -416,7 +416,7 @@ class HBCLIENT(DatagramProtocol): # regardless of the system type (MASTER or CLIENT) send_system = send_master - def dmrd_received(self, _radio_id, _rf_src, _dst_id, _seq, _data): + def dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data): pass def datagramReceived(self, _data, (_host, _port)): @@ -433,6 +433,20 @@ class HBCLIENT(DatagramProtocol): _seq = _data[4:5] _rf_src = _data[5:8] _dst_id = _data[8:11] + _bits = int_id(_data[15]) + _slot = 2 if (_bits & 0x80) else 1 + _call_type = 'group' if (_bits & 0x40) else 'unit' + _raw_frame_type = (_bits & 0x30) >> 4 + if _raw_frame_type == 0b00: + _frame_type = 'voice' + elif _raw_frame_type == 0b01: + _frame_type = 'voice_sync' + elif _raw_frame_type == 0b10: + _frame_type = 'data_sync' + else: + _frame_type = 'none' + _stream_id = _data[16:20] + #logger.debug('(%s) DMRD - Seqence: %s, RF Source: %s, Destination ID: %s', self._client, h(_seq), int_id(_rf_src), int_id(_dst_id)) # If AMBE audio exporting is configured... @@ -440,7 +454,7 @@ class HBCLIENT(DatagramProtocol): self._ambe.parseAMBE(self._client, _data) # Userland actions -- typically this is the function you subclass for an application - self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _data) + self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _stream_id, _data) elif _command == 'MSTN': # Actually MSTNAK -- a NACK from the master _radio_id = _data[4:8]