mirror of
				https://github.com/ShaYmez/hblink3.git
				synced 2025-10-27 11:00:31 -04:00 
			
		
		
		
	Restore XLXPEER functionality
This commit is contained in:
		
							parent
							
								
									d0d496b232
								
							
						
					
					
						commit
						4b9864671e
					
				
							
								
								
									
										49
									
								
								config.py
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								config.py
									
									
									
									
									
								
							| @ -182,7 +182,7 @@ def build_config(_config_file): | ||||
|                         'SOFTWARE_ID': bytes(config.get(section, 'SOFTWARE_ID').ljust(40)[:40], 'utf-8'), | ||||
|                         'PACKAGE_ID': bytes(config.get(section, 'PACKAGE_ID').ljust(40)[:40], 'utf-8'), | ||||
|                         'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'), | ||||
|                         'OPTIONS': b''.join([b'Type=HBlink;', bytes(config.get(section, 'OPTIONS'), 'utf-8')]), | ||||
|                         'OPTIONS': bytes(config.get(section, 'OPTIONS'), 'utf-8'), | ||||
|                         'USE_ACL': config.getboolean(section, 'USE_ACL'), | ||||
|                         'SUB_ACL': config.get(section, 'SUB_ACL'), | ||||
|                         'TG1_ACL': config.get(section, 'TGID_TS1_ACL'), | ||||
| @ -199,6 +199,52 @@ def build_config(_config_file): | ||||
|                         'LAST_PING_ACK_TIME': 0, | ||||
|                     }}) | ||||
| 
 | ||||
|                 if config.get(section, 'MODE') == 'XLXPEER': | ||||
|                     CONFIG['SYSTEMS'].update({section: { | ||||
|                         'MODE': config.get(section, 'MODE'), | ||||
|                         'ENABLED': config.getboolean(section, 'ENABLED'), | ||||
|                         'LOOSE': config.getboolean(section, 'LOOSE'), | ||||
|                         'SOCK_ADDR': (gethostbyname(config.get(section, 'IP')), config.getint(section, 'PORT')), | ||||
|                         'IP': gethostbyname(config.get(section, 'IP')), | ||||
|                         'PORT': config.getint(section, 'PORT'), | ||||
|                         'MASTER_SOCKADDR': (gethostbyname(config.get(section, 'MASTER_IP')), config.getint(section, 'MASTER_PORT')), | ||||
|                         'MASTER_IP': gethostbyname(config.get(section, 'MASTER_IP')), | ||||
|                         'MASTER_PORT': config.getint(section, 'MASTER_PORT'), | ||||
|                         'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE'), 'utf-8'), | ||||
|                         'CALLSIGN': bytes(config.get(section, 'CALLSIGN').ljust(8)[:8], 'utf-8'), | ||||
|                         'RADIO_ID': config.getint(section, 'RADIO_ID').to_bytes(4, 'big'), | ||||
|                         'RX_FREQ': bytes(config.get(section, 'RX_FREQ').ljust(9)[:9], 'utf-8'), | ||||
|                         'TX_FREQ': bytes(config.get(section, 'TX_FREQ').ljust(9)[:9], 'utf-8'), | ||||
|                         'TX_POWER': bytes(config.get(section, 'TX_POWER').rjust(2,'0'), 'utf-8'), | ||||
|                         'COLORCODE': bytes(config.get(section, 'COLORCODE').rjust(2,'0'), 'utf-8'), | ||||
|                         'LATITUDE': bytes(config.get(section, 'LATITUDE').ljust(8)[:8], 'utf-8'), | ||||
|                         'LONGITUDE': bytes(config.get(section, 'LONGITUDE').ljust(9)[:9], 'utf-8'), | ||||
|                         'HEIGHT': bytes(config.get(section, 'HEIGHT').rjust(3,'0'), 'utf-8'), | ||||
|                         'LOCATION': bytes(config.get(section, 'LOCATION').ljust(20)[:20], 'utf-8'), | ||||
|                         'DESCRIPTION': bytes(config.get(section, 'DESCRIPTION').ljust(19)[:19], 'utf-8'), | ||||
|                         'SLOTS': bytes(config.get(section, 'SLOTS'), 'utf-8'), | ||||
|                         'URL': bytes(config.get(section, 'URL').ljust(124)[:124], 'utf-8'), | ||||
|                         'SOFTWARE_ID': bytes(config.get(section, 'SOFTWARE_ID').ljust(40)[:40], 'utf-8'), | ||||
|                         'PACKAGE_ID': bytes(config.get(section, 'PACKAGE_ID').ljust(40)[:40], 'utf-8'), | ||||
|                         'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'), | ||||
|                         'XLXMODULE': config.getint(section, 'XLXMODULE'), | ||||
|                         'OPTIONS': '', | ||||
|                         'USE_ACL': config.getboolean(section, 'USE_ACL'), | ||||
|                         'SUB_ACL': config.get(section, 'SUB_ACL'), | ||||
|                         'TG1_ACL': config.get(section, 'TGID_TS1_ACL'), | ||||
|                         'TG2_ACL': config.get(section, 'TGID_TS2_ACL') | ||||
|                     }}) | ||||
|                     CONFIG['SYSTEMS'][section].update({'XLXSTATS': { | ||||
|                         'CONNECTION': 'NO',             # NO, RTPL_SENT, AUTHENTICATED, CONFIG-SENT, YES  | ||||
|                         'CONNECTED': None, | ||||
|                         'PINGS_SENT': 0, | ||||
|                         'PINGS_ACKD': 0, | ||||
|                         'NUM_OUTSTANDING': 0, | ||||
|                         'PING_OUTSTANDING': False, | ||||
|                         'LAST_PING_TX_TIME': 0, | ||||
|                         'LAST_PING_ACK_TIME': 0, | ||||
|                     }}) | ||||
| 
 | ||||
|                 elif config.get(section, 'MODE') == 'MASTER': | ||||
|                     CONFIG['SYSTEMS'].update({section: { | ||||
|                         'MODE': config.get(section, 'MODE'), | ||||
| @ -228,7 +274,6 @@ def build_config(_config_file): | ||||
|                         'TARGET_SOCK': (gethostbyname(config.get(section, 'TARGET_IP')), config.getint(section, 'TARGET_PORT')), | ||||
|                         'TARGET_IP': gethostbyname(config.get(section, 'TARGET_IP')), | ||||
|                         'TARGET_PORT': config.getint(section, 'TARGET_PORT'), | ||||
|                         'BOTH_SLOTS': config.getboolean(section, 'BOTH_SLOTS'), | ||||
|                         'USE_ACL': config.getboolean(section, 'USE_ACL'), | ||||
|                         'SUB_ACL': config.get(section, 'SUB_ACL'), | ||||
|                         'TG1_ACL': config.get(section, 'TGID_ACL'), | ||||
|  | ||||
| @ -120,9 +120,7 @@ STALE_DAYS: 7 | ||||
| # | ||||
| # ACLs: | ||||
| # OpenBridge does not 'register', so registration ACL is meaningless. | ||||
| # Proper OpenBridge passes all traffic on TS1. | ||||
| # HBlink can extend OPB to use both slots for unit calls only. | ||||
| # Setting "BOTH_SLOTS" True ONLY affects unit traffic! | ||||
| # OpenBridge passes all traffic on TS1, so there is only 1 TGID ACL. | ||||
| # Otherwise ACLs work as described in the global stanza | ||||
| [OBP-1] | ||||
| MODE: OPENBRIDGE | ||||
| @ -133,7 +131,6 @@ NETWORK_ID: 3129100 | ||||
| PASSPHRASE: password | ||||
| TARGET_IP: 1.2.3.4 | ||||
| TARGET_PORT: 62035 | ||||
| BOTH_SLOTS: True | ||||
| USE_ACL: True | ||||
| SUB_ACL: DENY:1 | ||||
| TGID_ACL: PERMIT:ALL | ||||
| @ -210,3 +207,35 @@ USE_ACL: True | ||||
| SUB_ACL: DENY:1 | ||||
| TGID_TS1_ACL: PERMIT:ALL | ||||
| TGID_TS2_ACL: PERMIT:ALL | ||||
| 
 | ||||
| [XLX-1] | ||||
| MODE: XLXPEER | ||||
| ENABLED: True | ||||
| LOOSE: True | ||||
| EXPORT_AMBE: False | ||||
| IP:  | ||||
| PORT: 54002 | ||||
| MASTER_IP: 172.16.1.1 | ||||
| MASTER_PORT: 62030 | ||||
| PASSPHRASE: passw0rd | ||||
| CALLSIGN: W1ABC | ||||
| RADIO_ID: 312000 | ||||
| RX_FREQ: 449000000 | ||||
| TX_FREQ: 444000000 | ||||
| TX_POWER: 25 | ||||
| COLORCODE: 1 | ||||
| SLOTS: 1 | ||||
| LATITUDE: 38.0000 | ||||
| LONGITUDE: -095.0000 | ||||
| HEIGHT: 75 | ||||
| LOCATION: Anywhere, USA | ||||
| DESCRIPTION: This is a cool repeater | ||||
| URL: www.w1abc.org | ||||
| SOFTWARE_ID: 20170620 | ||||
| PACKAGE_ID: MMDVM_HBlink | ||||
| GROUP_HANGTIME: 5 | ||||
| XLXMODULE: 4004 | ||||
| USE_ACL: True | ||||
| SUB_ACL: DENY:1 | ||||
| TGID_TS1_ACL: PERMIT:ALL | ||||
| TGID_TS2_ACL: PERMIT:ALL | ||||
|  | ||||
							
								
								
									
										48
									
								
								hblink.py
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								hblink.py
									
									
									
									
									
								
							| @ -223,6 +223,13 @@ class HBSYSTEM(DatagramProtocol): | ||||
|             self.datagramReceived = self.peer_datagramReceived | ||||
|             self.dereg = self.peer_dereg | ||||
| 
 | ||||
|         elif self._config['MODE'] == 'XLXPEER': | ||||
|             self._stats = self._config['XLXSTATS'] | ||||
|             self.send_system = self.send_master | ||||
|             self.maintenance_loop = self.peer_maintenance_loop | ||||
|             self.datagramReceived = self.peer_datagramReceived | ||||
|             self.dereg = self.peer_dereg | ||||
| 
 | ||||
|     def startProtocol(self): | ||||
|         # Set up periodic loop for tracking pings from peers. Run every 'PING_TIME' seconds | ||||
|         self._system_maintenance = task.LoopingCall(self.maintenance_loop) | ||||
| @ -282,6 +289,29 @@ class HBSYSTEM(DatagramProtocol): | ||||
|         # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! | ||||
|         # logger.debug('(%s) TX Packet to %s:%s -- %s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT'], ahex(_packet)) | ||||
| 
 | ||||
|     def send_xlxmaster(self, radio, xlx, mastersock): | ||||
|         radio3 = int.from_bytes(radio, 'big').to_bytes(3, 'big') | ||||
|         radio4 = int.from_bytes(radio, 'big').to_bytes(4, 'big') | ||||
|         xlx3   = xlx.to_bytes(3, 'big') | ||||
|         streamid = randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big')+randint(0,255).to_bytes(1, 'big') | ||||
|         # Wait for .5 secs for the XLX to log us in | ||||
|         for packetnr in range(5): | ||||
|             if packetnr < 3: | ||||
|                 # First 3 packets, voice start, stream type e1 | ||||
|                 strmtype = 225 | ||||
|                 payload = bytearray.fromhex('4f2e00b501ae3a001c40a0c1cc7dff57d75df5d5065026f82880bd616f13f185890000') | ||||
|             else: | ||||
|                 # Last 2 packets, voice end, stream type e2 | ||||
|                 strmtype = 226 | ||||
|                 payload = bytearray.fromhex('4f410061011e3a781c30a061ccbdff57d75df5d2534425c02fe0b1216713e885ba0000') | ||||
|             packetnr1 = packetnr.to_bytes(1, 'big') | ||||
|             strmtype1 = strmtype.to_bytes(1, 'big') | ||||
|             _packet = b''.join([DMRD, packetnr1, radio3, xlx3, radio4, strmtype1, streamid, payload]) | ||||
|             self.transport.write(_packet, mastersock) | ||||
|             # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! | ||||
|             #logger.debug('(%s) XLX Module Change Packet: %s', self._system, ahex(_packet)) | ||||
|         return | ||||
| 
 | ||||
|     def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data): | ||||
|         pass | ||||
| 
 | ||||
| @ -489,18 +519,6 @@ class HBSYSTEM(DatagramProtocol): | ||||
|                     self.transport.write(b''.join([MSTNAK, _peer_id]), _sockaddr) | ||||
|                     logger.warning('(%s) Ping from Radio ID that is not logged in: %s', self._system, int_id(_peer_id)) | ||||
| 
 | ||||
|         elif _command == RPTO: | ||||
|             _peer_id = _data[4:8] | ||||
|             if _peer_id in self._peers \ | ||||
|                         and self._peers[_peer_id]['CONNECTION'] == 'YES' \ | ||||
|                         and self._peers[_peer_id]['SOCKADDR'] == _sockaddr: | ||||
|                 logger.info('(%s) Peer %s (%s) has send options: %s', self._system, self._peers[_peer_id]['CALLSIGN'], int_id(_peer_id), _data[8:]) | ||||
|                 self.transport.write(b''.join([RPTACK, _peer_id]), _sockaddr) | ||||
| 
 | ||||
|         elif _command == DMRA: | ||||
|             _peer_id = _data[4:8] | ||||
|             logger.info('(%s) Recieved DMR Talker Alias from peer %s, subscriber %s', self._system, self._peers[_peer_id]['CALLSIGN'], int_id(_rf_src)) | ||||
|              | ||||
|         else: | ||||
|             logger.error('(%s) Unrecognized command. Raw HBP PDU: %s', self._system, ahex(_data)) | ||||
| 
 | ||||
| @ -630,7 +648,11 @@ class HBSYSTEM(DatagramProtocol): | ||||
|                             self._stats['CONNECTION'] = 'YES' | ||||
|                             self._stats['CONNECTED'] = time() | ||||
|                             logger.info('(%s) Connection to Master Completed', self._system) | ||||
|                              | ||||
|                             # If we are an XLX, send the XLX module request here. | ||||
|                             if self._config['MODE'] == 'XLXPEER': | ||||
|                                 self.send_xlxmaster(self._config['RADIO_ID'], int(4000), self._config['MASTER_SOCKADDR']) | ||||
|                                 self.send_xlxmaster(self._config['RADIO_ID'], self._config['XLXMODULE'], self._config['MASTER_SOCKADDR']) | ||||
|                                 logger.info('(%s) Sending XLX Module request', self._system) | ||||
|                     else: | ||||
|                         self._stats['CONNECTION'] = 'NO' | ||||
|                         logger.error('(%s) Master ACK Contained wrong ID - Connection Reset', self._system) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user