Fix bad GNSS status reported by PTP tracker
A "FAILURE-NOFIX" GNSS status was being reported because the new ICE driver reports "locked_ho_acq" status instead of "locked_ho_ack" as before. Now the logic takes both variations into account to decide upon the GNSS status. BONUS: Found an issue (bad indentation with subsequent logic error) with the threading lockers for ptp4l and ts2phc handlers in the sidecar (notificationclient), that could lead to an exception. Test Plan: PASS: Checked with synchronized GNSS status. Closes-Bug: #1996179 Signed-off-by: Douglas Henrique Koerich <douglashenrique.koerich@windriver.com> Change-Id: I1ad3c4c9ad9e1428685bf6729c77ba29b470ece3
This commit is contained in:
parent
db31ab00ba
commit
3a365e737a
@ -32,6 +32,7 @@ CLOCK_CLASS_VALUE6 = "6"
|
||||
NMEA_SERIALPORT = "ts2phc.nmea_serialport"
|
||||
GNSS_PIN = "GNSS-1PPS"
|
||||
GNSS_LOCKED_HO_ACK = 'locked_ho_ack'
|
||||
GNSS_LOCKED_HO_ACQ = 'locked_ho_acq'
|
||||
GNSS_DPLL_0 = "DPLL0"
|
||||
GNSS_DPLL_1 = "DPLL1"
|
||||
|
||||
|
@ -68,11 +68,15 @@ class GnssMonitor(Observer):
|
||||
}
|
||||
|
||||
# Initialize status
|
||||
if self.gnss_cgu_handler.cgu_output_parsed['EEC DPLL']['Current reference'] == 'GNSS-1PPS':
|
||||
self.gnss_eec_state = self.gnss_cgu_handler.cgu_output_parsed['EEC DPLL']['Status']
|
||||
if self.gnss_cgu_handler.cgu_output_parsed[
|
||||
'EEC DPLL']['Current reference'] == 'GNSS-1PPS':
|
||||
self.gnss_eec_state = \
|
||||
self.gnss_cgu_handler.cgu_output_parsed['EEC DPLL']['Status']
|
||||
|
||||
if self.gnss_cgu_handler.cgu_output_parsed['PPS DPLL']['Current reference'] == 'GNSS-1PPS':
|
||||
self.gnss_pps_state = self.gnss_cgu_handler.cgu_output_parsed['PPS DPLL']['Status']
|
||||
if self.gnss_cgu_handler.cgu_output_parsed[
|
||||
'PPS DPLL']['Current reference'] == 'GNSS-1PPS':
|
||||
self.gnss_pps_state = \
|
||||
self.gnss_cgu_handler.cgu_output_parsed['PPS DPLL']['Status']
|
||||
|
||||
def update(self, subject, matched_line) -> None:
|
||||
LOG.info("Kernel event detected. %s" % matched_line)
|
||||
@ -92,11 +96,16 @@ class GnssMonitor(Observer):
|
||||
self.gnss_cgu_handler.cgu_output_to_dict()
|
||||
self.gnss_eec_state = self.gnss_eec_state = \
|
||||
self.gnss_cgu_handler.cgu_output_parsed['EEC DPLL']['Status']
|
||||
self.gnss_pps_state = self.gnss_cgu_handler.cgu_output_parsed['PPS DPLL']['Status']
|
||||
self.gnss_pps_state = \
|
||||
self.gnss_cgu_handler.cgu_output_parsed['PPS DPLL']['Status']
|
||||
LOG.debug("GNSS EEC Status is: %s" % self.gnss_eec_state)
|
||||
LOG.debug("GNSS PPS Status is: %s" % self.gnss_pps_state)
|
||||
if self.gnss_pps_state == 'locked_ho_ack' and \
|
||||
self.gnss_eec_state == 'locked_ho_ack':
|
||||
if self.gnss_pps_state in [
|
||||
constants.GNSS_LOCKED_HO_ACK,
|
||||
constants.GNSS_LOCKED_HO_ACQ] and \
|
||||
self.gnss_eec_state in [
|
||||
constants.GNSS_LOCKED_HO_ACK,
|
||||
constants.GNSS_LOCKED_HO_ACQ]:
|
||||
self._state = GnssState.Synchronized
|
||||
else:
|
||||
self._state = GnssState.Failure_Nofix
|
||||
|
@ -33,23 +33,32 @@ THIS_NODE_NAME = os.environ.get("THIS_NODE_NAME", 'controller-0')
|
||||
|
||||
# Event source to event type mapping
|
||||
source_type = {
|
||||
'/sync/gnss-status/gnss-sync-status': 'event.sync.gnss-status.gnss-state-change',
|
||||
'/sync/ptp-status/clock-class': 'event.sync.ptp-status.ptp-clock-class-change',
|
||||
'/sync/ptp-status/lock-state': 'event.sync.ptp-status.ptp-state-change',
|
||||
'/sync/sync-status/os-clock-sync-state': 'event.sync.sync-status.os-clock-sync-state-change',
|
||||
'/sync/sync-status/sync-state': 'event.sync.sync-status.synchronization-state-change',
|
||||
'/sync/synce-status/clock-quality': 'event.sync.synce-status.synce-clock-quality-change',
|
||||
'/sync/synce-status/lock-state-extended': 'event.sync.synce-status.synce-state-change-extended',
|
||||
'/sync/synce-status/lock-state': 'event.sync.synce-status.synce-state-change',
|
||||
'/sync/gnss-status/gnss-sync-status':
|
||||
'event.sync.gnss-status.gnss-state-change',
|
||||
'/sync/ptp-status/clock-class':
|
||||
'event.sync.ptp-status.ptp-clock-class-change',
|
||||
'/sync/ptp-status/lock-state':
|
||||
'event.sync.ptp-status.ptp-state-change',
|
||||
'/sync/sync-status/os-clock-sync-state':
|
||||
'event.sync.sync-status.os-clock-sync-state-change',
|
||||
'/sync/sync-status/sync-state':
|
||||
'event.sync.sync-status.synchronization-state-change',
|
||||
'/sync/synce-status/clock-quality':
|
||||
'event.sync.synce-status.synce-clock-quality-change',
|
||||
'/sync/synce-status/lock-state-extended':
|
||||
'event.sync.synce-status.synce-state-change-extended',
|
||||
'/sync/synce-status/lock-state':
|
||||
'event.sync.synce-status.synce-state-change',
|
||||
}
|
||||
|
||||
'''Entry point of Default Process Worker'''
|
||||
|
||||
|
||||
def ProcessWorkerDefault(event, sqlalchemy_conf_json, broker_transport_endpoint):
|
||||
worker = PtpWatcherDefault(event, sqlalchemy_conf_json, broker_transport_endpoint)
|
||||
def ProcessWorkerDefault(event, sqlalchemy_conf_json,
|
||||
broker_transport_endpoint):
|
||||
worker = PtpWatcherDefault(event, sqlalchemy_conf_json,
|
||||
broker_transport_endpoint)
|
||||
worker.run()
|
||||
return
|
||||
|
||||
|
||||
class PtpWatcherDefault:
|
||||
@ -79,8 +88,9 @@ class PtpWatcherDefault:
|
||||
self.init_time = time.time()
|
||||
self.daemon_context = daemon_context
|
||||
|
||||
def _build_event_response(self, resource_path, last_event_time, resource_address,
|
||||
sync_state, value_type=constants.VALUE_TYPE_ENUMERATION):
|
||||
def _build_event_response(
|
||||
self, resource_path, last_event_time, resource_address,
|
||||
sync_state, value_type=constants.VALUE_TYPE_ENUMERATION):
|
||||
if resource_path in [constants.SOURCE_SYNC_PTP_CLOCK_CLASS,
|
||||
constants.SOURCE_SYNCE_CLOCK_QUALITY]:
|
||||
data_type = constants.DATA_TYPE_METRIC
|
||||
@ -111,123 +121,123 @@ class PtpWatcherDefault:
|
||||
resource_address = rpc_kwargs.get('ResourceAddress', None)
|
||||
optional = rpc_kwargs.get('optional', None)
|
||||
if resource_address:
|
||||
_, nodename, resource_path = utils.parse_resource_address(resource_address)
|
||||
_, nodename, resource_path = utils.parse_resource_address(
|
||||
resource_address)
|
||||
if resource_path == constants.SOURCE_SYNC_ALL:
|
||||
resource_path = constants.SOURCE_SYNC_SYNC_STATE
|
||||
if resource_path == constants.SOURCE_SYNC_GNSS_SYNC_STATUS:
|
||||
self.watcher.gnsstracker_context_lock.acquire()
|
||||
if optional:
|
||||
sync_state = self.watcher.gnsstracker_context[optional]. \
|
||||
get('sync_state', GnssState.Failure_Nofix)
|
||||
last_event_time = self.watcher.gnsstracker_context[optional].get(
|
||||
'last_event_time',
|
||||
time.time())
|
||||
lastStatus[optional] = self._build_event_response(resource_path,
|
||||
last_event_time,
|
||||
resource_address,
|
||||
sync_state)
|
||||
sync_state = \
|
||||
self.watcher.gnsstracker_context[optional].get(
|
||||
'sync_state', GnssState.Failure_Nofix)
|
||||
last_event_time = \
|
||||
self.watcher.gnsstracker_context[optional].get(
|
||||
'last_event_time', time.time())
|
||||
lastStatus[optional] = self._build_event_response(
|
||||
resource_path, last_event_time, resource_address,
|
||||
sync_state)
|
||||
else:
|
||||
for config in self.daemon_context['GNSS_INSTANCES']:
|
||||
sync_state = self.watcher.gnsstracker_context[config] \
|
||||
.get('sync_state', GnssState.Failure_Nofix)
|
||||
last_event_time = self.watcher.gnsstracker_context[config].get(
|
||||
'last_event_time',
|
||||
time.time())
|
||||
lastStatus[config] = self._build_event_response(resource_path,
|
||||
last_event_time,
|
||||
resource_address,
|
||||
sync_state)
|
||||
sync_state = \
|
||||
self.watcher.gnsstracker_context[config].get(
|
||||
'sync_state', GnssState.Failure_Nofix)
|
||||
last_event_time = \
|
||||
self.watcher.gnsstracker_context[config].get(
|
||||
'last_event_time', time.time())
|
||||
lastStatus[config] = self._build_event_response(
|
||||
resource_path, last_event_time,
|
||||
resource_address, sync_state)
|
||||
self.watcher.gnsstracker_context_lock.release()
|
||||
elif resource_path == constants.SOURCE_SYNC_PTP_CLOCK_CLASS:
|
||||
self.watcher.ptptracker_context_lock.acquire()
|
||||
if optional:
|
||||
clock_class = self.watcher.ptptracker_context[optional].get('clock_class',
|
||||
'248')
|
||||
last_clock_class_event_time = self.watcher.ptptracker_context[optional].get(
|
||||
'last_clock_class_event_time',
|
||||
time.time())
|
||||
lastStatus[optional] = \
|
||||
self._build_event_response(resource_path,
|
||||
last_clock_class_event_time,
|
||||
resource_address,
|
||||
clock_class,
|
||||
constants.VALUE_TYPE_METRIC)
|
||||
clock_class = \
|
||||
self.watcher.ptptracker_context[optional].get(
|
||||
'clock_class', '248')
|
||||
last_clock_class_event_time = \
|
||||
self.watcher.ptptracker_context[optional].get(
|
||||
'last_clock_class_event_time', time.time())
|
||||
lastStatus[optional] = self._build_event_response(
|
||||
resource_path, last_clock_class_event_time,
|
||||
resource_address, clock_class,
|
||||
constants.VALUE_TYPE_METRIC)
|
||||
else:
|
||||
for config in self.daemon_context['PTP4L_INSTANCES']:
|
||||
clock_class = self.watcher.ptptracker_context[config].get('clock_class',
|
||||
'248')
|
||||
clock_class = \
|
||||
self.watcher.ptptracker_context[config].get(
|
||||
'clock_class', '248')
|
||||
last_clock_class_event_time = \
|
||||
self.watcher.ptptracker_context[config].get(
|
||||
'last_clock_class_event_time',
|
||||
time.time())
|
||||
lastStatus[config] = \
|
||||
self._build_event_response(resource_path,
|
||||
last_clock_class_event_time,
|
||||
resource_address,
|
||||
clock_class,
|
||||
constants.VALUE_TYPE_METRIC)
|
||||
lastStatus[config] = self._build_event_response(
|
||||
resource_path, last_clock_class_event_time,
|
||||
resource_address, clock_class,
|
||||
constants.VALUE_TYPE_METRIC)
|
||||
self.watcher.ptptracker_context_lock.release()
|
||||
elif resource_path == constants.SOURCE_SYNC_PTP_LOCK_STATE:
|
||||
self.watcher.ptptracker_context_lock.acquire()
|
||||
if optional:
|
||||
sync_state = self.watcher.ptptracker_context[optional].get('sync_state',
|
||||
PtpState.Freerun)
|
||||
last_event_time = self.watcher.ptptracker_context[optional].get(
|
||||
'last_event_time',
|
||||
time.time())
|
||||
lastStatus[optional] = self._build_event_response(resource_path,
|
||||
last_event_time,
|
||||
resource_address,
|
||||
sync_state)
|
||||
sync_state = \
|
||||
self.watcher.ptptracker_context[optional].get(
|
||||
'sync_state', PtpState.Freerun)
|
||||
last_event_time = \
|
||||
self.watcher.ptptracker_context[optional].get(
|
||||
'last_event_time', time.time())
|
||||
lastStatus[optional] = self._build_event_response(
|
||||
resource_path, last_event_time, resource_address,
|
||||
sync_state)
|
||||
else:
|
||||
for config in self.daemon_context['PTP4L_INSTANCES']:
|
||||
sync_state = \
|
||||
self.watcher.ptptracker_context[config].get('sync_state',
|
||||
PtpState.Freerun)
|
||||
last_event_time = self.watcher.ptptracker_context[config].get(
|
||||
'last_event_time',
|
||||
time.time())
|
||||
lastStatus[config] = self._build_event_response(resource_path,
|
||||
last_event_time,
|
||||
resource_address,
|
||||
sync_state)
|
||||
self.watcher.ptptracker_context[config].get(
|
||||
'sync_state', PtpState.Freerun)
|
||||
last_event_time = \
|
||||
self.watcher.ptptracker_context[config].get(
|
||||
'last_event_time', time.time())
|
||||
lastStatus[config] = self._build_event_response(
|
||||
resource_path, last_event_time,
|
||||
resource_address, sync_state)
|
||||
self.watcher.ptptracker_context_lock.release()
|
||||
|
||||
elif resource_path == constants.SOURCE_SYNC_OS_CLOCK:
|
||||
self.watcher.osclocktracker_context_lock.acquire()
|
||||
sync_state = self.watcher.osclocktracker_context.get('sync_state',
|
||||
OsClockState.Freerun)
|
||||
last_event_time = self.watcher.osclocktracker_context.get('last_event_time',
|
||||
time.time())
|
||||
sync_state = \
|
||||
self.watcher.osclocktracker_context.get(
|
||||
'sync_state', OsClockState.Freerun)
|
||||
last_event_time = \
|
||||
self.watcher.osclocktracker_context.get(
|
||||
'last_event_time', time.time())
|
||||
self.watcher.osclocktracker_context_lock.release()
|
||||
lastStatus['os_clock_status'] = self._build_event_response(resource_path,
|
||||
last_event_time,
|
||||
resource_address,
|
||||
sync_state)
|
||||
lastStatus['os_clock_status'] = self._build_event_response(
|
||||
resource_path, last_event_time, resource_address,
|
||||
sync_state)
|
||||
elif resource_path == constants.SOURCE_SYNC_SYNC_STATE:
|
||||
self.watcher.overalltracker_context_lock.acquire()
|
||||
sync_state = self.watcher.overalltracker_context.get('sync_state',
|
||||
OverallClockState.Freerun)
|
||||
last_event_time = self.watcher.overalltracker_context.get('last_event_time',
|
||||
time.time())
|
||||
sync_state = self.watcher.overalltracker_context.get(
|
||||
'sync_state', OverallClockState.Freerun)
|
||||
last_event_time = self.watcher.overalltracker_context.get(
|
||||
'last_event_time', time.time())
|
||||
self.watcher.overalltracker_context_lock.release()
|
||||
lastStatus['overall_sync_status'] = self._build_event_response(resource_path,
|
||||
last_event_time,
|
||||
resource_address,
|
||||
sync_state)
|
||||
lastStatus['overall_sync_status'] = \
|
||||
self._build_event_response(
|
||||
resource_path, last_event_time, resource_address,
|
||||
sync_state)
|
||||
LOG.debug("query_status: {}".format(lastStatus))
|
||||
else:
|
||||
# Request is for PTP v1 notification
|
||||
# PTP v1 only supports single instance ptp
|
||||
instance = self.daemon_context['PTP4L_INSTANCES'][0]
|
||||
if len(self.daemon_context['PTP4L_INSTANCES']) > 1:
|
||||
LOG.warning(
|
||||
"Multiple ptp4l instances configured, retrieving status for %s" % instance)
|
||||
LOG.warning("Multiple ptp4l instances configured, "
|
||||
"retrieving status for %s" % instance)
|
||||
self.watcher.ptptracker_context_lock.acquire()
|
||||
sync_state = self.watcher.ptptracker_context[instance].get('sync_state',
|
||||
PtpState.Freerun)
|
||||
last_event_time = self.watcher.ptptracker_context[instance].get('last_event_time',
|
||||
time.time())
|
||||
sync_state = self.watcher.ptptracker_context[instance].get(
|
||||
'sync_state', PtpState.Freerun)
|
||||
last_event_time = \
|
||||
self.watcher.ptptracker_context[instance].get(
|
||||
'last_event_time', time.time())
|
||||
lastStatus[constants.PTP_V1_KEY] = {
|
||||
'ResourceType': ResourceType.TypePTP,
|
||||
'EventData': {
|
||||
@ -246,7 +256,6 @@ class PtpWatcherDefault:
|
||||
def trigger_delivery(self, **rpc_kwargs):
|
||||
self.watcher.forced_publishing = True
|
||||
self.watcher.signal_ptp_event()
|
||||
pass
|
||||
|
||||
def __init__(self, event, sqlalchemy_conf_json, daemon_context_json):
|
||||
self.sqlalchemy_conf = json.loads(sqlalchemy_conf_json)
|
||||
@ -258,92 +267,109 @@ class PtpWatcherDefault:
|
||||
# PTP Context
|
||||
self.ptptracker_context = {}
|
||||
for config in self.daemon_context['PTP4L_INSTANCES']:
|
||||
self.ptptracker_context[config] = PtpWatcherDefault.DEFAULT_PTPTRACKER_CONTEXT.copy()
|
||||
self.ptptracker_context[config] = \
|
||||
PtpWatcherDefault.DEFAULT_PTPTRACKER_CONTEXT.copy()
|
||||
self.ptptracker_context[config]['sync_state'] = PtpState.Freerun
|
||||
self.ptptracker_context[config]['last_event_time'] = self.init_time
|
||||
self.ptptracker_context[config]['holdover_seconds'] = os.environ.get("PTP_HOLDOVER_SECONDS", 30)
|
||||
self.ptptracker_context[config]['poll_freq_seconds'] = os.environ.get(
|
||||
"CONTROL_TIMEOUT", 2)
|
||||
self.ptp_device_simulated = "true" == self.ptptracker_context[config].get(
|
||||
'device_simulated',
|
||||
"False")
|
||||
self.ptptracker_context_lock = threading.Lock()
|
||||
self.ptptracker_context[config]['holdover_seconds'] = \
|
||||
os.environ.get("PTP_HOLDOVER_SECONDS", 30)
|
||||
self.ptptracker_context[config]['poll_freq_seconds'] = \
|
||||
os.environ.get("CONTROL_TIMEOUT", 2)
|
||||
self.ptp_device_simulated = \
|
||||
"true" == self.ptptracker_context[config].get(
|
||||
'device_simulated', "False")
|
||||
self.ptptracker_context_lock = threading.Lock()
|
||||
LOG.debug("ptptracker_context: %s" % self.ptptracker_context)
|
||||
|
||||
# GNSS Context
|
||||
self.gnsstracker_context = {}
|
||||
for config in self.daemon_context['GNSS_INSTANCES']:
|
||||
self.gnsstracker_context[config] = PtpWatcherDefault.DEFAULT_GNSSTRACKER_CONTEXT.copy()
|
||||
self.gnsstracker_context[config]['sync_state'] = GnssState.Failure_Nofix
|
||||
self.gnsstracker_context[config]['last_event_time'] = self.init_time
|
||||
self.gnsstracker_context[config]['holdover_seconds'] = os.environ.get("GNSS_HOLDOVER_SECONDS", 30)
|
||||
self.gnsstracker_context[config]['poll_freq_seconds'] = os.environ.get(
|
||||
"CONTROL_TIMEOUT", 2)
|
||||
self.gnsstracker_context_lock = threading.Lock()
|
||||
self.gnsstracker_context[config] = \
|
||||
PtpWatcherDefault.DEFAULT_GNSSTRACKER_CONTEXT.copy()
|
||||
self.gnsstracker_context[config]['sync_state'] = \
|
||||
GnssState.Failure_Nofix
|
||||
self.gnsstracker_context[config]['last_event_time'] = \
|
||||
self.init_time
|
||||
self.gnsstracker_context[config]['holdover_seconds'] = \
|
||||
os.environ.get("GNSS_HOLDOVER_SECONDS", 30)
|
||||
self.gnsstracker_context[config]['poll_freq_seconds'] = \
|
||||
os.environ.get("CONTROL_TIMEOUT", 2)
|
||||
self.gnsstracker_context_lock = threading.Lock()
|
||||
LOG.debug("gnsstracker_context: %s" % self.gnsstracker_context)
|
||||
|
||||
# OS Clock Context
|
||||
self.osclocktracker_context = {}
|
||||
self.osclocktracker_context = PtpWatcherDefault.DEFAULT_OS_CLOCK_TRACKER_CONTEXT.copy()
|
||||
self.osclocktracker_context = \
|
||||
PtpWatcherDefault.DEFAULT_OS_CLOCK_TRACKER_CONTEXT.copy()
|
||||
self.osclocktracker_context['sync_state'] = OsClockState.Freerun
|
||||
self.osclocktracker_context['last_event_time'] = self.init_time
|
||||
self.osclocktracker_context['holdover_seconds'] = os.environ.get("OS_CLOCK_HOLDOVER_SECONDS", 30)
|
||||
self.osclocktracker_context['poll_freq_seconds'] = os.environ.get(
|
||||
"CONTROL_TIMEOUT", 2)
|
||||
self.osclocktracker_context['holdover_seconds'] = \
|
||||
os.environ.get("OS_CLOCK_HOLDOVER_SECONDS", 30)
|
||||
self.osclocktracker_context['poll_freq_seconds'] = \
|
||||
os.environ.get("CONTROL_TIMEOUT", 2)
|
||||
self.osclocktracker_context_lock = threading.Lock()
|
||||
|
||||
# Overall Sync Context
|
||||
self.overalltracker_context = {}
|
||||
self.overalltracker_context = PtpWatcherDefault.DEFAULT_OVERALL_SYNC_TRACKER_CONTEXT.copy()
|
||||
self.overalltracker_context = \
|
||||
PtpWatcherDefault.DEFAULT_OVERALL_SYNC_TRACKER_CONTEXT.copy()
|
||||
self.overalltracker_context['sync_state'] = OverallClockState.Freerun
|
||||
self.overalltracker_context['last_event_time'] = self.init_time
|
||||
self.overalltracker_context['holdover_seconds'] = os.environ.get("OVERALL_HOLDOVER_SECONDS", 30)
|
||||
self.overalltracker_context['poll_freq_seconds'] = os.environ.get(
|
||||
"CONTROL_TIMEOUT", 2)
|
||||
self.overalltracker_context['holdover_seconds'] = \
|
||||
os.environ.get("OVERALL_HOLDOVER_SECONDS", 30)
|
||||
self.overalltracker_context['poll_freq_seconds'] = \
|
||||
os.environ.get("CONTROL_TIMEOUT", 2)
|
||||
self.overalltracker_context_lock = threading.Lock()
|
||||
|
||||
self.event_timeout = float(os.environ.get('CONTROL_TIMEOUT', 2))
|
||||
|
||||
self.node_name = self.daemon_context['THIS_NODE_NAME']
|
||||
|
||||
self.namespace = self.daemon_context.get('THIS_NAMESPACE', 'notification')
|
||||
self.namespace = self.daemon_context.get(
|
||||
'THIS_NAMESPACE', 'notification')
|
||||
|
||||
broker_transport_endpoint = self.daemon_context['NOTIFICATION_TRANSPORT_ENDPOINT']
|
||||
broker_transport_endpoint = \
|
||||
self.daemon_context['NOTIFICATION_TRANSPORT_ENDPOINT']
|
||||
|
||||
registration_transport_endpoint = self.daemon_context['REGISTRATION_TRANSPORT_ENDPOINT']
|
||||
registration_transport_endpoint = \
|
||||
self.daemon_context['REGISTRATION_TRANSPORT_ENDPOINT']
|
||||
|
||||
self.broker_endpoint = RpcEndpointInfo(broker_transport_endpoint)
|
||||
self.registration_broker_endpoint = RpcEndpointInfo(registration_transport_endpoint)
|
||||
self.registration_broker_endpoint = \
|
||||
RpcEndpointInfo(registration_transport_endpoint)
|
||||
self.ptpeventproducer = PtpEventProducer(
|
||||
self.node_name,
|
||||
self.broker_endpoint.TransportEndpoint,
|
||||
self.registration_broker_endpoint.TransportEndpoint)
|
||||
|
||||
self.__ptprequest_handler = PtpWatcherDefault.PtpRequestHandlerDefault(self,
|
||||
self.daemon_context)
|
||||
self.__ptprequest_handler = \
|
||||
PtpWatcherDefault.PtpRequestHandlerDefault(
|
||||
self, self.daemon_context)
|
||||
|
||||
# Set forced_publishing to True so that initial states are published
|
||||
# Main loop in run() sets it to false after the first iteration
|
||||
self.forced_publishing = True
|
||||
|
||||
self.observer_list = [GnssMonitor(i) for i in self.daemon_context['GNSS_CONFIGS']]
|
||||
self.observer_list = [
|
||||
GnssMonitor(i) for i in self.daemon_context['GNSS_CONFIGS']]
|
||||
|
||||
# Setup OS Clock monitor
|
||||
self.os_clock_monitor = OsClockMonitor(phc2sys_config=self.daemon_context['PHC2SYS_CONFIG'])
|
||||
self.os_clock_monitor = OsClockMonitor(
|
||||
phc2sys_config=self.daemon_context['PHC2SYS_CONFIG'])
|
||||
|
||||
# Setup PTP Monitor(s)
|
||||
self.ptp_monitor_list = [
|
||||
PtpMonitor(config, self.ptptracker_context[config]['holdover_seconds'],
|
||||
PtpMonitor(config,
|
||||
self.ptptracker_context[config]['holdover_seconds'],
|
||||
self.ptptracker_context[config]['poll_freq_seconds'],
|
||||
self.daemon_context['PHC2SYS_SERVICE_NAME']) for config in
|
||||
self.daemon_context['PTP4L_INSTANCES']]
|
||||
self.daemon_context['PHC2SYS_SERVICE_NAME'])
|
||||
for config in self.daemon_context['PTP4L_INSTANCES']]
|
||||
|
||||
def signal_ptp_event(self):
|
||||
if self.event:
|
||||
self.event.set()
|
||||
else:
|
||||
LOG.warning("Unable to assert ptp event")
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
# start location listener
|
||||
@ -364,7 +390,6 @@ class PtpWatcherDefault:
|
||||
self.event.clear()
|
||||
else:
|
||||
LOG.debug("daemon control event is timeout")
|
||||
pass
|
||||
continue
|
||||
self.__stop_listener()
|
||||
|
||||
@ -376,27 +401,29 @@ class PtpWatcherDefault:
|
||||
self.ptpeventproducer.start_status_listener(
|
||||
self.__ptprequest_handler
|
||||
)
|
||||
return
|
||||
|
||||
def __stop_listener(self):
|
||||
LOG.debug("stop listener to answer location querying")
|
||||
|
||||
self.ptpeventproducer.stop_status_listener(self.location_info)
|
||||
return
|
||||
|
||||
def __get_gnss_status(self, holdover_time, freq, sync_state, last_event_time, gnss_monitor):
|
||||
def __get_gnss_status(self, holdover_time, freq, sync_state,
|
||||
last_event_time, gnss_monitor):
|
||||
new_event, sync_state, new_event_time = gnss_monitor.get_gnss_status(
|
||||
holdover_time, freq, sync_state, last_event_time)
|
||||
LOG.debug("Getting GNSS status.")
|
||||
return new_event, sync_state, new_event_time
|
||||
|
||||
def __get_os_clock_status(self, holdover_time, freq, sync_state, last_event_time):
|
||||
new_event, sync_state, new_event_time = self.os_clock_monitor.os_clock_status(
|
||||
holdover_time, freq, sync_state, last_event_time)
|
||||
def __get_os_clock_status(self, holdover_time, freq, sync_state,
|
||||
last_event_time):
|
||||
new_event, sync_state, new_event_time = \
|
||||
self.os_clock_monitor.os_clock_status(
|
||||
holdover_time, freq, sync_state, last_event_time)
|
||||
LOG.debug("Getting os clock status.")
|
||||
return new_event, sync_state, new_event_time
|
||||
|
||||
def __get_overall_sync_state(self, holdover_time, freq, sync_state, last_event_time):
|
||||
def __get_overall_sync_state(self, holdover_time, freq, sync_state,
|
||||
last_event_time):
|
||||
new_event = False
|
||||
new_event_time = last_event_time
|
||||
previous_sync_state = sync_state
|
||||
@ -411,36 +438,44 @@ class PtpWatcherDefault:
|
||||
|
||||
LOG.debug("Getting overall sync state.")
|
||||
for gnss in self.observer_list:
|
||||
if gnss._state == constants.UNKNOWN_PHC_STATE or gnss._state == GnssState.Failure_Nofix:
|
||||
if gnss._state == constants.UNKNOWN_PHC_STATE or \
|
||||
gnss._state == GnssState.Failure_Nofix:
|
||||
gnss_state = GnssState.Failure_Nofix
|
||||
elif gnss._state == GnssState.Synchronized and gnss_state != GnssState.Failure_Nofix:
|
||||
elif gnss._state == GnssState.Synchronized and \
|
||||
gnss_state != GnssState.Failure_Nofix:
|
||||
gnss_state = GnssState.Synchronized
|
||||
|
||||
for ptp4l in self.ptp_monitor_list:
|
||||
_, read_state, _ = ptp4l.get_ptp_sync_state()
|
||||
if read_state == PtpState.Holdover or read_state == PtpState.Freerun or \
|
||||
if read_state == PtpState.Holdover or \
|
||||
read_state == PtpState.Freerun or \
|
||||
read_state == constants.UNKNOWN_PHC_STATE:
|
||||
ptp_state = PtpState.Freerun
|
||||
elif read_state == PtpState.Locked and ptp_state != PtpState.Freerun:
|
||||
elif read_state == PtpState.Locked and \
|
||||
ptp_state != PtpState.Freerun:
|
||||
ptp_state = PtpState.Locked
|
||||
|
||||
os_clock_state = self.os_clock_monitor.get_os_clock_state()
|
||||
|
||||
if gnss_state is GnssState.Failure_Nofix or os_clock_state is OsClockState.Freerun or \
|
||||
if gnss_state is GnssState.Failure_Nofix or \
|
||||
os_clock_state is OsClockState.Freerun or \
|
||||
ptp_state is PtpState.Freerun:
|
||||
sync_state = OverallClockState.Freerun
|
||||
else:
|
||||
sync_state = OverallClockState.Locked
|
||||
|
||||
if sync_state == OverallClockState.Freerun:
|
||||
if previous_sync_state in [constants.UNKNOWN_PHC_STATE, constants.FREERUN_PHC_STATE]:
|
||||
if previous_sync_state in [
|
||||
constants.UNKNOWN_PHC_STATE,
|
||||
constants.FREERUN_PHC_STATE]:
|
||||
sync_state = OverallClockState.Freerun
|
||||
elif previous_sync_state == constants.LOCKED_PHC_STATE:
|
||||
sync_state = OverallClockState.Holdover
|
||||
elif previous_sync_state == constants.HOLDOVER_PHC_STATE and \
|
||||
time_in_holdover < max_holdover_time:
|
||||
LOG.debug("Overall sync: Time in holdover is %s Max time in holdover is %s" % (
|
||||
time_in_holdover, max_holdover_time))
|
||||
LOG.debug("Overall sync: Time in holdover is %s "
|
||||
"Max time in holdover is %s"
|
||||
% (time_in_holdover, max_holdover_time))
|
||||
sync_state = OverallClockState.Holdover
|
||||
else:
|
||||
sync_state = OverallClockState.Freerun
|
||||
@ -450,7 +485,8 @@ class PtpWatcherDefault:
|
||||
new_event_time = datetime.datetime.utcnow().timestamp()
|
||||
return new_event, sync_state, new_event_time
|
||||
|
||||
def __get_ptp_status(self, holdover_time, freq, sync_state, last_event_time, ptp_monitor):
|
||||
def __get_ptp_status(self, holdover_time, freq, sync_state,
|
||||
last_event_time, ptp_monitor):
|
||||
new_event = False
|
||||
new_event_time = last_event_time
|
||||
ptp_monitor.set_ptp_sync_state()
|
||||
@ -469,7 +505,8 @@ class PtpWatcherDefault:
|
||||
else:
|
||||
sync_state = PtpState.Freerun
|
||||
else:
|
||||
new_event, sync_state, new_event_time = ptp_monitor.get_ptp_sync_state()
|
||||
new_event, sync_state, new_event_time = \
|
||||
ptp_monitor.get_ptp_sync_state()
|
||||
return new_event, sync_state, new_event_time
|
||||
|
||||
'''announce location'''
|
||||
@ -478,12 +515,14 @@ class PtpWatcherDefault:
|
||||
holdover_time = float(self.osclocktracker_context['holdover_seconds'])
|
||||
freq = float(self.osclocktracker_context['poll_freq_seconds'])
|
||||
sync_state = self.osclocktracker_context.get('sync_state', 'Unknown')
|
||||
last_event_time = self.osclocktracker_context.get('last_event_time', time.time())
|
||||
last_event_time = self.osclocktracker_context.get('last_event_time',
|
||||
time.time())
|
||||
lastStatus = {}
|
||||
|
||||
new_event, sync_state, new_event_time = self.__get_os_clock_status(
|
||||
holdover_time, freq, sync_state, last_event_time)
|
||||
LOG.info("os_clock_status: state is %s, new_event is %s " % (sync_state, new_event))
|
||||
LOG.info("os_clock_status: state is %s, new_event is %s "
|
||||
% (sync_state, new_event))
|
||||
if new_event or forced:
|
||||
self.osclocktracker_context_lock.acquire()
|
||||
self.osclocktracker_context['sync_state'] = sync_state
|
||||
@ -512,20 +551,23 @@ class PtpWatcherDefault:
|
||||
]
|
||||
}
|
||||
}
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_OS_CLOCK)
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
return
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_OS_CLOCK)
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
|
||||
def __publish_overall_sync_status(self, forced=False):
|
||||
lastStatus = {}
|
||||
holdover_time = float(self.overalltracker_context['holdover_seconds'])
|
||||
freq = float(self.overalltracker_context['poll_freq_seconds'])
|
||||
sync_state = self.overalltracker_context.get('sync_state', 'Unknown')
|
||||
last_event_time = self.overalltracker_context.get('last_event_time', time.time())
|
||||
last_event_time = self.overalltracker_context.get('last_event_time',
|
||||
time.time())
|
||||
|
||||
new_event, sync_state, new_event_time = self.__get_overall_sync_state(
|
||||
holdover_time, freq, sync_state, last_event_time)
|
||||
LOG.info("overall_sync_state: state is %s, new_event is %s " % (sync_state, new_event))
|
||||
LOG.info("overall_sync_state: state is %s, new_event is %s "
|
||||
% (sync_state, new_event))
|
||||
|
||||
if new_event or forced:
|
||||
# Update context
|
||||
@ -555,30 +597,36 @@ class PtpWatcherDefault:
|
||||
]
|
||||
}
|
||||
}
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_SYNC_STATE)
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_SYNC_STATE)
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
|
||||
def __publish_gnss_status(self, forced=False):
|
||||
lastStatus = {}
|
||||
for gnss in self.observer_list:
|
||||
holdover_time = float(
|
||||
self.gnsstracker_context[gnss.ts2phc_service_name]['holdover_seconds'])
|
||||
freq = float(self.gnsstracker_context[gnss.ts2phc_service_name]['poll_freq_seconds'])
|
||||
sync_state = self.gnsstracker_context[gnss.ts2phc_service_name].get('sync_state',
|
||||
'Unknown')
|
||||
last_event_time = self.gnsstracker_context[gnss.ts2phc_service_name].get(
|
||||
'last_event_time',
|
||||
time.time())
|
||||
self.gnsstracker_context[
|
||||
gnss.ts2phc_service_name]['holdover_seconds'])
|
||||
freq = float(self.gnsstracker_context[
|
||||
gnss.ts2phc_service_name]['poll_freq_seconds'])
|
||||
sync_state = \
|
||||
self.gnsstracker_context[gnss.ts2phc_service_name].get(
|
||||
'sync_state', 'Unknown')
|
||||
last_event_time = \
|
||||
self.gnsstracker_context[gnss.ts2phc_service_name].get(
|
||||
'last_event_time', time.time())
|
||||
|
||||
new_event, sync_state, new_event_time = self.__get_gnss_status(
|
||||
holdover_time, freq, sync_state, last_event_time, gnss)
|
||||
LOG.info("%s gnss_status: state is %s, new_event is %s" % (
|
||||
gnss.ts2phc_service_name, sync_state, new_event))
|
||||
LOG.info("%s gnss_status: state is %s, new_event is %s"
|
||||
% (gnss.ts2phc_service_name, sync_state, new_event))
|
||||
|
||||
if new_event or forced:
|
||||
# update context
|
||||
self.gnsstracker_context_lock.acquire()
|
||||
self.gnsstracker_context[gnss.ts2phc_service_name]['sync_state'] = sync_state
|
||||
self.gnsstracker_context[
|
||||
gnss.ts2phc_service_name]['sync_state'] = sync_state
|
||||
self.gnsstracker_context[gnss.ts2phc_service_name][
|
||||
'last_event_time'] = new_event_time
|
||||
self.gnsstracker_context_lock.release()
|
||||
@ -592,7 +640,8 @@ class PtpWatcherDefault:
|
||||
'id': uuidutils.generate_uuid(),
|
||||
'specversion': constants.SPEC_VERSION,
|
||||
'source': constants.SOURCE_SYNC_GNSS_SYNC_STATUS,
|
||||
'type': source_type[constants.SOURCE_SYNC_GNSS_SYNC_STATUS],
|
||||
'type': source_type[
|
||||
constants.SOURCE_SYNC_GNSS_SYNC_STATUS],
|
||||
'time': new_event_time,
|
||||
'data': {
|
||||
'version': constants.DATA_VERSION,
|
||||
@ -606,23 +655,25 @@ class PtpWatcherDefault:
|
||||
]
|
||||
}
|
||||
}
|
||||
self.ptpeventproducer.publish_status(lastStatus,
|
||||
constants.SOURCE_SYNC_GNSS_SYNC_STATUS)
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
return
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_GNSS_SYNC_STATUS)
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
|
||||
def __publish_ptpstatus(self, forced=False):
|
||||
lastStatus = {}
|
||||
lastClockClassStatus = {}
|
||||
for ptp_monitor in self.ptp_monitor_list:
|
||||
holdover_time = \
|
||||
float(self.ptptracker_context[ptp_monitor.ptp4l_service_name]['holdover_seconds'])
|
||||
freq = float(
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name]['poll_freq_seconds'])
|
||||
sync_state = self.ptptracker_context[ptp_monitor.ptp4l_service_name]. \
|
||||
get('sync_state', 'Unknown')
|
||||
last_event_time = self.ptptracker_context[ptp_monitor.ptp4l_service_name] \
|
||||
.get('last_event_time', time.time())
|
||||
holdover_time = float(self.ptptracker_context[
|
||||
ptp_monitor.ptp4l_service_name]['holdover_seconds'])
|
||||
freq = float(self.ptptracker_context[
|
||||
ptp_monitor.ptp4l_service_name]['poll_freq_seconds'])
|
||||
sync_state = \
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name].get(
|
||||
'sync_state', 'Unknown')
|
||||
last_event_time = \
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name].get(
|
||||
'last_event_time', time.time())
|
||||
|
||||
new_event, sync_state, new_event_time = self.__get_ptp_status(
|
||||
holdover_time, freq, sync_state, last_event_time, ptp_monitor)
|
||||
@ -631,12 +682,14 @@ class PtpWatcherDefault:
|
||||
|
||||
new_clock_class_event, clock_class, clock_class_event_time = \
|
||||
ptp_monitor.get_ptp_clock_class()
|
||||
LOG.info("%s PTP clock class: clockClass is %s, new_event is %s" % (
|
||||
ptp_monitor.ptp4l_service_name, clock_class, new_clock_class_event))
|
||||
LOG.info("%s PTP clock class: clockClass is %s, new_event is %s"
|
||||
% (ptp_monitor.ptp4l_service_name, clock_class,
|
||||
new_clock_class_event))
|
||||
if new_event or forced:
|
||||
# update context
|
||||
self.ptptracker_context_lock.acquire()
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name]['sync_state'] = sync_state
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name][
|
||||
'sync_state'] = sync_state
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name][
|
||||
'last_event_time'] = new_event_time
|
||||
|
||||
@ -676,19 +729,20 @@ class PtpWatcherDefault:
|
||||
}
|
||||
}
|
||||
self.ptptracker_context_lock.release()
|
||||
self.ptpeventproducer.publish_status(lastStatus,
|
||||
constants.SOURCE_SYNC_PTP_LOCK_STATE)
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_PTP_LOCK_STATE)
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
|
||||
if new_clock_class_event or forced:
|
||||
# update context
|
||||
self.ptptracker_context_lock.acquire()
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name]['clock_class'] = clock_class
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name][
|
||||
'clock_class'] = clock_class
|
||||
self.ptptracker_context[ptp_monitor.ptp4l_service_name][
|
||||
'last_clock_class_event_time'] \
|
||||
= clock_class_event_time
|
||||
|
||||
|
||||
resource_address = utils.format_resource_address(
|
||||
self.node_name, constants.SOURCE_SYNC_PTP_CLOCK_CLASS)
|
||||
|
||||
@ -711,19 +765,19 @@ class PtpWatcherDefault:
|
||||
}
|
||||
}
|
||||
self.ptptracker_context_lock.release()
|
||||
LOG.info("Publishing clockClass for %s: %s" % (ptp_monitor.ptp4l_service_name,
|
||||
clock_class))
|
||||
self.ptpeventproducer.publish_status(lastClockClassStatus,
|
||||
constants.SOURCE_SYNC_PTP_CLOCK_CLASS)
|
||||
LOG.info("Publishing clockClass for %s: %s"
|
||||
% (ptp_monitor.ptp4l_service_name, clock_class))
|
||||
self.ptpeventproducer.publish_status(
|
||||
lastClockClassStatus,
|
||||
constants.SOURCE_SYNC_PTP_CLOCK_CLASS)
|
||||
self.ptpeventproducer.publish_status(lastClockClassStatus,
|
||||
constants.SOURCE_SYNC_ALL)
|
||||
|
||||
return
|
||||
|
||||
|
||||
class DaemonControl(object):
|
||||
|
||||
def __init__(self, sqlalchemy_conf_json, daemon_context_json, process_worker=None):
|
||||
def __init__(self, sqlalchemy_conf_json, daemon_context_json,
|
||||
process_worker=None):
|
||||
self.event = mp.Event()
|
||||
self.daemon_context = json.loads(daemon_context_json)
|
||||
self.node_name = self.daemon_context['THIS_NODE_NAME']
|
||||
@ -733,8 +787,8 @@ class DaemonControl(object):
|
||||
self.sqlalchemy_conf_json = sqlalchemy_conf_json
|
||||
self.daemon_context_json = daemon_context_json
|
||||
self.process_worker = process_worker
|
||||
return
|
||||
|
||||
def refresh(self):
|
||||
self.process_worker(self.event, self.sqlalchemy_conf_json, self.daemon_context_json)
|
||||
self.process_worker(self.event, self.sqlalchemy_conf_json,
|
||||
self.daemon_context_json)
|
||||
self.event.set()
|
||||
|
Loading…
x
Reference in New Issue
Block a user