diff --git a/clkmgr/Makefile b/clkmgr/Makefile index 478de3c2..bcf1f918 100644 --- a/clkmgr/Makefile +++ b/clkmgr/Makefile @@ -22,7 +22,7 @@ CLKMGR_PROXY:=$(CLKMGR_PROXY_DIR)/clkmgr_proxy CLKMGR_GEN_CPP=$(Q_GEN)$(M4) -I $(CLKMGR_COMMON_DIR) -D lang=cpp $< > $@ CLKMGR_GEN_C=$(Q_GEN)$(M4) -I $(CLKMGR_COMMON_DIR) -D lang=c $< > $@ -CLKMGR_LDLIBS:=$(foreach lib,pthread rt rtpi,-l$(lib)) +CLKMGR_LDLIBS:=$(foreach lib,pthread rt rtpi chrony,-l$(lib)) CLKMGR_CXXFLAGS:=-I$(CLKMGR_DIR) -I$(CLKMGR_PUB_DIR) CLKMGR_COMMON_SRCS:=$(wildcard $(CLKMGR_COMMON_DIR)/*.cpp) diff --git a/clkmgr/client/clockmanager.cpp b/clkmgr/client/clockmanager.cpp index beb8f5bf..c2e077d4 100644 --- a/clkmgr/client/clockmanager.cpp +++ b/clkmgr/client/clockmanager.cpp @@ -213,7 +213,8 @@ int ClockManager::clkmgr_status_wait(int timeout, eventCount.as_capable_event_count || eventCount.synced_to_gm_event_count || eventCount.composite_event_count || - eventCount.gm_changed_event_count) { + eventCount.gm_changed_event_count || + eventCount.chrony_offset_in_range_event_count) { event_changes_detected = true; break; } diff --git a/clkmgr/client/notification_msg.cpp b/clkmgr/client/notification_msg.cpp index 2d92ee16..fd8ed317 100644 --- a/clkmgr/client/notification_msg.cpp +++ b/clkmgr/client/notification_msg.cpp @@ -219,6 +219,33 @@ PROCESS_MESSAGE_TYPE(ClientNotificationMessage::processMessage) client_ptp_data->gm_changed_event_count; clkmgrCurrentEventCount.composite_event_count = client_ptp_data->composite_event_count; + printf("notification: proxy chronyd offset = %ld\n",proxy_data.chrony_offset ); + if(proxy_data.chrony_offset != client_ptp_data->chrony_offset) { + client_ptp_data->chrony_offset = proxy_data.chrony_offset; + if(currentClientState->get_eventSub().in_range(thresholdGMOffset, + client_ptp_data->chrony_offset)) { + if(!(client_ptp_data->chrony_offset_in_range)) { + client_ptp_data->chrony_offset_in_range = true; + client_ptp_data->chrony_offset_in_range_event_count.fetch_add(1, + std::memory_order_relaxed); + } + } else { + if((client_ptp_data->chrony_offset_in_range)) { + client_ptp_data->chrony_offset_in_range = false; + client_ptp_data->chrony_offset_in_range_event_count.fetch_add(1, + std::memory_order_relaxed); + } + } + } + //client_ptp_data->chrony_offset = proxy_data.chrony_offset; + clkmgrCurrentState.chrony_clock_offset = client_ptp_data->chrony_offset; + clkmgrCurrentEventCount.chrony_offset_in_range_event_count = + client_ptp_data->chrony_offset_in_range_event_count; + clkmgrCurrentState.chrony_offset_in_range = + client_ptp_data->chrony_offset_in_range; + client_ptp_data->chrony_reference_id = proxy_data.chrony_reference_id; + clkmgrCurrentState.chrony_reference_id = client_ptp_data->chrony_reference_id; + printf("notification: client chronyd offset = %ld\n",clkmgrCurrentState.chrony_clock_offset); } return true; } diff --git a/clkmgr/client/subscribe_msg.cpp b/clkmgr/client/subscribe_msg.cpp index f4ef6196..7c0a0d7a 100644 --- a/clkmgr/client/subscribe_msg.cpp +++ b/clkmgr/client/subscribe_msg.cpp @@ -143,6 +143,12 @@ PARSE_RXBUFFER_TYPE(ClientSubscribeMessage::parseBuffer) clkmgrCurrentState->notification_timestamp += last_notification_time.tv_nsec; memcpy(clkmgrCurrentState->gm_identity, client_data->gm_identity, sizeof(client_data->gm_identity)); + client_data->chrony_offset = data.chrony_offset; + client_data->chrony_reference_id = data.chrony_reference_id; + //printf("client_data->chrony_offset =%ld, data.chrony_offset = %ld \n",client_data->chrony_offset,data.chrony_offset); + clkmgrCurrentState->chrony_clock_offset = client_data->chrony_offset; + clkmgrCurrentState->chrony_offset_in_range = + client_data->chrony_offset_in_range; return true; } diff --git a/clkmgr/common/ptp_event.hpp b/clkmgr/common/ptp_event.hpp index 9eee7132..69092211 100644 --- a/clkmgr/common/ptp_event.hpp +++ b/clkmgr/common/ptp_event.hpp @@ -25,6 +25,8 @@ struct ptp_event { bool as_capable; /* 802@.1AS Capable */ bool synced_to_primary_clock; uint8_t ptp4l_id; + int64_t chrony_offset; + uint64_t chrony_reference_id; }; struct client_ptp_event { @@ -42,6 +44,10 @@ struct client_ptp_event { std::atomic synced_to_gm_event_count{}; std::atomic gm_changed_event_count{}; std::atomic composite_event_count{}; + int64_t chrony_offset; + uint64_t chrony_reference_id; + bool chrony_offset_in_range; + std::atomic chrony_offset_in_range_event_count{}; }; __CLKMGR_NAMESPACE_END diff --git a/clkmgr/proxy/connect_ptp4l.cpp b/clkmgr/proxy/connect_ptp4l.cpp index 8ae8d384..6928998b 100644 --- a/clkmgr/proxy/connect_ptp4l.cpp +++ b/clkmgr/proxy/connect_ptp4l.cpp @@ -25,6 +25,7 @@ #include #include #include +#include __CLKMGR_NAMESPACE_USE @@ -41,7 +42,11 @@ static SockBase *sk; static std::unique_ptr m_sk; SUBSCRIBE_EVENTS_NP_t d; -ptp_event pe = { 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0}; +ptp_event pe = { 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0}; +chrony_session *s; +int fd; +int report_index = 0; +int polling_interval; void notify_client() { @@ -78,12 +83,12 @@ void event_handle() memcpy(pe.gm_identity, timeStatus->gmIdentity.v, sizeof(pe.gm_identity)); /* Uncomment for debug data printing */ - //printf("master_offset = %ld, synced_to_primary_clock = %d\n", - // pe.master_offset, pe.synced_to_primary_clock); - //printf("gm_identity = %02x%02x%02x.%02x%02x.%02x%02x%02x\n\n", - // pe.gm_identity[0], pe.gm_identity[1],pe.gm_identity[2], - // pe.gm_identity[3], pe.gm_identity[4], - // pe.gm_identity[5], pe.gm_identity[6],pe.gm_identity[7]); + printf("master_offset = %ld, synced_to_primary_clock = %d\n", + pe.master_offset, pe.synced_to_primary_clock); + printf("gm_identity = %02x%02x%02x.%02x%02x.%02x%02x%02x\n\n", + pe.gm_identity[0], pe.gm_identity[1],pe.gm_identity[2], + pe.gm_identity[3], pe.gm_identity[4], + pe.gm_identity[5], pe.gm_identity[6],pe.gm_identity[7]); break; } case PORT_PROPERTIES_NP: /* Get initial port state when Proxy starts */ @@ -200,6 +205,114 @@ bool event_subscription(struct clkmgr_handle **handle) return ret; } +static chrony_err process_chronyd_data(chrony_session *s) +{ + struct pollfd pfd = { .fd = chrony_get_fd(s), .events = POLLIN }; + int n, timeout; + chrony_err r; + timeout = 1000; + while (chrony_needs_response(s)) { + n = poll(&pfd, 1, timeout); + if (n < 0) { + perror("poll"); +// return -1; + } else if (n == 0) { + fprintf(stderr, "No valid response received\n"); +// return -1; + } + r = chrony_process_response(s); + if (r != CHRONY_OK) + return r; + } + return CHRONY_OK; +} + +static int subscribe_to_chronyd(chrony_session *s, int report_index) +{ + chrony_field_content content; + const char *report_name; + chrony_err r; + int i, j; + report_name = chrony_get_report_name(report_index); +// printf("%s:\n", report_name); // report name = tracking or sources + i = 0; + r = chrony_request_record(s, report_name, i); + if (r != CHRONY_OK) + return r; + r = process_chronyd_data(s); + if (r != CHRONY_OK) + return r; + for (j = 0; j < chrony_get_record_number_fields(s); j++) { + content = chrony_get_field_content(s, j); + if (content == CHRONY_CONTENT_NONE) + continue; + const char *field_name = chrony_get_field_name(s, j); + if (field_name != NULL && strcmp(field_name, "Last offset") == 0) { + float second = (chrony_get_field_float(s, j) * 1e9); + pe.chrony_offset = (int)second; + printf("offset (chrony): %ld nanosecond \n\n", pe.chrony_offset); + } + if (field_name != NULL && strcmp(field_name, "Reference ID") == 0) { + pe.chrony_reference_id = chrony_get_field_uinteger(s, j); + printf("Reference ID: %lX\n", pe.chrony_reference_id); + } + if (field_name != NULL && strcmp(field_name, "Poll") == 0) { + polling_interval = chrony_get_field_integer(s, j); + //printf("Poll: %d\n", pe.chrony_poll); + printf("Pollng interval: %ld s\n",polling_interval); + } + } + return CHRONY_OK; +} + + +struct ThreadArgs +{ + chrony_session *s; + int report_index; +}; + +void* monitor_chronyd(void* arg) +{ + ThreadArgs* args = (ThreadArgs*)arg; + chrony_session *s = args->s; + int report_index = args->report_index; + while (true) { + if (chrony_init_session(&s, fd) == CHRONY_OK) { + for (int i = 0; i < 2; i++) { + subscribe_to_chronyd(s, i); + // chrony_deinit_session(s); + } + } + usleep(polling_interval); // Sleep duration is based on chronyd polling interval + } + return NULL; +} + +void start_monitor_thread(chrony_session *s, int report_index) +{ + pthread_t thread_id; + ThreadArgs* args = new ThreadArgs{s, report_index}; + if (pthread_create(&thread_id, NULL, monitor_chronyd, args) != 0) { + fprintf(stderr, "Failed to create thread\n"); + exit(EXIT_FAILURE); + } +} +/* +void* monitor_chronyd(void* arg) { + + while (true) { + if (chrony_init_session(&s, fd) == CHRONY_OK) { + subscribe_to_chronyd(s,report_index); + chrony_deinit_session(s); + } + sleep(1); // Adjust the sleep duration as necessary + } + + return NULL; +} +*/ + /** * @brief Runs the main event loop for handling PTP (Precision Time Protocol) * events. @@ -240,6 +353,10 @@ void *ptp4l_event_loop(void *arg) msg_set_action(false, PORT_PROPERTIES_NP); event_subscription(nullptr); while(1) { + // if (chrony_init_session(&s, fd) == CHRONY_OK) { + // subscribe_to_chronyd(s,report_index); + // chrony_deinit_session(s); + // } if(sk->poll(timeout_ms) > 0) { const auto cnt = sk->rcv(buf, bufSize); if(cnt > 0) { @@ -302,6 +419,16 @@ int Connect::connect(uint8_t transport_specific) prms.transportSpecific = transport_specific; msg.updateParams(prms); sk = m_sk.get(); + + /* connect to chronyd unix socket*/ + fd = chrony_open_socket("/var/run/chrony/chronyd.sock"); + chrony_session *s; + if (chrony_init_session(&s, fd) == CHRONY_OK) { + //subscribe_to_chronyd(s,report_index); + start_monitor_thread(s, report_index); + chrony_deinit_session(s); + } + handle_connect(); return 0; } diff --git a/clkmgr/pub/clkmgr/clockmanager_c.h b/clkmgr/pub/clkmgr/clockmanager_c.h index d5e6fb94..a3e4dbb8 100644 --- a/clkmgr/pub/clkmgr/clockmanager_c.h +++ b/clkmgr/pub/clkmgr/clockmanager_c.h @@ -44,6 +44,8 @@ struct clkmgr_c_event_state { bool gm_changed; /**< Primary clock UUID changed */ bool composite_event; /**< Composite event */ bool reserved[27]; /**< Reserved for future */ + int64_t chrony_clock_offset; /**< Chrony clock offset */ + uint64_t chrony_reference_id; /**< Chrony reference ID */ }; /** diff --git a/clkmgr/pub/clkmgr/event_state.h b/clkmgr/pub/clkmgr/event_state.h index 9f7209bc..fd90eb7e 100644 --- a/clkmgr/pub/clkmgr/event_state.h +++ b/clkmgr/pub/clkmgr/event_state.h @@ -32,6 +32,9 @@ struct clkmgr_event_state { bool gm_changed; /**< Primary clock UUID changed */ bool composite_event; /**< Composite event */ bool reserved[27]; /**< Reserved for future */ + int64_t chrony_clock_offset; /**< Chrony clock offset */ + uint64_t chrony_reference_id; /**< Chrony reference ID */ + bool chrony_offset_in_range; /**< Chrony clock offset in range */ }; /** @@ -45,6 +48,7 @@ struct clkmgr_event_count { uint32_t gm_changed_event_count; /**< Primary clock UUID changed */ uint32_t composite_event_count; /**< Composite event */ uint32_t reserved[27]; /**< Reserved for future */ + uint32_t chrony_offset_in_range_event_count; /**< Chrony clock offset in range */ }; __CLKMGR_NAMESPACE_END diff --git a/clkmgr/sample/clkmgr_c_test.c b/clkmgr/sample/clkmgr_c_test.c index 414168b9..97dae48b 100644 --- a/clkmgr/sample/clkmgr_c_test.c +++ b/clkmgr/sample/clkmgr_c_test.c @@ -203,6 +203,12 @@ int main(int argc, char *argv[]) } else { printf("\n"); } + printf("+---------------------------+------------------------+\n"); + printf("| %-25s | %-19ld ns |\n", + "chrony clock_offset", event_state.chrony_clock_offset); + printf("| %-25s | %-19lX |\n", + "chrony clock_reference_id", event_state.chrony_reference_id); + printf("+---------------------------+------------------------+\n\n"); sleep(1); @@ -277,6 +283,12 @@ int main(int argc, char *argv[]) } else { printf("\n"); } + printf("+---------------------------+----------------------------+\n"); + printf("| %-25s | %-19ld ns |\n", + "chrony clock_offset", event_state.chrony_clock_offset); + printf("| %-25s | %-19lX |\n", + "chrony clock_reference_id", event_state.chrony_reference_id); + printf("+---------------------------+----------------------------+\n\n"); printf("[clkmgr][%.3f] sleep for %d seconds...\n\n", getMonotonicTime(), idle_time); diff --git a/clkmgr/sample/clkmgr_test.cpp b/clkmgr/sample/clkmgr_test.cpp index ec734c81..ff1947d5 100644 --- a/clkmgr/sample/clkmgr_test.cpp +++ b/clkmgr/sample/clkmgr_test.cpp @@ -222,6 +222,15 @@ int main(int argc, char *argv[]) } else { printf("\n"); } + printf("+---------------------------+------------------------+\n"); + printf("| %-25s | %-22d |\n", "chrony offset_in_range", + eventState.chrony_offset_in_range); + printf("+---------------------------+----------------------------+\n"); + printf("| %-25s | %-19ld ns |\n", + "chrony clock_offset", eventState.chrony_clock_offset); + printf("| %-25s | %-19lX |\n", + "chrony clock_reference_id", eventState.chrony_reference_id); + printf("+---------------------------+------------------------+\n\n"); sleep(1); @@ -296,6 +305,15 @@ int main(int argc, char *argv[]) } else { printf("\n"); } + printf("+---------------------------+----------------------------+\n"); + printf("| %-25s | %-12d | %-11d |\n", "chrony offset_in_range", + eventState.chrony_offset_in_range, eventCount.chrony_offset_in_range_event_count); + printf("+---------------------------+----------------------------+\n"); + printf("| %-25s | %-19ld ns |\n", + "chrony clock_offset", eventState.chrony_clock_offset); + printf("| %-25s | %-19lX |\n", + "chrony clock_reference_id", eventState.chrony_reference_id); + printf("+---------------------------+----------------------------+\n\n"); printf("[clkmgr][%.3f] sleep for %d seconds...\n\n", getMonotonicTime(), idleTime);