Mostly kinda works now
This commit is contained in:
		
							parent
							
								
									2860ec6847
								
							
						
					
					
						commit
						77d19f65ed
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -93,3 +93,5 @@ hblink.cfg | |||||||
| *.config | *.config | ||||||
| *.bak | *.bak | ||||||
| rules.py | rules.py | ||||||
|  | subscriber_ids.csv | ||||||
|  | peer_ids.csv | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								bridge.py
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								bridge.py
									
									
									
									
									
								
							| @ -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 | ||||||
| @ -586,7 +586,7 @@ class routerHBP(HBSYSTEM): | |||||||
|                                             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) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -807,5 +810,4 @@ if __name__ == '__main__': | |||||||
|     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() | ||||||
|  | |||||||
| @ -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'), | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								const.py
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								const.py
									
									
									
									
									
								
							| @ -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' | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								hblink.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								hblink.py
									
									
									
									
									
								
							| @ -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) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
							
								
								
									
										5591
									
								
								peer_ids.csv
									
									
									
									
									
								
							
							
						
						
									
										5591
									
								
								peer_ids.csv
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -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', | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								rules.py
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								rules.py
									
									
									
									
									
								
							| @ -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) |  | ||||||
							
								
								
									
										116858
									
								
								subscriber_ids.csv
									
									
									
									
									
								
							
							
						
						
									
										116858
									
								
								subscriber_ids.csv
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user