[MME] [AMF] Add no_time_zone_information param (#2745)

Allow network operators to omit the time zone in the 4G EMM Information
and 5G Configuration Update. This is useful for better compatibility
with some UEs.

The parameter is optional according to:
* 4G: 3GPP TS 24.301 Table 8.2.13.1
* 5G: 3GPP TS 24.501 Table 8.2.19.1.1
This commit is contained in:
Oliver Smith 2023-11-27 14:26:12 +01:00 committed by GitHub
parent c6372255d5
commit 5070ddfa3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 69 deletions

View File

@ -235,6 +235,10 @@ int ogs_app_parse_global_conf(ogs_yaml_iter_t *parent)
"no_pfcp_rr_select")) {
global_conf.parameter.no_pfcp_rr_select =
ogs_yaml_iter_bool(&parameter_iter);
} else if (!strcmp(parameter_key,
"no_time_zone_information")) {
global_conf.parameter.no_time_zone_information =
ogs_yaml_iter_bool(&parameter_iter);
} else
ogs_warn("unknown key `%s`", parameter_key);
}

View File

@ -62,6 +62,7 @@ typedef struct ogs_global_conf_s {
int no_ipv4v6_local_addr_in_packet_filter;
int no_pfcp_rr_select;
int no_time_zone_information;
} parameter;
struct {

View File

@ -551,50 +551,52 @@ ogs_pkbuf_t *gmm_build_configuration_update_command(
&amf_self()->short_name, sizeof(ogs_nas_network_name_t));
}
ogs_gettimeofday(&tv);
ogs_gmtime(tv.tv_sec, &gmt);
ogs_localtime(tv.tv_sec, &local);
if (!ogs_global_conf()->parameter.no_time_zone_information) {
ogs_gettimeofday(&tv);
ogs_gmtime(tv.tv_sec, &gmt);
ogs_localtime(tv.tv_sec, &local);
ogs_info(" UTC [%04d-%02d-%02dT%02d:%02d:%02d] "
"Timezone[%d]/DST[%d]",
gmt.tm_year+1900, gmt.tm_mon+1, gmt.tm_mday,
gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
(int)gmt.tm_gmtoff, gmt.tm_isdst);
ogs_info(" LOCAL [%04d-%02d-%02dT%02d:%02d:%02d] "
"Timezone[%d]/DST[%d]",
local.tm_year+1900, local.tm_mon+1, local.tm_mday,
local.tm_hour, local.tm_min, local.tm_sec,
(int)local.tm_gmtoff, local.tm_isdst);
ogs_info(" UTC [%04d-%02d-%02dT%02d:%02d:%02d] "
"Timezone[%d]/DST[%d]",
gmt.tm_year+1900, gmt.tm_mon+1, gmt.tm_mday,
gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
(int)gmt.tm_gmtoff, gmt.tm_isdst);
ogs_info(" LOCAL [%04d-%02d-%02dT%02d:%02d:%02d] "
"Timezone[%d]/DST[%d]",
local.tm_year+1900, local.tm_mon+1, local.tm_mday,
local.tm_hour, local.tm_min, local.tm_sec,
(int)local.tm_gmtoff, local.tm_isdst);
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_LOCAL_TIME_ZONE_PRESENT;
if (local.tm_gmtoff >= 0) {
*local_time_zone = OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900);
} else {
*local_time_zone = OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900);
*local_time_zone |= 0x08;
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_LOCAL_TIME_ZONE_PRESENT;
if (local.tm_gmtoff >= 0) {
*local_time_zone = OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900);
} else {
*local_time_zone = OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900);
*local_time_zone |= 0x08;
}
ogs_debug(" Timezone:0x%x", *local_time_zone);
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT;
universal_time_and_local_time_zone->year =
OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100);
universal_time_and_local_time_zone->mon =
OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1);
universal_time_and_local_time_zone->mday =
OGS_NAS_TIME_TO_BCD(gmt.tm_mday);
universal_time_and_local_time_zone->hour =
OGS_NAS_TIME_TO_BCD(gmt.tm_hour);
universal_time_and_local_time_zone->min =
OGS_NAS_TIME_TO_BCD(gmt.tm_min);
universal_time_and_local_time_zone->sec =
OGS_NAS_TIME_TO_BCD(gmt.tm_sec);
universal_time_and_local_time_zone->timezone = *local_time_zone;
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT;
network_daylight_saving_time->length = 1;
}
ogs_debug(" Timezone:0x%x", *local_time_zone);
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT;
universal_time_and_local_time_zone->year =
OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100);
universal_time_and_local_time_zone->mon =
OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1);
universal_time_and_local_time_zone->mday =
OGS_NAS_TIME_TO_BCD(gmt.tm_mday);
universal_time_and_local_time_zone->hour =
OGS_NAS_TIME_TO_BCD(gmt.tm_hour);
universal_time_and_local_time_zone->min =
OGS_NAS_TIME_TO_BCD(gmt.tm_min);
universal_time_and_local_time_zone->sec =
OGS_NAS_TIME_TO_BCD(gmt.tm_sec);
universal_time_and_local_time_zone->timezone = *local_time_zone;
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT;
network_daylight_saving_time->length = 1;
}
if (param->guti) {

View File

@ -316,36 +316,38 @@ int emm_handle_attach_complete(
&mme_self()->short_name, sizeof(ogs_nas_network_name_t));
}
emm_information->presencemask |=
OGS_NAS_EPS_EMM_INFORMATION_LOCAL_TIME_ZONE_PRESENT;
if (!ogs_global_conf()->parameter.no_time_zone_information) {
emm_information->presencemask |=
OGS_NAS_EPS_EMM_INFORMATION_LOCAL_TIME_ZONE_PRESENT;
if (local.tm_gmtoff >= 0) {
*local_time_zone = OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900);
} else {
*local_time_zone = OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900);
*local_time_zone |= 0x08;
if (local.tm_gmtoff >= 0) {
*local_time_zone = OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900);
} else {
*local_time_zone = OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900);
*local_time_zone |= 0x08;
}
ogs_debug(" Timezone:0x%x", *local_time_zone);
emm_information->presencemask |=
OGS_NAS_EPS_EMM_INFORMATION_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT;
universal_time_and_local_time_zone->year =
OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100);
universal_time_and_local_time_zone->mon =
OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1);
universal_time_and_local_time_zone->mday =
OGS_NAS_TIME_TO_BCD(gmt.tm_mday);
universal_time_and_local_time_zone->hour =
OGS_NAS_TIME_TO_BCD(gmt.tm_hour);
universal_time_and_local_time_zone->min =
OGS_NAS_TIME_TO_BCD(gmt.tm_min);
universal_time_and_local_time_zone->sec =
OGS_NAS_TIME_TO_BCD(gmt.tm_sec);
universal_time_and_local_time_zone->timezone = *local_time_zone;
emm_information->presencemask |=
OGS_NAS_EPS_EMM_INFORMATION_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT;
network_daylight_saving_time->length = 1;
}
ogs_debug(" Timezone:0x%x", *local_time_zone);
emm_information->presencemask |=
OGS_NAS_EPS_EMM_INFORMATION_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT;
universal_time_and_local_time_zone->year =
OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100);
universal_time_and_local_time_zone->mon =
OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1);
universal_time_and_local_time_zone->mday =
OGS_NAS_TIME_TO_BCD(gmt.tm_mday);
universal_time_and_local_time_zone->hour =
OGS_NAS_TIME_TO_BCD(gmt.tm_hour);
universal_time_and_local_time_zone->min =
OGS_NAS_TIME_TO_BCD(gmt.tm_min);
universal_time_and_local_time_zone->sec =
OGS_NAS_TIME_TO_BCD(gmt.tm_sec);
universal_time_and_local_time_zone->timezone = *local_time_zone;
emm_information->presencemask |=
OGS_NAS_EPS_EMM_INFORMATION_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT;
network_daylight_saving_time->length = 1;
emmbuf = nas_eps_security_encode(mme_ue, &message);
if (!emmbuf) {