diff --git a/hb_bridge_all.py b/hb_bridge_all.py index 068c8a2..9d98c35 100755 --- a/hb_bridge_all.py +++ b/hb_bridge_all.py @@ -134,7 +134,7 @@ class bridgeallSYSTEM(HBSYSTEM): for _target in self._CONFIG['SYSTEMS']: if _target != self._system: systems[_target].send_system(_data) - self._logger.debug('(%s) Packet routed to system: %s', self._system, _target) + #self._logger.debug('(%s) Packet routed to system: %s', self._system, _target) # Final actions - Is this a voice terminator? @@ -228,4 +228,4 @@ if __name__ == '__main__': 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]) - reactor.run() \ No newline at end of file + reactor.run() diff --git a/hb_config.py b/hb_config.py index 2f3e1a3..110b493 100755 --- a/hb_config.py +++ b/hb_config.py @@ -121,6 +121,7 @@ def build_config(_config_file): 'CONNECTION': 'NO', # NO, RTPL_SENT, AUTHENTICATED, CONFIG-SENT, YES 'PINGS_SENT': 0, 'PINGS_ACKD': 0, + 'NUM_OUTSTANDING': 0, 'PING_OUTSTANDING': False, 'LAST_PING_TX_TIME': 0, 'LAST_PING_ACK_TIME': 0, diff --git a/hblink.py b/hblink.py index f7d4037..0d76aff 100755 --- a/hblink.py +++ b/hblink.py @@ -154,18 +154,23 @@ class HBSYSTEM(DatagramProtocol): # Aliased in __init__ to maintenance_loop if system is a client def client_maintenance_loop(self): self._logger.debug('(%s) Client maintenance loop started', self._system) + if self._stats['PING_OUTSTANDING']: + self._stats['NUM_OUTSTANDING'] += 1 # If we're not connected, zero out the stats and send a login request RPTL - if self._stats['CONNECTION'] == 'NO' or self._stats['CONNECTION'] == 'RTPL_SENT': + if self._stats['CONNECTION'] == 'NO' or self._stats['CONNECTION'] == 'RPTL_SENT' or self._stats['NUM_OUTSTANDING'] >= self._CONFIG['GLOBAL']['MAX_MISSED']: self._stats['PINGS_SENT'] = 0 self._stats['PINGS_ACKD'] = 0 - self._stats['CONNECTION'] = 'RTPL_SENT' + self._stats['NUM_OUTSTANDING'] = 0 + self._stats['PING_OUTSTANDING'] = False + self._stats['CONNECTION'] = 'RPTL_SENT' self.send_master('RPTL'+self._config['RADIO_ID']) self._logger.info('(%s) Sending login request to master %s:%s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT']) # If we are connected, sent a ping to the master and increment the counter if self._stats['CONNECTION'] == 'YES': self.send_master('RPTPING'+self._config['RADIO_ID']) + self._logger.debug('(%s) RPTPING Sent to Master. Total Sent: %s, Total Missed: %s, Currently Outstanding: %s', self._system, self._stats['PINGS_SENT'], self._stats['PINGS_SENT'] - self._stats['PINGS_ACKD'], self._stats['NUM_OUTSTANDING']) self._stats['PINGS_SENT'] += 1 - self._logger.debug('(%s) RPTPING Sent to Master. Pings Since Connected: %s', self._system, self._stats['PINGS_SENT']) + self._stats['PING_OUTSTANDING'] = True def send_clients(self, _packet): for _client in self._clients: @@ -230,7 +235,7 @@ class HBSYSTEM(DatagramProtocol): for _client in self._clients: if _client != _radio_id: self.send_client(_client, _data) - self._logger.debug('(%s) Packet on TS%s from %s (%s) for destination ID %s repeated to client: %s (%s) [Stream ID: %s]', self._system, _slot, self._clients[_radio_id]['CALLSIGN'], int_id(_radio_id), int_id(_dst_id), self._clients[_client]['CALLSIGN'], int_id(_client), int_id(_stream_id)) + #self._logger.debug('(%s) Packet on TS%s from %s (%s) for destination ID %s repeated to client: %s (%s) [Stream ID: %s]', self._system, _slot, self._clients[_radio_id]['CALLSIGN'], int_id(_radio_id), int_id(_dst_id), self._clients[_client]['CALLSIGN'], int_id(_client), int_id(_stream_id)) # Userland actions -- typically this is the function you subclass for an application self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data) @@ -381,14 +386,14 @@ class HBSYSTEM(DatagramProtocol): self.dmrd_received(_radio_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data) elif _command == 'MSTN': # Actually MSTNAK -- a NACK from the master - _radio_id = _data[4:8] + _radio_id = _data[6:10] if _radio_id == self._config['RADIO_ID']: # Validate the source and intended target - self._logger.warning('(%s) MSTNAK Received', self._system) + self._logger.warning('(%s) MSTNAK Received. Resetting connection to the Master.', self._system) self._stats['CONNECTION'] = 'NO' # Disconnect ourselves and re-register elif _command == 'RPTA': # Actually RPTACK -- an ACK from the master # Depending on the state, an RPTACK means different things, in each clause, we check and/or set the state - if self._stats['CONNECTION'] == 'RTPL_SENT': # If we've sent a login request... + if self._stats['CONNECTION'] == 'RPTL_SENT': # If we've sent a login request... _login_int32 = _data[6:10] self._logger.info('(%s) Repeater Login ACK Received with 32bit ID: %s', self._system, int_id(_login_int32)) _pass_hash = sha256(_login_int32+self._config['PASSPHRASE']).hexdigest() @@ -447,6 +452,8 @@ class HBSYSTEM(DatagramProtocol): elif _command == 'MSTP': # Actually MSTPONG -- a reply to RPTPING (send by client) if _data [7:11] == self._config['RADIO_ID']: + self._stats['PING_OUTSTANDING'] = False + self._stats['NUM_OUTSTANDING'] = 0 self._stats['PINGS_ACKD'] += 1 self._logger.debug('(%s) MSTPONG Received. Pongs Since Connected: %s', self._system, self._stats['PINGS_ACKD'])