diff --git a/lib/core/ogs-time.c b/lib/core/ogs-time.c index d6e8b35e34..bb94e6a53a 100644 --- a/lib/core/ogs-time.c +++ b/lib/core/ogs-time.c @@ -167,6 +167,40 @@ int ogs_time_from_gmt(ogs_time_t *t, struct tm *tm, int tm_usec) return status; } +/* RFC 5905 A.1.1, A.4 + * PFCP entity uses NTP timestamp(1900), but Open5GS uses UNIX(1970). + * + * One is the offset between the two epochs. + * Unix uses an epoch located at 1/1/1970-00:00h (UTC) and + * NTP uses 1/1/1900-00:00h. This leads to an offset equivalent + * to 70 years in seconds (there are 17 leap years + * between the two dates so the offset is + * + * (70*365 + 17)*86400 = 2208988800 + * + * to be substracted from NTP time to get Unix struct timeval. + */ +uint32_t ogs_time_ntp32_now(void) +{ + int rc; + struct timeval tv; + + rc = ogs_gettimeofday(&tv); + ogs_assert(rc == 0); + + return ogs_time_to_ntp32(tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec); +} +ogs_time_t ogs_time_from_ntp32(uint32_t ntp_timestamp) +{ + if (ntp_timestamp < OGS_1970_1900_SEC_DIFF) + return 0; + return (ntp_timestamp - OGS_1970_1900_SEC_DIFF) * OGS_USEC_PER_SEC; +} +uint32_t ogs_time_to_ntp32(ogs_time_t time) +{ + return (time / OGS_USEC_PER_SEC) + OGS_1970_1900_SEC_DIFF; +} + int ogs_timezone(void) { #if defined(_WIN32) diff --git a/lib/core/ogs-time.h b/lib/core/ogs-time.h index 033ebe9f2e..0257f19661 100644 --- a/lib/core/ogs-time.h +++ b/lib/core/ogs-time.h @@ -99,6 +99,11 @@ ogs_time_t ogs_time_now(void); /* This returns GMT */ int ogs_time_from_lt(ogs_time_t *t, struct tm *tm, int tm_usec); int ogs_time_from_gmt(ogs_time_t *t, struct tm *tm, int tm_usec); +#define OGS_1970_1900_SEC_DIFF 2208988800UL /* 1970 - 1900 in seconds */ +uint32_t ogs_time_ntp32_now(void); /* This returns NTP timestamp (1900) */ +ogs_time_t ogs_time_from_ntp32(uint32_t ntp_timestamp); +uint32_t ogs_time_to_ntp32(ogs_time_t time); + /** @return number of microseconds since an arbitrary point */ ogs_time_t ogs_get_monotonic_time(void); /** @return the GMT offset in seconds */ diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index 661f1d28e2..66b88bc24a 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -39,27 +39,12 @@ static OGS_POOL(ogs_pfcp_rule_pool, ogs_pfcp_rule_t); void ogs_pfcp_context_init(void) { - struct timeval tv; ogs_assert(context_initialized == 0); /* Initialize SMF context */ memset(&self, 0, sizeof(ogs_pfcp_context_t)); - /* - * PFCP entity uses NTP timestamp(1900), but Open5GS uses UNIX(1970). - * - * One is the offset between the two epochs. - * Unix uses an epoch located at 1/1/1970-00:00h (UTC) and - * NTP uses 1/1/1900-00:00h. This leads to an offset equivalent - * to 70 years in seconds (there are 17 leap years - * between the two dates so the offset is - * - * (70*365 + 17)*86400 = 2208988800 - * - * to be substracted from NTP time to get Unix struct timeval. - */ - ogs_gettimeofday(&tv); - self.pfcp_started = tv.tv_sec + 2208988800; + self.pfcp_started = ogs_time_ntp32_now(); ogs_log_install_domain(&__ogs_pfcp_domain, "pfcp", ogs_core()->log.level);