diff --git a/ci-scripts/conf_files/nrue.uicc.2pdu.conf b/ci-scripts/conf_files/nrue.uicc.2pdu.conf new file mode 100644 index 0000000000..03f64f47fc --- /dev/null +++ b/ci-scripts/conf_files/nrue.uicc.2pdu.conf @@ -0,0 +1,11 @@ +uicc0 = { + imsi = "208990100001100"; + key = "fec86ba6eb707ed08905757b1bb44b8f"; + opc= "C42449363BBAD02B66D16BC975D77CC1"; + pdu_sessions = ( + { id = 1; dnn = "oai"; nssai_sst = 1; }, + { id = 2; dnn = "oai"; nssai_sst = 1; } + ) +} + +thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" diff --git a/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml index c4a4e2ebea..ebb006213d 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml @@ -149,7 +149,7 @@ services: - NET_RAW # for ping environment: USE_ADDITIONAL_OPTIONS: --rfsim -r 25 --numerology 0 --uicc0.imsi 208990100001100 --band 66 -C 2152680000 --CO -400000000 --ssb 48 - --rfsimulator.serveraddr 192.168.71.141 --extra-pdu-id 2 --log_config.global_log_options level,nocolor,time + --rfsimulator.serveraddr 192.168.71.141 --log_config.global_log_options level,nocolor,time --telnetsrv --telnetsrv.shrmod ciUE --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.listenport 8091 ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: @@ -160,7 +160,7 @@ services: devices: - /dev/net/tun:/dev/net/tun volumes: - - ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf + - ../../conf_files/nrue.uicc.2pdu.conf:/opt/oai-nr-ue/etc/nr-ue.conf healthcheck: test: /bin/bash -c "pgrep nr-uesoftmodem" start_period: 10s diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 81451796e0..457ba77b4b 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -174,8 +174,9 @@ static int add_pdu_session(char *buf, int debug, telnet_printfunc_t prnt) DevAssert(nas->uicc); nssai_t nssai = {nas->uicc->nssai_sst, nas->uicc->nssai_sd}; - const char *dnn = nas->uicc->dnnStr; - request_pdusession(nas, pdusession_id, 1 /* = PDU_SESSION_TYPE_IPV4 */, nssai, dnn); + pdu_session_config_t c = {pdusession_id, 1 /* = PDU_SESSION_TYPE_IPV4 */, nssai, nas->uicc->dnnStr}; + nas->uicc->pdu_sessions[nas->uicc->n_pdu_sessions++] = c; + request_pdusession(nas, &c); prnt("Triggered PDU session request for UE %d with ID %d\n", ue_id, pdusession_id); return 0; } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index f1cc659cae..0d3c4053b2 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -181,10 +181,8 @@ static void get_options(configmodule_interface_t *cfg) config_get(cfg, cmdline_params, numparams, NULL); if (nrUE_params.vcdflag > 0) ouput_vcd = 1; - AssertFatal(nrUE_params.extra_pdu_id != get_softmodem_params()->default_pdu_session_id, - "Default PDU ID (%d) and Extra PDU ID (%d) must be different!\n", - get_softmodem_params()->default_pdu_session_id, - nrUE_params.extra_pdu_id); + AssertFatal(nrUE_params.extra_pdu_id == -1, + "Add additional PDU sessions in uicc.pdu_sessions array instead\n"); } // set PHY vars from command line diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 09fced4aa3..558fd4968b 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -156,6 +156,10 @@ void get_common_options(configmodule_interface_t *cfg) nfapi_setmode(nfapi_mode); if (stats_disabled) IS_SOFTMODEM_NOSTATS = true; + + // To be removed in a future release (after 1 month) + AssertFatal(get_softmodem_params()->default_pdu_session_id == -1, + "Use uicc0.pdu_sessions.[0].id to change the requested PDU session ID (is %d)\n", get_softmodem_params()->default_pdu_session_id); } void softmodem_verify_mode(const softmodem_params_t *p) diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 4dfa5eb680..cf5c6ad553 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -180,7 +180,7 @@ extern int usrp_tx_thread; {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&softmodem_params.threequarter_fs, .defintval=0, TYPE_INT, 0}, \ {"imscope" , CONFIG_HLP_IMSCOPE, PARAMFLAG_BOOL, .uptr=&enable_imscope, .defintval=0, TYPE_UINT, 0}, \ {"imscope-record" , CONFIG_HLP_IMSCOPE_RECORD,PARAMFLAG_BOOL, .uptr=&enable_imscope_record, .defintval=0, TYPE_UINT, 0}, \ - {"default-pdu-id", NULL, 0, .iptr=&DEFAULT_PDU_ID, .defintval=10, TYPE_INT, 0}, \ + {"default-pdu-id", NULL, 0, .iptr=&DEFAULT_PDU_ID, .defintval=-1, TYPE_INT, 0}, \ } // clang-format on diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index f839ff4be6..59472df32a 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -1773,8 +1773,9 @@ static void send_nas_5gmm_ind(instance_t instance, const Guti5GSMobileIdentity_t itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); } -void request_pdusession(nr_ue_nas_t *nas, int pdusession_id, int t, nssai_t nssai, const char *dnn) +void request_pdusession(nr_ue_nas_t *nas, const pdu_session_config_t *pdu) { + int t = pdu->type; AssertFatal(t == PDU_SESSION_TYPE_IPV4 || t == PDU_SESSION_TYPE_IPV6 || t == PDU_SESSION_TYPE_IPV4V6 || t == PDU_SESSION_TYPE_UNSTRUCT || t == PDU_SESSION_TYPE_ETHER, "illegal PDU session type %d\n", @@ -1782,12 +1783,12 @@ void request_pdusession(nr_ue_nas_t *nas, int pdusession_id, int t, nssai_t nssa AssertFatal(t != PDU_SESSION_TYPE_UNSTRUCT, "unstructured PDU sessions not handled yet\n"); MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, nas->UE_id, NAS_PDU_SESSION_REQ); nas_pdu_session_req_t *pdu_req = &NAS_PDU_SESSION_REQ(message_p); - pdu_req->pdusession_id = pdusession_id; + pdu_req->pdusession_id = pdu->id; // 24.501: joint PDU session type IEI (0x9-, Table 8.3.1.1.1) and type (9.11.4.11) pdu_req->pdusession_type = 0x90 | t; - pdu_req->sst = nssai.sst; - pdu_req->sd = nssai.sd; - snprintf(pdu_req->dnn, sizeof(pdu_req->dnn), "%s", dnn); + pdu_req->sst = pdu->nssai.sst; + pdu_req->sd = pdu->nssai.sd; + snprintf(pdu_req->dnn, sizeof(pdu_req->dnn), "%s", pdu->dnn); itti_send_msg_to_task(TASK_NAS_NRUE, nas->UE_id, message_p); } @@ -1873,14 +1874,18 @@ static void handle_registration_accept(nr_ue_nas_t *nas, const uint8_t *pdu_buff send_nas_uplink_data_req(nas, &initialNasMsg); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } - nssai_t ch_nssai = {nas->uicc->nssai_sst, nas->uicc->nssai_sd}; - if (get_user_nssai_idx(ch_nssai, msg.nas_allowed_nssai) < 0) { - LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n"); - } else { - nssai_t nssai = {nas->uicc->nssai_sst, nas->uicc->nssai_sd}; - request_pdusession(nas, get_softmodem_params()->default_pdu_session_id, PDU_SESSION_TYPE_IPV4, nssai, nas->uicc->dnnStr); - if (get_nrUE_params()->extra_pdu_id != -1) { - request_pdusession(nas, get_nrUE_params()->extra_pdu_id, PDU_SESSION_TYPE_IPV4, nssai, nas->uicc->dnnStr); + if (nas->uicc->n_pdu_sessions == 0) + LOG_W(SIM, "no PDU sessions to request configured\n"); + for (const pdu_session_config_t *pdu = nas->uicc->pdu_sessions; pdu < nas->uicc->pdu_sessions + nas->uicc->n_pdu_sessions; ++pdu) { + if (get_user_nssai_idx(pdu->nssai, msg.nas_allowed_nssai) < 0) { + LOG_E(NAS, + "PDU session ID %d NSSAI %d.%d: mismatch for allowed NSSAI. Couldn't request PDU session.\n", + pdu->id, + pdu->nssai.sst, + pdu->nssai.sd); + } else { + LOG_I(NAS, "requested PDU session ID %d type %d NSSAI %d.%d DNN %s\n", pdu->id, pdu->type, pdu->nssai.sst, pdu->nssai.sd, pdu->dnn); + request_pdusession(nas, pdu); } } // Free local message after processing diff --git a/openair3/NAS/NR_UE/nr_nas_msg.h b/openair3/NAS/NR_UE/nr_nas_msg.h index 1dd5afafe9..1bed56aa3c 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.h +++ b/openair3/NAS/NR_UE/nr_nas_msg.h @@ -114,6 +114,6 @@ void *nas_nrue_task(void *args_p); void *nas_nrue(void *args_p); void nas_init_nrue(int num_ues); void nr_ue_create_ip_if(const char *ifnameprefix, const char *ipv4, const char *ipv6, int ue_id, int pdu_session_id); -void request_pdusession(nr_ue_nas_t *nas, int pdusession_id, int type, nssai_t nssai, const char *dnn); +void request_pdusession(nr_ue_nas_t *nas, const pdu_session_config_t *pdu); #endif /* __NR_NAS_MSG_SIM_H__*/ diff --git a/openair3/UICC/pdu_session.c b/openair3/UICC/pdu_session.c index f3d13334f7..1eabeb7f37 100644 --- a/openair3/UICC/pdu_session.c +++ b/openair3/UICC/pdu_session.c @@ -82,7 +82,7 @@ static int config_check_dnn(configmodule_interface_t *cfg, paramdef_t *param) return 0; } -int get_pdu_session_configs(int module_id, pdu_session_config_t *configs, int max_len) +int get_pdu_session_configs(const char *uiccName, pdu_session_config_t *configs, int max_len) { paramdef_t pdu_sess_params[] = PDU_SESS_PARAMS_DESC; const int npsp = sizeofArray(pdu_sess_params); @@ -92,7 +92,7 @@ int get_pdu_session_configs(int module_id, pdu_session_config_t *configs, int ma "param_def_t array and corresponding checkedparam_t array should have the same size"); for (int i = 0; i < sizeofArray(pdu_sess_params); ++i) pdu_sess_params[i].chkPptr = &pdu_sess_params_check[i]; - int ret = config_getlist(config_get_if(), &pdu_sess_list, pdu_sess_params, sizeofArray(pdu_sess_params), NULL); + int ret = config_getlist(config_get_if(), &pdu_sess_list, pdu_sess_params, sizeofArray(pdu_sess_params), uiccName); if (ret < 0) { // couldn't load configuration from pdu_sessions, caller has to handle return -1; diff --git a/openair3/UICC/pdu_session.h b/openair3/UICC/pdu_session.h index d74d4664ab..c1acaa82b1 100644 --- a/openair3/UICC/pdu_session.h +++ b/openair3/UICC/pdu_session.h @@ -31,6 +31,6 @@ typedef struct { char *dnn; // [103]? } pdu_session_config_t; -int get_pdu_session_configs(int module_id, pdu_session_config_t *configs, int max_len); +int get_pdu_session_configs(const char *uiccName, pdu_session_config_t *configs, int max_len); #endif /* PDU_SESSION_H_ */ diff --git a/openair3/UICC/usim_interface.c b/openair3/UICC/usim_interface.c index f1019366b1..f722d6ccd6 100644 --- a/openair3/UICC/usim_interface.c +++ b/openair3/UICC/usim_interface.c @@ -22,6 +22,7 @@ */ #include +#include "common/platform_constants.h" #include #include extern uint16_t NB_UE_INST; @@ -76,10 +77,7 @@ uicc_t *init_uicc(char *sectionName) { // key, OPc, sqn, amf don't need to be read from the true USIM int ret = config_get(config_get_if(), uicc_params, sizeofArray(uicc_params), sectionName); AssertFatal(ret >= 0, "configuration couldn't be performed for uicc name: %s", sectionName); - LOG_I(SIM, - "UICC simulation: IMSI=%s, IMEISV=%s, Ki=%s, OPc=%s, DNN=%s, SST=0x%02x, SD=0x%06x\n", - uicc->imsiStr, uicc->imeisvStr, uicc->keyStr, uicc->opcStr, - uicc->dnnStr, uicc->nssai_sst, uicc->nssai_sd); + LOG_I(SIM, "UICC simulation: IMSI=%s, IMEISV=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->imeisvStr, uicc->keyStr, uicc->opcStr); to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) ); to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) ); to_hex(uicc->sqnStr,uicc->sqn, sizeof(uicc->sqn) ); @@ -112,6 +110,36 @@ uicc_t * checkUicc(int Mod_id) { char uiccName[64]; sprintf(uiccName,"uicc%d", Mod_id); uiccArray[Mod_id]=(void*)init_uicc(uiccName); + uicc_t *uicc = uiccArray[Mod_id]; + uicc->n_pdu_sessions = get_pdu_session_configs(uiccName, uicc->pdu_sessions, sizeof(uicc->pdu_sessions)); + if (uicc->n_pdu_sessions > 0) { + LOG_I(SIM, "overriding potential %s.dnn/nssai_sst/nssai_sd from %s.pdu_sessions\n", uiccName, uiccName); + } else if (uicc->n_pdu_sessions < 0) { + // we could not load from "new" pdu_sessions list, so read from "legacy" + // config + LOG_W(SIM, + "loading PDU session parameters from legacy UICC configuration. Please update to use %s.pdu_sessions instead to make this warning disappear\n", + uiccName); + sleep(3); + uicc->n_pdu_sessions = 1; + pdu_session_config_t *pdu = &uicc->pdu_sessions[0]; + AssertFatal(uicc->dnnStr != NULL, "no default DNN, cannot create\n"); + pdu->id = DEFAULT_NOS1_PDU_ID; // any default would do + pdu->dnn = strdup(uicc->dnnStr); + pdu->nssai.sst = uicc->nssai_sst; + pdu->nssai.sd = uicc->nssai_sd; + pdu->type = 1; /* = PDU_SESSION_TYPE_IPV4 */ + } // else: uicc->n_pdu_sessions == 0 => don't request a PDU session + for (int i = 0; i < uicc->n_pdu_sessions; ++i) { + const pdu_session_config_t *pdu = &uicc->pdu_sessions[i]; + LOG_I(SIM, + "will request PDU session ID %d, type %d, DNN %s, NSSAI %d.%6x\n", + pdu->id, + pdu->type, + pdu->dnn, + pdu->nssai.sst, + pdu->nssai.sd); + } } return (uicc_t*) uiccArray[Mod_id]; } diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h index 1a275db887..f4689594c2 100644 --- a/openair3/UICC/usim_interface.h +++ b/openair3/UICC/usim_interface.h @@ -34,6 +34,7 @@ #include #include #include "common_lib.h" +#include "pdu_session.h" /* 3GPP glossary RES RESponse @@ -53,6 +54,8 @@ typedef struct { char *dnnStr; int nssai_sst; int nssai_sd; + pdu_session_config_t pdu_sessions[256]; + int n_pdu_sessions; uint8_t key[16]; uint8_t opc[16]; uint8_t amf[2];