From adfae0d2a885571004bde05c8da6966fbdb83c69 Mon Sep 17 00:00:00 2001
From: Cole Walker <cole.walker@windriver.com>
Date: Tue, 24 Oct 2023 15:29:06 -0400
Subject: [PATCH] Add support for multi-domain phc2sys-ha components

Update the logic in set_utc_offset() to handle the case where ha_phc2sys
is in use and there are multiple ptp4l instances using different domain
numbers.

The process is to check for a user configured ha_domainNumber parameter
in the phc2sys config, if present use that for applicable pmc queries.

If a ha_domainNumber is not defined, check for a global domainNumber in
the phc2sys config and use that.

If neither are specified, use the default domainNumber 0.

Add the 'valid sources' check to ptp-notification v1 for when ha_phc2sys
is in use. Log a warning if ha_phc2sys has no valid sources to select.

Test plan:
Pass: Verify image build and deploy images
Pass: Verify set_utc_offset functionality with ha phc2sys
- Global domainNumber
- Per interface domainNumber
- No domainNumber defined
Pass: Verify set_utc_offset functionality without ha phc2sys
Pass: Verify that v1 ptp-notification logs a warning when ha_phc2sys is
enabled and there are no valid sources.

Story: 2010723
Task: 49010

Signed-off-by: Cole Walker <cole.walker@windriver.com>
Change-Id: Ia8cd15c3711bed45e6d082e322af83f2e4d5cac3
---
 .../common/helpers/os_clock_monitor.py        | 25 ++++++++++++++-----
 .../common/helpers/ptpsync.py                 | 15 ++++++++---
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/notificationservice-base-v2/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/os_clock_monitor.py b/notificationservice-base-v2/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/os_clock_monitor.py
index 3097685..28eed52 100644
--- a/notificationservice-base-v2/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/os_clock_monitor.py
+++ b/notificationservice-base-v2/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/os_clock_monitor.py
@@ -88,7 +88,7 @@ class OsClockMonitor:
                 client_socket.connect(unix_socket)
                 client_socket.send(query.encode())
                 response = client_socket.recv(1024)
-                response = response.decode()
+                response = response.decode().strip()
                 if response == "None":
                     response = None
                 return response
@@ -104,11 +104,11 @@ class OsClockMonitor:
                 if hasattr(client_socket, 'close'):
                     client_socket.close()
         else:
-            LOG.warning("No socket path supplied for instance %s" % self.instance_name)
+            LOG.warning("No socket path supplied for instance %s" % self.phc2sys_instance)
             return None
 
     def set_phc2sys_ha_interface_and_phc(self):
-        update_phc_interface = self.query_phc2sys_socket('clock source', self.phc2sys_com_socket)
+        update_phc_interface = self.query_phc2sys_socket('valid sources', self.phc2sys_com_socket)
         if update_phc_interface is None:
             LOG.info("No PHC device found for HA phc2sys, status is FREERUN.")
             self._state = OsClockState.Freerun
@@ -127,6 +127,8 @@ class OsClockMonitor:
     def set_utc_offset(self, pidfile_path="/var/run/"):
         # Check command line options for offset
         utc_offset = self._get_phc2sys_command_line_option(pidfile_path, '-O')
+        domain_number = None
+        uds_addr = None
 
         # If not, check config file for uds_address and domainNumber
         # If uds_address, get utc_offset from TIME_PROPERTIES_DATA_SET using the phc2sys config
@@ -134,15 +136,26 @@ class OsClockMonitor:
             utc_offset = constants.UTC_OFFSET
             utc_offset_valid = False
 
+            if self.config.has_section(self.phc_interface) \
+                and 'ha_domainNumber' in self.config[self.phc_interface].keys():
+                domain_number = self.config[self.phc_interface].get('ha_domainNumber')
+                LOG.debug("set_utc_offset: ha_domainNumber is %s" % domain_number)
+
             if self.config.has_section('global') \
-                and 'domainNumber' in self.config['global'].keys() \
                 and 'uds_address' in self.config['global'].keys():
+                uds_addr = self.config['global']['uds_address']
+                LOG.debug("set_utc_offset: uds_addr is %s" % uds_addr)
+
+                if domain_number is None:
+                    domain_number = self.config['global'].get('domainNumber', '0')
+                    LOG.debug("set_utc_offset: domainNumber is %s" % domain_number)
+
                 #
                 # sudo /usr/sbin/pmc -u -b 0 'GET TIME_PROPERTIES_DATA_SET'
                 #
                 data = subprocess.check_output(
-                    [PLUGIN_STATUS_QUERY_EXEC, '-f', self.phc2sys_config, '-u', '-b', '0',
-                    'GET TIME_PROPERTIES_DATA_SET']).decode()
+                    [PLUGIN_STATUS_QUERY_EXEC, '-f', self.phc2sys_config, '-u', '-b', '0', '-d',
+                     domain_number, 'GET TIME_PROPERTIES_DATA_SET']).decode()
 
                 for line in data.split('\n'):
                     if 'currentUtcOffset ' in line:
diff --git a/notificationservice-base/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/ptpsync.py b/notificationservice-base/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/ptpsync.py
index 78c2932..6e3a8ff 100644
--- a/notificationservice-base/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/ptpsync.py
+++ b/notificationservice-base/docker/ptptrackingfunction/trackingfunctionsdk/common/helpers/ptpsync.py
@@ -21,9 +21,12 @@ import subprocess
 import datetime
 import logging
 from trackingfunctionsdk.common.helpers import constants
+from trackingfunctionsdk.common.helpers import log_helper
 
 
 LOG = logging.getLogger(__name__)
+log_helper.config_logger(LOG)
+
 
 
 # dictionary includes PMC commands used and keywords of intrest
@@ -83,18 +86,20 @@ def check_critical_resources():
         # User enabled phc2sys HA source clock validation
         phc2sys_source_clock = check_phc2sys_ha_source()
         if phc2sys_source_clock is None:
-            phc2sys = False
-            LOG.warning("No Phc2sys HA source clock found")
+            # Log that phc2sys has no sources, but allow state checking to proceed
+            LOG.info("HA phc2sys has no valid sources to select")
+        else:
+            LOG.info("HA phc2sys has valid sources: %s" % phc2sys_source_clock)
     return pmc, ptp4l, phc2sys, ptp4lconf
 
 def check_phc2sys_ha_source():
-    query = 'clock source'
+    query = 'valid sources'
     try:
         client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
         client_socket.connect(phc2sys_com_socket)
         client_socket.send(query.encode())
         response = client_socket.recv(1024)
-        response = response.decode()
+        response = response.decode().strip()
         if response == "None":
             response = None
         return response
@@ -222,6 +227,8 @@ def ptp_status(holdover_time, freq, sync_state, event_time):
         result, total_ptp_keywords, port_count = ptpsync()
         sync_state = check_results(result, total_ptp_keywords, port_count)
     else:
+        LOG.warning("Critical resources not available: pmc %s ptp4l %s phc2sys %s ptp4lconf %s" %
+                    (pmc, ptp4l, phc2sys, ptp4lconf))
         sync_state = constants.FREERUN_PHC_STATE
     # determine if transition into holdover mode (cannot be in holdover if system clock is not in sync)
     if sync_state == constants.FREERUN_PHC_STATE and phc2sys: