diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index 7aff02f9df..1d7169f29f 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -1235,7 +1235,13 @@ You should be able to connect a UE now. # OAI Management Plane -We support Configuration Management in OAI gNB, where gNB configures CU-planes, interfaces, TX/RX antennas, and TX/RX carriers for the RU. +In OAI gNB, we support: +* Configuration Management: interface(s) creation, configuration of RU CU-planes, Tx/Rx antennas, and Tx/Rx carriers. +* Performance Management: activation/deactivation of available RU performance measurements and its notification reception with 10s periodicity: +```bash +[HW] [MPLANE] [PM: "192.168.80.9"][RX_ON_TIME 773428][RX_EARLY 0][RX_LATE 0][RX_TOTAL 878881][RX_ON_TIME_C 104744][RX_EARLY_C 0][RX_LATE_C 0][TX_TOTAL 435922] +``` + The reference specifications: * `O-RAN.WG4.MP.0-v05.00` * `O-RAN.WG4.MP-YANGs-v04.00` @@ -1375,7 +1381,7 @@ Once the mplane service is successfully enabled on the RU, two new users are bei oranbenetel:x:1000:1000::/home/oranbenetel:/bin/sh oranext:x:1001:1001::/home/oranext:/bin/sh ``` -Create `oranbenetel` home directory: +OAI gNB requires the `sudo` access group for NETCONF session. In the case of Benetel O-RUs, the corresponding user is `oranbenetel`. Therefore, please create its home directory: ```bash mkdir /home/oranbenetel && chown oranbenetel:oranbenetel /home/oranbenetel ``` @@ -1393,7 +1399,7 @@ The reference gNB configuration file for one Benetel RAN550: The reference DU configuration file for two Benetel RAN650: [gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf) -In order to run gNB/DU with M-plane, we need to modify the `fhi_72` section in the configuration file. +In order to run gNB/DU with M-plane, we need to modify Tx gain `att_tx` in RU section, as well as the `fhi_72` section in the configuration file. Example for one RU: ```bash fhi_72 = { @@ -1404,6 +1410,7 @@ fhi_72 = { du_key_pair = ("/.ssh/id_rsa.pub", "/.ssh/id_rsa"); du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67"); # only one needed if one VF configured vlan_tag = (9, 9); # only one needed if one VF configured + ru_username = ("oranbenetel"); ru_ip_addr = ("192.168.80.9"); fh_config = ({ T1a_cp_dl = (419, 470); @@ -1423,6 +1430,7 @@ fhi_72 = { du_key_pair = ("/home/oaicicd/.ssh/id_rsa.pub", "/home/oaicicd/.ssh/id_rsa"); du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67", "00:11:22:33:44:68", "00:11:22:33:44:69"); # only two needed if two VFs configured vlan_tag = (9, 9, 11, 11); # only two needed if two VFs configured + ru_username = ("oranbenetel", "oranbenetel"); ru_ip_addr = ("192.168.80.9", "192.168.80.10"); fh_config = ( # RAN550 #1 @@ -1451,6 +1459,7 @@ fhi_72 = { * `du_key_pair`: ssh public and private keys to authenticate RU with NETCONF * `du_addr`: DU MAC address(es) to create CU-plane interface(s) in the RU * `vlan_tag`: VLAN U and C plane tags to create CU-plane interface(s) in the RU + * `ru_username`: Username with `sudo` access to connect to the RU via M-plane * `ru_ip_addr`: RU IP address to connect to the RU via M-plane * `dpdk_mem_size`: [*] * `dpdk_iova_mode`: [*] @@ -1557,7 +1566,9 @@ sequenceDiagram note over du: DU configures xran - du->ru: 12. DU and RU exchange packets + du->ru: 12. DU activates Performance Measurements + + du->ru: 13. DU and RU exchange packets ``` @@ -1596,7 +1607,9 @@ sequenceDiagram Band sector ID 0 CC ID 0 RU port ID 0 + max Tx gain 24.0 [HW] [MPLANE] Successfully retrieved all the U-plane info - interface name, TX/RX carrier names, and TX/RX endpoint names. +[HW] [MPLANE] Successfully retreived all performance measurement names. [HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-yang-metadata". [HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "yang". [HW] [MPLANE] RPC request to RU "192.168.80.9" = for module "ietf-inet-types". @@ -1636,6 +1649,59 @@ sequenceDiagram 9 + + 10 + 10 + 10 + + RX_ON_TIME + false + RU + COUNT + + + RX_EARLY + false + RU + COUNT + + + RX_LATE + false + RU + COUNT + + + RX_TOTAL + false + RU + COUNT + + + RX_ON_TIME_C + false + RU + COUNT + + + RX_EARLY_C + false + RU + COUNT + + + RX_LATE_C + false + RU + COUNT + + + TX_TOTAL + false + RU + COUNT + + ETH-INTERFACE @@ -1729,8 +1795,10 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 61440 @@ -1746,8 +1814,10 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 61440 @@ -1763,8 +1833,10 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 61440 @@ -1780,8 +1852,10 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 61440 @@ -1797,9 +1871,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1807,6 +1887,7 @@ sequenceDiagram 15 0 + true LowLevelRxPrachEndpoint0 @@ -1814,9 +1895,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1824,6 +1911,7 @@ sequenceDiagram 15 4 + true LowLevelRxEndpoint1 @@ -1831,9 +1919,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1841,6 +1935,7 @@ sequenceDiagram 15 1 + true LowLevelRxPrachEndpoint1 @@ -1848,9 +1943,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1858,6 +1959,7 @@ sequenceDiagram 15 5 + true LowLevelRxEndpoint2 @@ -1865,9 +1967,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1875,6 +1983,7 @@ sequenceDiagram 15 2 + true LowLevelRxPrachEndpoint2 @@ -1882,9 +1991,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1892,6 +2007,7 @@ sequenceDiagram 15 6 + true LowLevelRxEndpoint3 @@ -1899,9 +2015,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1909,6 +2031,7 @@ sequenceDiagram 15 3 + true LowLevelRxPrachEndpoint3 @@ -1916,9 +2039,15 @@ sequenceDiagram 9 STATIC - 0 - 0 + 193 + NORMAL + 352 + 288 0 + + KHZ_30 + 0 + 61440 3840 @@ -1926,6 +2055,7 @@ sequenceDiagram 15 7 + true TxArray0 @@ -1933,7 +2063,7 @@ sequenceDiagram 3950400000 100000000 ACTIVE - 0.0 + 24.0 0 0 @@ -1957,7 +2087,7 @@ sequenceDiagram [HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9". [HW] [MPLANE] RPC request to RU "192.168.80.9" = candidate datastore. [HW] [MPLANE] RPC reply = OK. -[HW] [MPLANE] Successfully commited CU-planes configuration into running datastore for RU "192.168.80.9". +[HW] [MPLANE] Successfully commited configuration into running datastore for RU "192.168.80.9". [HW] [MPLANE] Usage state = "idle" for RU "192.168.80.9". [HW] [MPLANE] Received notification from RU "192.168.80.9" at (2025-03-29T12:40:23.049085102+00:00) { @@ -2025,9 +2155,71 @@ sequenceDiagram "operation": "create" }, ... -} - [HW] [MPLANE] RU "192.168.80.9" is now ready. +[HW] [MPLANE] RPC request to RU "192.168.80.9" = : + + 10 + 10 + 10 + + RX_ON_TIME + true + RU + COUNT + + + RX_EARLY + true + RU + COUNT + + + RX_LATE + true + RU + COUNT + + + RX_TOTAL + true + RU + COUNT + + + RX_ON_TIME_C + true + RU + COUNT + + + RX_EARLY_C + true + RU + COUNT + + + RX_LATE_C + true + RU + COUNT + + + TX_TOTAL + true + RU + COUNT + + + +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully edited the candidate datastore for RU "192.168.80.9". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = candidate datastore. +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully validated candidate datastore for RU "192.168.80.9". +[HW] [MPLANE] RPC request to RU "192.168.80.9" = candidate datastore. +[HW] [MPLANE] RPC reply = OK. +[HW] [MPLANE] Successfully commited configuration into running datastore for RU "192.168.80.9". +[HW] [MPLANE] Sucessfully activated PM after start-up procedure for RU "192.168.80.9". ``` diff --git a/executables/nr-ru.c b/executables/nr-ru.c index de3a4b7875..20deff5725 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -878,11 +878,12 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file) } } -static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, int slots_per_frame, uint16_t ofdm_symbol_size) +static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, const NR_DL_FRAME_PARMS *fp) { const nfapi_nr_prach_config_t *prach_config = &config->prach_config; const nfapi_nr_tdd_table_t *tdd_table = &config->tdd_table; const nfapi_nr_cell_config_t *cell_config = &config->cell_config; + const nfapi_nr_carrier_config_t *carrier_config = &config->carrier_config; DevAssert(prach_config->prach_ConfigurationIndex.tl.tag == NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG); split7->prach_index = prach_config->prach_ConfigurationIndex.value; @@ -893,7 +894,7 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_ if (cell_config->frame_duplex_type.value == 1 /* TDD */) { DevAssert(tdd_table->tdd_period.tl.tag == NFAPI_NR_CONFIG_TDD_PERIOD_TAG); int nb_periods_per_frame = get_nb_periods_per_frame(tdd_table->tdd_period.value); - split7->n_tdd_period = slots_per_frame / nb_periods_per_frame; + split7->n_tdd_period = fp->slots_per_frame / nb_periods_per_frame; for (int slot = 0; slot < split7->n_tdd_period; ++slot) { for (int sym = 0; sym < 14; ++sym) { split7->slot_dirs[slot].sym_dir[sym] = tdd_table->max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[sym].slot_config.value; @@ -901,7 +902,15 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_ } } - split7->fftSize = log2(ofdm_symbol_size); + split7->fftSize = log2(fp->ofdm_symbol_size); + + // M-plane related parameters + for (size_t i = 0; i < 5 ; i++) { + split7->dl_k0[i] = carrier_config->dl_k0[i].value; + split7->ul_k0[i] = carrier_config->ul_k0[i].value; + } + split7->cp_prefix0 = fp->nb_prefix_samples0; + split7->cp_prefix_other = fp->nb_prefix_samples; } /* this function maps the RU tx and rx buffers to the available rf chains. @@ -1044,7 +1053,7 @@ void *ru_thread(void *param) nr_dump_frame_parms(fp); nr_phy_init_RU(ru); fill_rf_config(ru, ru->rf_config_file); - fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp->slots_per_frame, fp->ofdm_symbol_size); + fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp); // Start IF device if any if (ru->nr_start_if) { diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index f928d554a8..b87a6a8abf 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -198,6 +198,13 @@ typedef struct split7_config { } slot_dirs[160]; /*! this is the exponent in 2^X for the FFT size */ uint16_t fftSize; + + // M-plane related parameters + uint16_t dl_k0[5]; + uint16_t ul_k0[5]; + uint16_t cp_prefix0; + uint16_t cp_prefix_other; + } split7_config_t; /*! \brief RF frontend parameters set by application */ diff --git a/radio/fhi_72/mplane/config-mplane.c b/radio/fhi_72/mplane/config-mplane.c index 69ff1fd2b3..da28665023 100644 --- a/radio/fhi_72/mplane/config-mplane.c +++ b/radio/fhi_72/mplane/config-mplane.c @@ -21,14 +21,12 @@ #include "config-mplane.h" #include "rpc-send-recv.h" -#include "yang/get-yang.h" -#include "yang/create-yang-config.h" #include "common/utils/assertions.h" #include #include -bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus) +static bool edit_config_mplane(ru_session_t *ru_session, const char *content) { int timeout = CLI_RPC_REPLY_TIMEOUT; struct nc_rpc *rpc; @@ -39,37 +37,21 @@ bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const open NC_RPC_EDIT_TESTOPT test = NC_RPC_EDIT_TESTOPT_UNKNOWN; NC_RPC_EDIT_ERROPT err = NC_RPC_EDIT_ERROPT_UNKNOWN; - bool success = false; - - struct ly_ctx *ctx = NULL; - success = load_yang_models(ru_session, buffer, &ctx); - AssertError(success, return false, "[MPLANE] Unable to continue.\n"); - - char *content = NULL; - success = configure_ru_from_yang(&ctx, ru_session, oai, num_rus, &content); - AssertError(success, return false, "[MPLANE] Unable to create content for RPC.\n"); - MP_LOG_I("RPC request to RU \"%s\" = :\n%s\n", ru_session->ru_ip_add, content); rpc = nc_rpc_edit(target, op, test, err, content, param); AssertError(rpc != NULL, return false, "[MPLANE] RPC creation failed.\n"); - success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); + bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); AssertError(success, return false, "[MPLANE] Failed to edit configuration for the candidate datastore.\n"); MP_LOG_I("Successfully edited the candidate datastore for RU \"%s\".\n", ru_session->ru_ip_add); nc_rpc_free(rpc); - free(content); -#ifdef MPLANE_V1 - ly_ctx_destroy(ctx, NULL); -#elif defined MPLANE_V2 - ly_ctx_destroy(ctx); -#endif return true; } -bool validate_config_mplane(ru_session_t *ru_session) +static bool validate_config_mplane(ru_session_t *ru_session) { int timeout = CLI_RPC_REPLY_TIMEOUT; struct nc_rpc *rpc; @@ -92,7 +74,7 @@ bool validate_config_mplane(ru_session_t *ru_session) return true; } -bool commit_config_mplane(ru_session_t *ru_session) +static bool commit_config_mplane(ru_session_t *ru_session) { int timeout = CLI_RPC_REPLY_TIMEOUT; struct nc_rpc *rpc; @@ -109,9 +91,25 @@ bool commit_config_mplane(ru_session_t *ru_session) bool success = rpc_send_recv((struct nc_session *)ru_session->session, rpc, wd, timeout, NULL); AssertError(success, return false, "[MPLANE] Failed to commit candidate datastore.\n"); - MP_LOG_I("Successfully commited CU-planes configuration into running datastore for RU \"%s\".\n", ru_session->ru_ip_add); + MP_LOG_I("Successfully commited configuration into running datastore for RU \"%s\".\n", ru_session->ru_ip_add); nc_rpc_free(rpc); return true; } + +bool edit_val_commmit_rpc(ru_session_t *ru_session, const char *content) +{ + bool success = false; + + success = edit_config_mplane(ru_session, content); + AssertError(success, return false, "[MPLANE] Unable to edit the RU configuration.\n"); + + success = validate_config_mplane(ru_session); + AssertError(success, return false, "[MPLANE] Unable to validate the RU configuration.\n"); + + success = commit_config_mplane(ru_session); + AssertError(success, return false, "[MPLANE] Unable to commit the RU configuration.\n"); + + return success; +} diff --git a/radio/fhi_72/mplane/config-mplane.h b/radio/fhi_72/mplane/config-mplane.h index c8451ca8a0..dae2dbea63 100644 --- a/radio/fhi_72/mplane/config-mplane.h +++ b/radio/fhi_72/mplane/config-mplane.h @@ -25,10 +25,6 @@ #include "ru-mplane-api.h" #include "radio/COMMON/common_lib.h" -bool edit_config_mplane(ru_session_t *ru_session, const char *buffer, const openair0_config_t *oai, const size_t num_rus); - -bool validate_config_mplane(ru_session_t *ru_session); - -bool commit_config_mplane(ru_session_t *ru_session); +bool edit_val_commmit_rpc(ru_session_t *ru_session, const char *content); #endif /* CONFIGURE_MPLANE_H */ diff --git a/radio/fhi_72/mplane/connect-mplane.c b/radio/fhi_72/mplane/connect-mplane.c index 08b758bef1..9744ce01e8 100644 --- a/radio/fhi_72/mplane/connect-mplane.c +++ b/radio/fhi_72/mplane/connect-mplane.c @@ -20,6 +20,7 @@ */ #include "connect-mplane.h" +#include "init-mplane.h" #include "common/utils/assertions.h" #include @@ -37,9 +38,8 @@ static int my_auth_hostkey_check(const char *hostname, ssh_session session, void bool connect_mplane(ru_session_t *ru_session) { int port = NC_PORT_SSH; - char *user = "oranbenetel"; - nc_client_ssh_set_username(user); + nc_client_ssh_set_username(ru_session->username); nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1); // ssh-key identification nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1); @@ -47,11 +47,11 @@ bool connect_mplane(ru_session_t *ru_session) nc_client_ssh_set_auth_hostkey_check_clb(my_auth_hostkey_check, "DATA"); // host-key identification - MP_LOG_I("RPC request to RU \"%s\" = with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port); + MP_LOG_I("RPC request to RU \"%s\" = with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, ru_session->username, port); ru_session->session = nc_connect_ssh(ru_session->ru_ip_add, port, NULL); AssertError(ru_session->session != NULL, return false, "[MPLANE] RU IP address %s unreachable. Maybe M-plane is disabled on the RU?\n", ru_session->ru_ip_add); - MP_LOG_I("Successfuly connected to RU \"%s\" with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port); + MP_LOG_I("Successfuly connected to RU \"%s\" with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, ru_session->username, port); return true; } @@ -64,9 +64,18 @@ void disconnect_mplane(void *rus_disconnect) ru_session_t *ru_session = &ru_session_list->ru_session[i]; if (ru_session->session == NULL) continue; + MP_LOG_I("Sending PM de-activation request for RU \"%s\".\n", ru_session->ru_ip_add); + bool success = pm_conf(ru_session, "false"); + if (success) + MP_LOG_I("Successfully de-activated PM for RU \"%s\".\n", ru_session->ru_ip_add); MP_LOG_I("Disconnecting from RU \"%s\".\n", ru_session->ru_ip_add); nc_session_free(ru_session->session, NULL); ru_session->session = NULL; +#ifdef MPLANE_V1 + ly_ctx_destroy((struct ly_ctx *)ru_session->ctx, NULL); +#elif defined MPLANE_V2 + ly_ctx_destroy((struct ly_ctx *)ru_session->ctx); +#endif } nc_client_destroy(); diff --git a/radio/fhi_72/mplane/init-mplane.c b/radio/fhi_72/mplane/init-mplane.c index 39e8cfb995..fc20ba5af4 100644 --- a/radio/fhi_72/mplane/init-mplane.c +++ b/radio/fhi_72/mplane/init-mplane.c @@ -25,6 +25,8 @@ #include "subscribe-mplane.h" #include "config-mplane.h" #include "xml/get-xml.h" +#include "yang/get-yang.h" +#include "yang/create-yang-config.h" #include #include @@ -94,11 +96,14 @@ bool init_mplane(ru_session_list_t *ru_session_list) char **ru_ip_addrs = gpd(fhip, nump, ORAN_CONFIG_RU_IP_ADDR)->strlistptr; int num_rus = gpd(fhip, nump, ORAN_CONFIG_RU_IP_ADDR)->numelt; + char **ru_usernames = gpd(fhip, nump, ORAN_CONFIG_RU_USERNAME)->strlistptr; + int num_ru_users = gpd(fhip, nump, ORAN_CONFIG_RU_USERNAME)->numelt; char **du_mac_addr = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->strlistptr; int num_dus = gpd(fhip, nump, ORAN_CONFIG_DU_ADDR)->numelt; int32_t *vlan_tag = gpd(fhip, nump, ORAN_CONFIG_VLAN_TAG)->iptr; int num_vlan_tags = gpd(fhip, nump, ORAN_CONFIG_VLAN_TAG)->numelt; + AssertError(num_rus == num_ru_users, return false, "[MPLANE] Number of RUs should be equal to the number of users, one for each.\n"); AssertError(num_dus == num_vlan_tags, return false, "[MPLANE] Number of DU MAC addresses should be equal to the number of VLAN tags.\n"); int num_cu_planes = num_dus / num_rus; @@ -110,6 +115,8 @@ bool init_mplane(ru_session_list_t *ru_session_list) ru_session->session = NULL; ru_session->ru_ip_add = calloc(strlen(ru_ip_addrs[i]) + 1, sizeof(char)); memcpy(ru_session->ru_ip_add, ru_ip_addrs[i], strlen(ru_ip_addrs[i]) + 1); + ru_session->username = calloc(strlen(ru_usernames[i]) + 1, sizeof(char)); + memcpy(ru_session->username, ru_usernames[i], strlen(ru_usernames[i]) + 1); // store DU MAC addresses and VLAN tags ru_session->ru_mplane_config.num_cu_planes = num_cu_planes; @@ -175,15 +182,21 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz success = get_uplane_info(operational_ds, &ru_session->ru_mplane_config); AssertError(success, return false, "[MPLANE] Unable to get U-plane info from RU operational datastore.\n"); + // Performance Management + success = get_pm_object_list(operational_ds, &ru_session->pm_stats); + AssertError(success, return false, "[MPLANE] Unable to retrieve performance measurement names from RU \"%s\".\n", ru_session->ru_ip_add); + + success = load_yang_models(ru_session, operational_ds); + AssertError(success, return false, "[MPLANE] Unable to load yang models.\n"); + if (ru_session->ru_notif.ptp_state) { - success = edit_config_mplane(ru_session, operational_ds, oai, num_rus); - AssertError(success, return false, "[MPLANE] Unable to edit the RU configuration.\n"); + char *content = NULL; + success = configure_ru_from_yang(ru_session, oai, num_rus, &content); + AssertError(success, return false, "[MPLANE] Unable to create content for RPC for start-up procedure.\n"); - success = validate_config_mplane(ru_session); - AssertError(success, return false, "[MPLANE] Unable to validate the RU configuration.\n"); - - success = commit_config_mplane(ru_session); - AssertError(success, return false, "[MPLANE] Unable to commit the RU configuration.\n"); + success = edit_val_commmit_rpc(ru_session, content); + AssertError(success, return false, "[MPLANE] Unable to continue.\n"); + free(content); } const char *usage_state = get_ru_xml_node(operational_ds, "usage-state"); @@ -203,3 +216,15 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz return true; } + +bool pm_conf(ru_session_t *ru_session, const char *active) +{ + char *content = get_pm_content(ru_session, active); + + bool success = edit_val_commmit_rpc(ru_session, content); + AssertError(success, return false, "[MPLANE] Cannot continue.\n"); + + free(content); + + return true; +} diff --git a/radio/fhi_72/mplane/init-mplane.h b/radio/fhi_72/mplane/init-mplane.h index 5077908d64..ef6e23610f 100644 --- a/radio/fhi_72/mplane/init-mplane.h +++ b/radio/fhi_72/mplane/init-mplane.h @@ -29,4 +29,6 @@ bool init_mplane(ru_session_list_t *ru_session_list); bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus); +bool pm_conf(ru_session_t *ru_session, const char *active); + #endif /* OAI_MPLANE_H */ diff --git a/radio/fhi_72/mplane/ru-mplane-api.c b/radio/fhi_72/mplane/ru-mplane-api.c index d387a40864..df4bf3b8ba 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.c +++ b/radio/fhi_72/mplane/ru-mplane-api.c @@ -33,7 +33,7 @@ static void free_match_list(char **match_list, size_t count) free(match_list); } -static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t interface_mtu, const int16_t first_iq_width, const int max_num_ant) +static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t interface_mtu, const int16_t first_iq_width, const int max_num_ant, const char *model_name) { if (interface_mtu == 1500) { MP_LOG_I("Interface MTU %d unreliable/not correctly reported by Benetel O-RU, hardcoding to 9600.\n", interface_mtu); @@ -50,6 +50,14 @@ static void fix_benetel_setting(xran_mplane_t *xran_mplane, const uint32_t inter } xran_mplane->prach_offset = max_num_ant; + + if (strcasecmp(model_name, "RAN550") == 0) { + xran_mplane->max_tx_gain = 24.0; + } else if (strcasecmp(model_name, "RAN650") == 0) { + xran_mplane->max_tx_gain = 35.0; + } else { + assert(false && "[MPLANE] Unknown Benetel model name.\n"); + } } bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_t *xran_mplane) @@ -61,7 +69,7 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ xran_mplane->ru_mac_addr = get_ru_xml_node(buffer, "mac-address"); // TODO: support for VVDN, as it defines multiple MAC addresses // MTU - const uint32_t interface_mtu = (uint32_t)atoi(get_ru_xml_node(buffer, "interface-mtu")); + const uint32_t interface_mtu = (uint32_t)atoi(get_ru_xml_node(buffer, "l2-mtu")); // IQ bitwidth char **match_list = NULL; @@ -91,8 +99,25 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ // RU port ID xran_mplane->ru_port = 0; + // Frame structure + match_list = NULL; + count = 0; + get_ru_xml_list(buffer, "supported-frame-structures", &match_list, &count); + xran_mplane->frame_str = (int16_t)atoi((char *)match_list[0]); + free_match_list(match_list, count); + + // Managed delay support + const char *managed_delay = get_ru_xml_node(buffer, "managed-delay-support"); + xran_mplane->managed_delay = (strcasecmp(managed_delay, "NON_MANAGED") == 0) ? false : true; + + // Store the max gain + xran_mplane->max_tx_gain = (double)atof(get_ru_xml_node(buffer, "max-gain")); + + // Model name + const char *model_name = get_ru_xml_node(buffer, "model-name"); + if (strcasecmp(ru_vendor, "BENETEL") == 0 /* || strcmp(ru_vendor, "VVDN-LPRU") == 0 || strcmp(ru_vendor, "Metanoia") == 0 */) { - fix_benetel_setting(xran_mplane, interface_mtu, first_iq_width, max_num_ant); + fix_benetel_setting(xran_mplane, interface_mtu, first_iq_width, max_num_ant, model_name); } else { AssertError(false, return false, "[MPLANE] %s RU currently not supported.\n", ru_vendor); } @@ -109,7 +134,8 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ DU port ID %d\n\ Band sector ID %d\n\ CC ID %d\n\ - RU port ID %d\n", + RU port ID %d\n\ + max Tx gain %.1f\n", xran_mplane->ru_mac_addr, xran_mplane->mtu, xran_mplane->iq_width, @@ -121,7 +147,8 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ xran_mplane->du_port, xran_mplane->band_sector, xran_mplane->ccid, - xran_mplane->ru_port); + xran_mplane->ru_port, + xran_mplane->max_tx_gain); return true; } @@ -155,3 +182,23 @@ bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config) return true; } + +bool get_pm_object_list(const char *buffer, pm_stats_t *pm_stats) +{ + const char *ru_vendor = get_ru_xml_node(buffer, "mfg-name"); + if (strcasecmp(ru_vendor, "BENETEL") == 0) { + pm_stats->start_up_timing = false; + } else { + pm_stats->start_up_timing = true; + } + + // Rx window + get_ru_xml_list(buffer, "rx-window-objects", &pm_stats->rx_window_meas, &pm_stats->rx_num); + + // Tx + get_ru_xml_list(buffer, "tx-stats-objects", &pm_stats->tx_meas, &pm_stats->tx_num); + + MP_LOG_I("Successfully retreived all performance measurement names.\n"); + + return true; +} diff --git a/radio/fhi_72/mplane/ru-mplane-api.h b/radio/fhi_72/mplane/ru-mplane-api.h index 70857adea6..85fac5515c 100644 --- a/radio/fhi_72/mplane/ru-mplane-api.h +++ b/radio/fhi_72/mplane/ru-mplane-api.h @@ -57,6 +57,10 @@ typedef struct { uint8_t band_sector; uint8_t ccid; uint8_t ru_port; + int16_t frame_str; // might be needed in the future xran releases + bool managed_delay; + + double max_tx_gain; } xran_mplane_t; @@ -78,11 +82,26 @@ typedef struct { } ru_mplane_config_t; typedef struct { + // activation if required at start-up timing + bool start_up_timing; + + size_t rx_num; + char **rx_window_meas; + + size_t tx_num; + char **tx_meas; + +} pm_stats_t; + +typedef struct { + char *username; char *ru_ip_add; ru_mplane_config_t ru_mplane_config; void *session; + void *ctx; xran_mplane_t xran_mplane; ru_notif_t ru_notif; + pm_stats_t pm_stats; } ru_session_t; @@ -97,4 +116,6 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_ bool get_uplane_info(const char *buffer, ru_mplane_config_t *ru_mplane_config); +bool get_pm_object_list(const char *buffer, pm_stats_t *pm_stats); + #endif /* RU_MPLANE_API_H */ diff --git a/radio/fhi_72/mplane/subscribe-mplane.c b/radio/fhi_72/mplane/subscribe-mplane.c index 9a8e28c4c1..bec7e28a68 100644 --- a/radio/fhi_72/mplane/subscribe-mplane.c +++ b/radio/fhi_72/mplane/subscribe-mplane.c @@ -54,6 +54,37 @@ static void notif_clb_v1(struct nc_session *session, const struct nc_notif *noti recv_notif_v1(notif, answer); } #elif MPLANE_V2 +static void log_v2_pm_info(const char *ru_ip_add, struct lyd_node_inner *stats) +{ + struct lyd_node *child, *field = NULL; + size_t len = 0; + char *meas_list[8], *count_list[8] = {}; + + LY_LIST_FOR(stats->child, child) { + // const char *type = child->schema->name; // e.g. "rx-window-stats", "tx-stats" + struct lyd_node_inner *stats_inner = (struct lyd_node_inner *)child; + LY_LIST_FOR(stats_inner->child, field) { + if (strcmp(field->schema->name, "measurement-object") == 0) { + meas_list[len] = (char *)lyd_get_value(field); + } else if (strcmp(field->schema->name, "count") == 0) { + count_list[len] = (char *)lyd_get_value(field); + len++; + } + } + } + + MP_LOG_I("[PM: \"%s\"][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s][%s %7s]\n", + ru_ip_add, + meas_list[0], count_list[0], + meas_list[1], count_list[1], + meas_list[2], count_list[2], + meas_list[3], count_list[3], + meas_list[4], count_list[4], + meas_list[5], count_list[5], + meas_list[6], count_list[6], + meas_list[7], count_list[7]); +} + static void recv_notif_v2(struct lyd_node_inner *op, ru_notif_t *answer) { const char *notif = op->schema->name; @@ -92,9 +123,14 @@ static void notif_clb_v2(struct nc_session *session, const struct lyd_node *envp char *subs_reply = NULL; lyd_print_mem(&subs_reply, op, output_format, LYD_PRINT_WITHSIBLINGS); const char *ru_ip_add = nc_session_get_host(session); + struct lyd_node_inner *op_inner = (struct lyd_node_inner *)op; + if (strcmp(op_inner->schema->name, "measurement-result-stats") == 0) { + log_v2_pm_info(ru_ip_add, op_inner); + return; + } MP_LOG_I("Received notification from RU \"%s\" at (%s)\n%s\n", ru_ip_add, ((struct lyd_node_opaq *)lyd_child(envp))->value, subs_reply); - recv_notif_v2((struct lyd_node_inner *)op, answer); + recv_notif_v2(op_inner, answer); } #endif diff --git a/radio/fhi_72/mplane/xml/get-xml.c b/radio/fhi_72/mplane/xml/get-xml.c index 616d2e480f..6456219293 100644 --- a/radio/fhi_72/mplane/xml/get-xml.c +++ b/radio/fhi_72/mplane/xml/get-xml.c @@ -68,7 +68,8 @@ static void find_ru_xml_list(xmlNode *node, const char *filter, char ***match_li xmlNode *name_node = NULL; for (xmlNode *cur_node2 = cur_node->children; cur_node2; cur_node2 = cur_node2->next) { - if (cur_node2->type == XML_ELEMENT_NODE && strcmp((const char *)cur_node2->name, "name") == 0) { + const char *name_node_str = (const char *)cur_node2->name; + if (cur_node2->type == XML_ELEMENT_NODE && (strcmp(name_node_str, "name") == 0 || strcmp(name_node_str, "measurement-object") == 0)) { name_node = cur_node2; break; } diff --git a/radio/fhi_72/mplane/yang/create-yang-config.c b/radio/fhi_72/mplane/yang/create-yang-config.c index 7276b9fae0..187fe5b7c1 100644 --- a/radio/fhi_72/mplane/yang/create-yang-config.c +++ b/radio/fhi_72/mplane/yang/create-yang-config.c @@ -23,13 +23,14 @@ #include "common/utils/nr/nr_common.h" #define VERIFY_SUCCESS(var, message, args...) AssertError(var, return false, message, ##args) +const char *scs_name[] = {"KHZ_15", "KHZ_30", "KHZ_60", "KHZ_120", "KHZ_240", NULL}; #ifdef MPLANE_V2 -static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root) +static bool create_cu_interface_v2(const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root) { LY_ERR ret = LY_SUCCESS; - ret = lyd_new_path(NULL, *ctx, "/ietf-interfaces:interfaces", NULL, 0, root); + ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/ietf-interfaces:interfaces", NULL, 0, root); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"interfaces\" node.\n"); struct lyd_node *interface_node = NULL; @@ -43,7 +44,7 @@ static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_s ret = lyd_new_term(interface_node, NULL, "enabled", "true", 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"enabled\" node.\n"); - const struct lys_module *oran_int_mod = ly_ctx_get_module_implemented(*ctx, "o-ran-interfaces"); + const struct lys_module *oran_int_mod = ly_ctx_get_module_implemented((struct ly_ctx *)ru_session->ctx, "o-ran-interfaces"); VERIFY_SUCCESS(oran_int_mod != NULL, "[MPLANE] Failed to get \"o-ran-interfaces\" module.\n"); struct lyd_node *base_int = NULL; @@ -63,11 +64,11 @@ static bool create_cu_interface_v2(struct ly_ctx **ctx, const ru_session_t *ru_s return true; } -static bool create_proc_elem_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root) +static bool create_proc_elem_v2(const ru_session_t *ru_session, const size_t idx, const char *int_name, struct lyd_node **root) { LY_ERR ret = LY_SUCCESS; - ret = lyd_new_path(NULL, *ctx, "/o-ran-processing-element:processing-elements", NULL, 0, root); + ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/o-ran-processing-element:processing-elements", NULL, 0, root); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"processing-elements\" node.\n"); ret = lyd_new_term(*root, NULL, "transport-session-type", "ETH-INTERFACE", 0, NULL); @@ -104,20 +105,42 @@ static bool create_proc_elem_v2(struct ly_ctx **ctx, const ru_session_t *ru_sess return true; } -static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx, struct lyd_node **root) +typedef enum { UP_CH_RX, UP_CH_TX } uplane_dir_t; + +static LY_ERR fill_uplane_ch_common_v2(const uplane_dir_t dir, const xran_mplane_t *xran_mplane, const openair0_config_t *oai, const size_t idx, struct lyd_node **root) { LY_ERR ret = LY_SUCCESS; - ret = lyd_new_term(*root, NULL, "cp-length", "0", 0, NULL); + char frame_str[8]; + snprintf(frame_str, sizeof(frame_str), "%d", (oai->split7.fftSize << 4) + oai->nr_scs_for_raster); // 3GPP TS 38.211 + ret = lyd_new_term(*root, NULL, "frame-structure", frame_str, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"frame-structure\" node.\n"); + + // EXTENDED not supported + // 3GPP TS 38.211 + const char cp_type[] = "NORMAL"; + ret = lyd_new_term(*root, NULL, "cp-type", cp_type, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-type\" node.\n"); + + char cp_len[8]; + snprintf(cp_len, sizeof(cp_len), "%d", oai->split7.cp_prefix0); + ret = lyd_new_term(*root, NULL, "cp-length", cp_len, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-length\" node.\n"); - - ret = lyd_new_term(*root, NULL, "cp-length-other", "0", 0, NULL); + + char cp_len_other[8]; + snprintf(cp_len_other, sizeof(cp_len_other), "%d", oai->split7.cp_prefix_other); + ret = lyd_new_term(*root, NULL, "cp-length-other", cp_len_other, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"cp-length-other\" node.\n"); - - // to we actually store this from DU config file? - ret = lyd_new_term(*root, NULL, "offset-to-absolute-frequency-center", "0", 0, NULL); + + char freq_offset[8]; + if (dir == UP_CH_RX) { + snprintf(freq_offset, sizeof(freq_offset), "%d", oai->split7.ul_k0[oai->nr_scs_for_raster]); + } else { + snprintf(freq_offset, sizeof(freq_offset), "%d", oai->split7.dl_k0[oai->nr_scs_for_raster]); + } + ret = lyd_new_term(*root, NULL, "offset-to-absolute-frequency-center", freq_offset, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"offset-to-absolute-frequency-center\" node.\n"); - + struct lyd_node *compression_node = NULL; ret = lyd_new_inner(*root, NULL, "compression", 0, &compression_node); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression\" node.\n"); @@ -126,15 +149,15 @@ static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx snprintf(iq_width_str, sizeof(iq_width_str), "%d", xran_mplane->iq_width); ret = lyd_new_term(compression_node, NULL, "iq-bitwidth", iq_width_str, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"iq-bitwidth\" node.\n"); - + if (xran_mplane->iq_width < 16) { ret = lyd_new_term(compression_node, NULL, "compression-type", "STATIC", 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression-type\" node.\n"); - + // ret = lyd_new_term(compression_node, NULL, "compression-method", "BLOCK_FLOATING_POINT", 0, NULL); // VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"compression-method\" node.\n"); } - + struct lyd_node *eaxc_conf = NULL; ret = lyd_new_inner(*root, NULL, "e-axcid", 0, &eaxc_conf); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"e-axcid\" node.\n"); @@ -143,12 +166,12 @@ static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx snprintf(eaxc_id, sizeof(eaxc_id), "%ld", idx); ret = lyd_new_term(eaxc_conf, NULL, "eaxc-id", eaxc_id, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"eaxc-id\" node.\n"); - + char du_port_bitmask[16]; snprintf(du_port_bitmask, sizeof(du_port_bitmask), "%d", xran_mplane->du_port_bitmask); ret = lyd_new_term(eaxc_conf, NULL, "o-du-port-bitmask", du_port_bitmask, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"o-du-port-bitmask\" node.\n"); - + char band_sector_bitmask[8]; snprintf(band_sector_bitmask, sizeof(band_sector_bitmask), "%d", xran_mplane->band_sector_bitmask); ret = lyd_new_term(eaxc_conf, NULL, "band-sector-bitmask", band_sector_bitmask, 0, NULL); @@ -164,15 +187,50 @@ static bool fill_uplane_ch_v2(const xran_mplane_t *xran_mplane, const size_t idx ret = lyd_new_term(eaxc_conf, NULL, "ru-port-bitmask", ru_port_bitmask, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ru-port-bitmask\" node.\n"); + return LY_SUCCESS; +} + +static bool fill_uplane_ch_rx_v2(const xran_mplane_t *xran_mplane, const openair0_config_t *oai, const size_t idx, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + + ret = fill_uplane_ch_common_v2(UP_CH_RX, xran_mplane, oai, idx, root); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create common nodes.\n"); + + const char *managed_delay = xran_mplane->managed_delay ? "true" : "false"; + ret = lyd_new_term(*root, NULL, "non-time-managed-delay-enabled", managed_delay, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"non-time-managed-delay-enabled\" node.\n"); + + struct lyd_node *fft_offset = NULL; + ret = lyd_new_list(*root, NULL, "ul-fft-sampling-offsets", 0, &fft_offset, scs_name[oai->nr_scs_for_raster]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ul-fft-sampling-offsets\" node.\n"); + + // Note: set of allowed values is restricted by SCS derived from values in supported-frame-structures. + char ul_fft_offset[8]; + const int frame = (oai->split7.fftSize << 4) + oai->nr_scs_for_raster; + snprintf(ul_fft_offset, sizeof(ul_fft_offset), "%d", frame - xran_mplane->frame_str); + ret = lyd_new_term(fft_offset, NULL, "ul-fft-sampling-offset", ul_fft_offset, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"ul-fft-sampling-offset\" node.\n"); + return true; } -static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, const char *u_proc_elem, struct lyd_node **root) +static bool fill_uplane_ch_tx_v2(const xran_mplane_t *xran_mplane, const openair0_config_t *oai, const size_t idx, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + + ret = fill_uplane_ch_common_v2(UP_CH_TX, xran_mplane, oai, idx, root); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create common nodes.\n"); + + return true; +} + +static bool create_uplane_conf_v2(const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, const char *u_proc_elem, struct lyd_node **root) { LY_ERR ret = LY_SUCCESS; bool success = true; - ret = lyd_new_path(NULL, *ctx, "/o-ran-uplane-conf:user-plane-configuration", NULL, 0, root); + ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/o-ran-uplane-conf:user-plane-configuration", NULL, 0, root); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"user-plane-configuration\" node.\n"); if (ru_session->ru_mplane_config.rx_carriers.num != 1 || ru_session->ru_mplane_config.tx_carriers.num !=1) @@ -204,7 +262,8 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se ret = lyd_new_term(rx_carrier_node, NULL, "downlink-sfn-offset", "0", 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"downlink-sfn-offset\" node.\n"); - // oai->rx_gain_offset is this the correction? if yes, test it later + // gain offset applied uniformly across all array elements or layers + // needs to be within ret = lyd_new_term(rx_carrier_node, NULL, "gain-correction", "0", 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"gain-correction\" node.\n"); @@ -234,8 +293,12 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se ret = lyd_new_term(tx_carrier_node, NULL, "channel-bandwidth", tx_bw, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"channel-bandwidth\" node.\n"); - // oai->tx_gain to be tested - ret = lyd_new_term(tx_carrier_node, NULL, "gain", "0", 0, NULL); + // oai->tx_gain takes the value of att_tx from the RU section of gNB config file + // we assume the same gain is applied to all channels; same as above for the frequency + const double tx_gain_value = ((oai->tx_gain[0] * 10000) < ru_session->xran_mplane.max_tx_gain) ? (oai->tx_gain[0] * 10000) : ru_session->xran_mplane.max_tx_gain; + char tx_gain_str[8]; + snprintf(tx_gain_str, sizeof(tx_gain_str), "%.f", tx_gain_value); + ret = lyd_new_term(tx_carrier_node, NULL, "gain", tx_gain_str, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"gain\" node.\n"); ret = lyd_new_term(tx_carrier_node, NULL, "downlink-radio-frame-offset", "0", 0, NULL); @@ -254,7 +317,7 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se ret = lyd_new_list(*root, NULL, "low-level-rx-endpoints", 0, &pusch_node, ru_session->ru_mplane_config.rx_endpoints.name[i]); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoints\" node.\n"); - success = fill_uplane_ch_v2(&ru_session->xran_mplane, i, &pusch_node); + success = fill_uplane_ch_rx_v2(&ru_session->xran_mplane, oai, i, &pusch_node); VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-rx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.rx_endpoints.name[i]); const size_t prach_endpoint_name_offset = i + (ru_session->ru_mplane_config.rx_endpoints.num / 2); @@ -262,7 +325,7 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se ret = lyd_new_list(*root, NULL, "low-level-rx-endpoints", 0, &prach_node, ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset]); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-rx-endpoints\" node.\n"); - success = fill_uplane_ch_v2(&ru_session->xran_mplane, i + ru_session->xran_mplane.prach_offset, &prach_node); + success = fill_uplane_ch_rx_v2(&ru_session->xran_mplane, oai, i + ru_session->xran_mplane.prach_offset, &prach_node); VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-rx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.rx_endpoints.name[prach_endpoint_name_offset]); } @@ -273,7 +336,7 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se ret = lyd_new_list(*root, NULL, "low-level-tx-endpoints", 0, &pdsch_node, ru_session->ru_mplane_config.tx_endpoints.name[i]); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"low-level-tx-endpoints\" node.\n"); - success = fill_uplane_ch_v2(&ru_session->xran_mplane, i, &pdsch_node); + success = fill_uplane_ch_tx_v2(&ru_session->xran_mplane, oai, i, &pdsch_node); VERIFY_SUCCESS(success, "[MPLANE] Failed to fill \"low-level-tx-endpoints\" node for %s.\n", ru_session->ru_mplane_config.tx_endpoints.name[i]); } @@ -333,9 +396,59 @@ static bool create_uplane_conf_v2(struct ly_ctx **ctx, const ru_session_t *ru_se return true; } + +static +bool create_pm_conf_v2(const ru_session_t *ru_session, const char *active, struct lyd_node **root) +{ + LY_ERR ret = LY_SUCCESS; + + ret = lyd_new_path(NULL, (struct ly_ctx *)ru_session->ctx, "/o-ran-performance-management:performance-measurement-objects", NULL, 0, root); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create root \"performance-measurement-objects\" node.\n"); + + ret = lyd_new_term(*root, NULL, "notification-interval", "10", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"notification-interval\" node.\n"); + + ret = lyd_new_term(*root, NULL, "rx-window-measurement-interval", "10", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-window-measurement-interval\" node.\n"); + + ret = lyd_new_term(*root, NULL, "tx-measurement-interval", "10", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"tx-measurement-interval\" node.\n"); + + for (size_t i = 0; i < ru_session->pm_stats.rx_num; i++) { + struct lyd_node *rx_window_meas_objects = NULL; + ret = lyd_new_list(*root, NULL, "rx-window-measurement-objects", 0, &rx_window_meas_objects, ru_session->pm_stats.rx_window_meas[i]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"rx-window-measurement-objects\" node.\n"); + + ret = lyd_new_term(rx_window_meas_objects, NULL, "active", active, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"active\" node.\n"); + + ret = lyd_new_term(rx_window_meas_objects, NULL, "object-unit", "RU", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"object-unit\" node.\n"); + + ret = lyd_new_term(rx_window_meas_objects, NULL, "report-info", "COUNT", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"report-info\" node.\n"); + } + + for (size_t i = 0; i < ru_session->pm_stats.tx_num; i++) { + struct lyd_node *tx_meas_objects = NULL; + ret = lyd_new_list(*root, NULL, "tx-measurement-objects", 0, &tx_meas_objects, ru_session->pm_stats.tx_meas[i]); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"tx-measurement-objects\" node.\n"); + + ret = lyd_new_term(tx_meas_objects, NULL, "active", active, 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"active\" node.\n"); + + ret = lyd_new_term(tx_meas_objects, NULL, "object-unit", "RU", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"object-unit\" node.\n"); + + ret = lyd_new_term(tx_meas_objects, NULL, "report-info", "COUNT", 0, NULL); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"report-info\" node.\n"); + } + + return true; +} #endif -bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result) +bool configure_ru_from_yang(const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result) { bool success = false; @@ -357,12 +470,12 @@ bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, struct lyd_node *cu_interface = NULL; char int_name[12]; snprintf(int_name, sizeof(int_name), "INTERFACE_%ld", i); - success = create_cu_interface_v2(ctx, ru_session, i, int_name, &cu_interface); + success = create_cu_interface_v2(ru_session, i, int_name, &cu_interface); VERIFY_SUCCESS(success, "[MPLANE] Cannot create CU-plane interface.\n"); // struct lyd_node *proc_elem = NULL; - success = create_proc_elem_v2(ctx, ru_session, i, int_name, &proc_elem); + success = create_proc_elem_v2(ru_session, i, int_name, &proc_elem); VERIFY_SUCCESS(success, "[MPLANE] Cannot create CU-plane processing element.\n"); ret = lyd_merge_siblings(&all_merge, cu_interface, 0); @@ -376,17 +489,49 @@ bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, // struct lyd_node *uplane_conf = NULL; - success = create_uplane_conf_v2(ctx, ru_session, oai, num_rus, "PLANE_0", &uplane_conf); + success = create_uplane_conf_v2(ru_session, oai, num_rus, "PLANE_0", &uplane_conf); VERIFY_SUCCESS(success, "[MPLANE] Cannot create U-plane configuration.\n"); - - ret = lyd_merge_siblings(&uplane_conf, all_merge, 0); + + ret = lyd_merge_siblings(&all_merge, uplane_conf, 0); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge CU-plane interface, processing element and U-plane configuration.\n"); - lyd_print_mem(result, uplane_conf, LYD_XML, LYD_PRINT_WITHSIBLINGS); + // + struct lyd_node *pm_conf = NULL; + if (ru_session->pm_stats.start_up_timing) { + success = create_pm_conf_v2(ru_session, "true", &pm_conf); + VERIFY_SUCCESS(success, "[MPLANE] Cannot create PM activation.\n"); + } else { + success = create_pm_conf_v2(ru_session, "false", &pm_conf); + VERIFY_SUCCESS(success, "[MPLANE] Cannot create PM deactivation.\n"); + } + + ret = lyd_merge_siblings(&all_merge, pm_conf, 0); + VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Cannot merge CU-plane interface, processing element, U-plane configuration and PM configuration.\n"); + + lyd_print_mem(result, all_merge, LYD_XML, LYD_PRINT_WITHSIBLINGS); lyd_free_siblings(all_merge); lyd_free_siblings(uplane_conf); + lyd_free_siblings(pm_conf); #endif return true; } + +char *get_pm_content(const ru_session_t *ru_session, const char *active) +{ + bool success = false; + char *content = NULL; + +#ifdef MPLANE_V1 + VERIFY_SUCCESS(success, "[MPLANE] To be implemented and tested.\n"); +#elif defined MPLANE_V2 + struct lyd_node *pm_conf = NULL; + success = create_pm_conf_v2(ru_session, active, &pm_conf); + AssertError(success, return false, "[MPLANE] Cannot create PM configuration.\n"); + lyd_print_mem(&content, pm_conf, LYD_XML, LYD_PRINT_WITHSIBLINGS); + lyd_free_siblings(pm_conf); +#endif + + return content; +} diff --git a/radio/fhi_72/mplane/yang/create-yang-config.h b/radio/fhi_72/mplane/yang/create-yang-config.h index 9e06bdc923..2f03a3f774 100644 --- a/radio/fhi_72/mplane/yang/create-yang-config.h +++ b/radio/fhi_72/mplane/yang/create-yang-config.h @@ -27,6 +27,8 @@ #include -bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result); +bool configure_ru_from_yang(const ru_session_t *ru_session, const openair0_config_t *oai, const size_t num_rus, char **result); + +char *get_pm_content(const ru_session_t *ru_session, const char *active); #endif /* CREATE_MPLANE_YANG_CONFIG_H */ diff --git a/radio/fhi_72/mplane/yang/get-yang.c b/radio/fhi_72/mplane/yang/get-yang.c index c27454136f..60131b34cf 100644 --- a/radio/fhi_72/mplane/yang/get-yang.c +++ b/radio/fhi_72/mplane/yang/get-yang.c @@ -95,8 +95,10 @@ static bool load_from_operational_ds(xmlNode *node, ru_session_t *ru_session, st return false; } -bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ctx **ctx) +bool load_yang_models(ru_session_t *ru_session, const char *buffer) { + struct ly_ctx **ctx = (struct ly_ctx **)&ru_session->ctx; + // Initialize the xml file size_t len = strlen(buffer) + 1; xmlDoc *doc = xmlReadMemory(buffer, len, NULL, NULL, 0); @@ -114,7 +116,7 @@ bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ct 1) the yang models order is not good - the dependancy models have to be loaded first 2) earlier O-RAN yang versions (e.g. v4) is not properly defined (i.e. optional parameters should not be included by default) */ const char *yang_dir = YANG_MODELS; - const char *yang_models[] = {"ietf-interfaces", "iana-if-type", "ietf-ip", "iana-hardware", "ietf-hardware", "o-ran-interfaces", "o-ran-module-cap", "o-ran-compression-factors", "o-ran-processing-element", "o-ran-uplane-conf"}; + const char *yang_models[] = {"ietf-interfaces", "iana-if-type", "ietf-ip", "iana-hardware", "ietf-hardware", "o-ran-interfaces", "o-ran-module-cap", "o-ran-compression-factors", "o-ran-processing-element", "o-ran-uplane-conf", "ietf-netconf-acm", "ietf-crypto-types", "o-ran-file-management", "o-ran-performance-management"}; #ifdef MPLANE_V1 *ctx = ly_ctx_new(yang_dir, 0); diff --git a/radio/fhi_72/mplane/yang/get-yang.h b/radio/fhi_72/mplane/yang/get-yang.h index 5956bde203..7ca191d234 100644 --- a/radio/fhi_72/mplane/yang/get-yang.h +++ b/radio/fhi_72/mplane/yang/get-yang.h @@ -26,6 +26,6 @@ #include -bool load_yang_models(ru_session_t *ru_session, const char *buffer, struct ly_ctx **ctx); +bool load_yang_models(ru_session_t *ru_session, const char *buffer); #endif /* GET_MPLANE_YANG_MODELS_H */ diff --git a/radio/fhi_72/mplane/yang/models/ietf-crypto-types.yang b/radio/fhi_72/mplane/yang/models/ietf-crypto-types.yang new file mode 100644 index 0000000000..1b94b03176 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/ietf-crypto-types.yang @@ -0,0 +1,1783 @@ +module ietf-crypto-types { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-crypto-types"; + prefix ct; + + import ietf-yang-types { + prefix yang; + reference + "RFC 6991: Common YANG Data Types"; + } + + import ietf-netconf-acm { + prefix nacm; + reference + "RFC 8341: Network Configuration Access Control Model"; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + Author: Kent Watsen + Author: Wang Haiguang "; + + description + "This module defines common YANG types for cryptographic + applications. + + Copyright (c) 2019 IETF Trust and the persons identified + as authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with + or without modification, is permitted pursuant to, and + subject to the license terms contained in, the Simplified + BSD License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC XXXX + (https://www.rfc-editor.org/info/rfcXXXX); see the RFC + itself for full legal notices.; + + The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', + 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', + 'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document + are to be interpreted as described in BCP 14 (RFC 2119) + (RFC 8174) when, and only when, they appear in all + capitals, as shown here."; + + revision 2019-04-29 { + description + "Initial version"; + reference + "RFC XXXX: Common YANG Data Types for Cryptography"; + } + + /**************************************/ + /* Identities for Hash Algorithms */ + /**************************************/ + + identity hash-algorithm { + description + "A base identity for hash algorithm verification."; + } + + identity sha-224 { + base hash-algorithm; + description + "The SHA-224 algorithm."; + reference + "RFC 6234: US Secure Hash Algorithms."; + } + identity sha-256 { + base hash-algorithm; + description + "The SHA-256 algorithm."; + reference + "RFC 6234: US Secure Hash Algorithms."; + } + + identity sha-384 { + base hash-algorithm; + description + "The SHA-384 algorithm."; + reference + "RFC 6234: US Secure Hash Algorithms."; + } + + identity sha-512 { + base hash-algorithm; + description + "The SHA-512 algorithm."; + reference + "RFC 6234: US Secure Hash Algorithms."; + } + + /***********************************************/ + /* Identities for Asymmetric Key Algorithms */ + /***********************************************/ + + identity asymmetric-key-algorithm { + description + "Base identity from which all asymmetric key + encryption Algorithm."; + } + + identity rsa1024 { + base asymmetric-key-algorithm; + description + "The RSA algorithm using a 1024-bit key."; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity rsa2048 { + base asymmetric-key-algorithm; + description + "The RSA algorithm using a 2048-bit key."; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity rsa3072 { + base asymmetric-key-algorithm; + description + "The RSA algorithm using a 3072-bit key."; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity rsa4096 { + base asymmetric-key-algorithm; + description + "The RSA algorithm using a 4096-bit key."; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity rsa7680 { + base asymmetric-key-algorithm; + description + "The RSA algorithm using a 7680-bit key."; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity rsa15360 { + base asymmetric-key-algorithm; + description + "The RSA algorithm using a 15360-bit key."; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity secp192r1 { + base asymmetric-key-algorithm; + description + "The ECDSA algorithm using a NIST P256 Curve."; + reference + "RFC 6090: + Fundamental Elliptic Curve Cryptography Algorithms."; + } + identity secp224r1 { + base asymmetric-key-algorithm; + description + "The ECDSA algorithm using a NIST P256 Curve."; + reference + "RFC 6090: + Fundamental Elliptic Curve Cryptography Algorithms."; + } + + identity secp256r1 { + base asymmetric-key-algorithm; + description + "The ECDSA algorithm using a NIST P256 Curve."; + reference + "RFC 6090: + Fundamental Elliptic Curve Cryptography Algorithms."; + } + + identity secp384r1 { + base asymmetric-key-algorithm; + description + "The ECDSA algorithm using a NIST P256 Curve."; + reference + "RFC 6090: + Fundamental Elliptic Curve Cryptography Algorithms."; + } + + identity secp521r1 { + base asymmetric-key-algorithm; + description + "The ECDSA algorithm using a NIST P256 Curve."; + reference + "RFC 6090: + Fundamental Elliptic Curve Cryptography Algorithms."; + } + + /*************************************/ + /* Identities for MAC Algorithms */ + /*************************************/ + + identity mac-algorithm { + description + "A base identity for mac generation."; + } + + identity hmac-sha1 { + base mac-algorithm; + description + "Generating MAC using SHA1 hash function"; + reference + "RFC 3174: US Secure Hash Algorithm 1 (SHA1)"; + } + + identity hmac-sha1-96 { + base mac-algorithm; + description + "Generating MAC using SHA1 hash function"; + reference + "RFC 2404: The Use of HMAC-SHA-1-96 within ESP and AH"; + } + + identity hmac-sha2-224 { + base mac-algorithm; + description + "Generating MAC using SHA2 hash function"; + reference + "RFC 6234: + US Secure Hash Algorithms (SHA and SHA-based HMAC and + HKDF)"; + } + + identity hmac-sha2-256 { + base mac-algorithm; + description + "Generating MAC using SHA2 hash function"; + reference + "RFC 6234: + US Secure Hash Algorithms (SHA and SHA-based HMAC and + HKDF)"; + } + + identity hmac-sha2-256-128 { + base mac-algorithm; + description + "Generating a 256 bits MAC using SHA2 hash function and + truncate it to 128 bits"; + reference + "RFC 4868: + Using HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512 + with IPsec"; + } + + identity hmac-sha2-384 { + base mac-algorithm; + description + "Generating MAC using SHA2 hash function"; + reference + "RFC 6234: + US Secure Hash Algorithms (SHA and SHA-based HMAC and + HKDF)"; + } + + identity hmac-sha2-384-192 { + base mac-algorithm; + description + "Generating a 384 bits MAC using SHA2 hash function and + truncate it to 192 bits"; + reference + "RFC 4868: + Using HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512 with + IPsec"; + } + + identity hmac-sha2-512 { + base mac-algorithm; + description + "Generating MAC using SHA2 hash function"; + reference + "RFC 6234: + US Secure Hash Algorithms (SHA and SHA-based HMAC and + HKDF)"; + } + + identity hmac-sha2-512-256 { + base mac-algorithm; + description + "Generating a 512 bits MAC using SHA2 hash function and + truncating it to 256 bits"; + reference + "RFC 4868: + Using HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512 with + IPsec"; + } + + identity aes-128-gmac { + base mac-algorithm; + description + "Generating MAC using the Advanced Encryption Standard (AES) + Galois Message Authentication Code (GMAC) as a mechanism to + provide data origin authentication"; + reference + "RFC 4543: + The Use of Galois Message Authentication Code (GMAC) in + IPsec ESP and AH"; + } + + identity aes-192-gmac { + base mac-algorithm; + description + "Generating MAC using the Advanced Encryption Standard (AES) + Galois Message Authentication Code (GMAC) as a mechanism to + provide data origin authentication"; + reference + "RFC 4543: + The Use of Galois Message Authentication Code (GMAC) in + IPsec ESP and AH"; + } + + identity aes-256-gmac { + base mac-algorithm; + description + "Generating MAC using the Advanced Encryption Standard (AES) + Galois Message Authentication Code (GMAC) as a mechanism to + provide data origin authentication"; + reference + "RFC 4543: + The Use of Galois Message Authentication Code (GMAC) in + IPsec ESP and AH"; + } + + identity aes-cmac-96 { + base mac-algorithm; + description + "Generating MAC using Advanced Encryption Standard (AES) + Cipher-based Message Authentication Code (CMAC)"; + reference + "RFC 4494: The AES-CMAC-96 Algorithm and its Use with IPsec"; + } + + identity aes-cmac-128 { + base mac-algorithm; + description + "Generating MAC using Advanced Encryption Standard (AES) + Cipher-based Message Authentication Code (CMAC)"; + reference + "RFC 4493: The AES-CMAC Algorithm"; + } + + /********************************************/ + /* Identities for Encryption Algorithms */ + /********************************************/ + + identity encryption-algorithm { + description + "A base identity for encryption algorithm."; + } + + identity aes-128-cbc { + base encryption-algorithm; + description + "Encrypt message with AES algorithm in CBC mode with a key + length of 128 bits"; + reference + "RFC 3565: + Use of the Advanced Encryption Standard (AES) Encryption + Algorithm in Cryptographic Message Syntax (CMS)"; + } + + identity aes-192-cbc { + base encryption-algorithm; + description + "Encrypt message with AES algorithm in CBC mode with a key + length of 192 bits"; + reference + "RFC 3565: + Use of the Advanced Encryption Standard (AES) Encryption + Algorithm in Cryptographic Message Syntax (CMS)"; + } + + identity aes-256-cbc { + base encryption-algorithm; + description + "Encrypt message with AES algorithm in CBC mode with a key + length of 256 bits"; + reference + "RFC 3565: + Use of the Advanced Encryption Standard (AES) Encryption + Algorithm in Cryptographic Message Syntax (CMS)"; + } + + identity aes-128-ctr { + base encryption-algorithm; + description + "Encrypt message with AES algorithm in CTR mode with a key + length of 128 bits"; + reference + "RFC 3686: + Using Advanced Encryption Standard (AES) Counter Mode with + IPsec Encapsulating Security Payload (ESP)"; + } + identity aes-192-ctr { + base encryption-algorithm; + description + "Encrypt message with AES algorithm in CTR mode with a key + length of 192 bits"; + reference + "RFC 3686: + Using Advanced Encryption Standard (AES) Counter Mode with + IPsec Encapsulating Security Payload (ESP)"; + } + + identity aes-256-ctr { + base encryption-algorithm; + description + "Encrypt message with AES algorithm in CTR mode with a key + length of 256 bits"; + reference + "RFC 3686: + Using Advanced Encryption Standard (AES) Counter Mode with + IPsec Encapsulating Security Payload (ESP)"; + } + + /****************************************************/ + /* Identities for Encryption and MAC Algorithms */ + /****************************************************/ + + identity encryption-and-mac-algorithm { + description + "A base identity for encryption and MAC algorithm."; + } + + identity aes-128-ccm { + base encryption-and-mac-algorithm; + description + "Encrypt message with AES algorithm in CCM mode with a key + length of 128 bits; it can also be used for generating MAC"; + reference + "RFC 4309: + Using Advanced Encryption Standard (AES) CCM Mode with + IPsec Encapsulating Security Payload (ESP)"; + } + + identity aes-192-ccm { + base encryption-and-mac-algorithm; + description + "Encrypt message with AES algorithm in CCM mode with a key + length of 192 bits; it can also be used for generating MAC"; + reference + "RFC 4309: + Using Advanced Encryption Standard (AES) CCM Mode with + IPsec Encapsulating Security Payload (ESP)"; + } + + identity aes-256-ccm { + base encryption-and-mac-algorithm; + description + "Encrypt message with AES algorithm in CCM mode with a key + length of 256 bits; it can also be used for generating MAC"; + reference + "RFC 4309: + Using Advanced Encryption Standard (AES) CCM Mode with + IPsec Encapsulating Security Payload (ESP)"; + } + + identity aes-128-gcm { + base encryption-and-mac-algorithm; + description + "Encrypt message with AES algorithm in GCM mode with a key + length of 128 bits; it can also be used for generating MAC"; + reference + "RFC 4106: + The Use of Galois/Counter Mode (GCM) in IPsec Encapsulating + Security Payload (ESP)"; + } + + identity aes-192-gcm { + base encryption-and-mac-algorithm; + description + "Encrypt message with AES algorithm in GCM mode with a key + length of 192 bits; it can also be used for generating MAC"; + reference + "RFC 4106: + The Use of Galois/Counter Mode (GCM) in IPsec Encapsulating + Security Payload (ESP)"; + } + + identity mac-aes-256-gcm { + base encryption-and-mac-algorithm; + description + "Encrypt message with AES algorithm in GCM mode with a key + length of 128 bits; it can also be used for generating MAC"; + reference + "RFC 4106: + The Use of Galois/Counter Mode (GCM) in IPsec Encapsulating + Security Payload (ESP)"; + } + identity chacha20-poly1305 { + base encryption-and-mac-algorithm; + description + "Encrypt message with chacha20 algorithm and generate MAC with + POLY1305; it can also be used for generating MAC"; + reference + "RFC 8439: ChaCha20 and Poly1305 for IETF Protocols"; + } + + /******************************************/ + /* Identities for signature algorithm */ + /******************************************/ + + identity signature-algorithm { + description + "A base identity for asymmetric key encryption algorithm."; + } + + identity dsa-sha1 { + base signature-algorithm; + description + "The signature algorithm using DSA algorithm with SHA1 hash + algorithm"; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer Protocol"; + } + + identity rsassa-pkcs1-sha1 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PKCS1-v1_5 with the SHA1 + hash algorithm."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer Protocol"; + } + + identity rsassa-pkcs1-sha256 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PKCS1-v1_5 with the + SHA256 hash algorithm."; + reference + "RFC 8332: + Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell + (SSH) Protocol + RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + identity rsassa-pkcs1-sha384 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PKCS1-v1_5 with the + SHA384 hash algorithm."; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pkcs1-sha512 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PKCS1-v1_5 with the + SHA512 hash algorithm."; + reference + "RFC 8332: + Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell + (SSH) Protocol + RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pss-rsae-sha256 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PSS with mask generation + function 1 and SHA256 hash algorithm. If the public key is + carried in an X.509 certificate, it MUST use the rsaEncryption + OID"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pss-rsae-sha384 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PSS with mask generation + function 1 and SHA384 hash algorithm. If the public key is + carried in an X.509 certificate, it MUST use the rsaEncryption + OID"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pss-rsae-sha512 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PSS with mask generation + function 1 and SHA512 hash algorithm. If the public key is + carried in an X.509 certificate, it MUST use the rsaEncryption + OID"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pss-pss-sha256 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PSS with mask generation + function 1 and SHA256 hash algorithm. If the public key is + carried in an X.509 certificate, it MUST use the RSASSA-PSS + OID"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pss-pss-sha384 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PSS with mask generation + function 1 and SHA256 hash algorithm. If the public key is + carried in an X.509 certificate, it MUST use the RSASSA-PSS + OID"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity rsassa-pss-pss-sha512 { + base signature-algorithm; + description + "The signature algorithm using RSASSA-PSS with mask generation + function 1 and SHA256 hash algorithm. If the public key is + carried in an X.509 certificate, it MUST use the RSASSA-PSS + OID"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity ecdsa-secp256r1-sha256 { + base signature-algorithm; + description + "The signature algorithm using ECDSA with curve name secp256r1 + and SHA256 hash algorithm."; + reference + "RFC 5656: Elliptic Curve Algorithm Integration in the + Secure Shell Transport Layer + RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity ecdsa-secp384r1-sha384 { + base signature-algorithm; + description + "The signature algorithm using ECDSA with curve name secp384r1 + and SHA384 hash algorithm."; + reference + "RFC 5656: Elliptic Curve Algorithm Integration in the + Secure Shell Transport Layer + RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity ecdsa-secp521r1-sha512 { + base signature-algorithm; + description + "The signature algorithm using ECDSA with curve name secp521r1 + and SHA512 hash algorithm."; + reference + "RFC 5656: Elliptic Curve Algorithm Integration in the + Secure Shell Transport Layer + RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity ed25519 { + base signature-algorithm; + description + "The signature algorithm using EdDSA as defined in RFC 8032 or + its successors."; + reference + "RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA)"; + } + + identity ed448 { + base signature-algorithm; + description + "The signature algorithm using EdDSA as defined in RFC 8032 or + its successors."; + reference + "RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA)"; + } + + identity eccsi { + base signature-algorithm; + description + "The signature algorithm using ECCSI signature as defined in + RFC 6507."; + reference + "RFC 6507: + Elliptic Curve-Based Certificateless Signatures for + Identity-based Encryption (ECCSI)"; + } + + /**********************************************/ + /* Identities for key exchange algorithms */ + /**********************************************/ + + identity key-exchange-algorithm { + description + "A base identity for Diffie-Hellman based key exchange + algorithm."; + } + + identity psk-only { + base key-exchange-algorithm; + description + "Using Pre-shared key for authentication and key exchange"; + reference + "RFC 4279: + Pre-Shared Key cipher suites for Transport Layer Security + (TLS)"; + } + + identity dhe-ffdhe2048 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with 2048 bit + finite field"; + reference + "RFC 7919: + Negotiated Finite Field Diffie-Hellman Ephemeral Parameters + for Transport Layer Security (TLS)"; + } + + identity dhe-ffdhe3072 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with 3072 bit finite + field"; + reference + "RFC 7919: + Negotiated Finite Field Diffie-Hellman Ephemeral Parameters + for Transport Layer Security (TLS)"; + } + + identity dhe-ffdhe4096 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with 4096 bit + finite field"; + reference + "RFC 7919: + Negotiated Finite Field Diffie-Hellman Ephemeral Parameters + for Transport Layer Security (TLS)"; + } + + identity dhe-ffdhe6144 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with 6144 bit + finite field"; + reference + "RFC 7919: + Negotiated Finite Field Diffie-Hellman Ephemeral Parameters + for Transport Layer Security (TLS)"; + } + + identity dhe-ffdhe8192 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with 8192 bit + finite field"; + reference + "RFC 7919: + Negotiated Finite Field Diffie-Hellman Ephemeral Parameters + for Transport Layer Security (TLS)"; + } + + identity psk-dhe-ffdhe2048 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with Diffie-Hellman key + generation mechanism, where the DH group is FFDHE2048"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-dhe-ffdhe3072 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with Diffie-Hellman key + generation mechanism, where the DH group is FFDHE3072"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-dhe-ffdhe4096 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with Diffie-Hellman key + generation mechanism, where the DH group is FFDHE4096"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-dhe-ffdhe6144 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with Diffie-Hellman key + generation mechanism, where the DH group is FFDHE6144"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-dhe-ffdhe8192 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with Diffie-Hellman key + generation mechanism, where the DH group is FFDHE8192"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity ecdhe-secp256r1 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with elliptic group + over curve secp256r1"; + reference + "RFC 8422: + Elliptic Curve Cryptography (ECC) Cipher Suites for + Transport Layer Security (TLS) Versions 1.2 and Earlier"; + } + + identity ecdhe-secp384r1 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with elliptic group + over curve secp384r1"; + reference + "RFC 8422: + Elliptic Curve Cryptography (ECC) Cipher Suites for + Transport Layer Security (TLS) Versions 1.2 and Earlier"; + } + + identity ecdhe-secp521r1 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with elliptic group + over curve secp521r1"; + reference + "RFC 8422: + Elliptic Curve Cryptography (ECC) Cipher Suites for + Transport Layer Security (TLS) Versions 1.2 and Earlier"; + } + + identity ecdhe-x25519 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with elliptic group + over curve x25519"; + reference + "RFC 8422: + Elliptic Curve Cryptography (ECC) Cipher Suites for + Transport Layer Security (TLS) Versions 1.2 and Earlier"; + } + + identity ecdhe-x448 { + base key-exchange-algorithm; + description + "Ephemeral Diffie Hellman key exchange with elliptic group + over curve x448"; + reference + "RFC 8422: + Elliptic Curve Cryptography (ECC) Cipher Suites for + Transport Layer Security (TLS) Versions 1.2 and Earlier"; + } + + identity psk-ecdhe-secp256r1 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with elliptic group-based + Ephemeral Diffie Hellman key exchange over curve secp256r1"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-ecdhe-secp384r1 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with elliptic group-based + Ephemeral Diffie Hellman key exchange over curve secp384r1"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-ecdhe-secp521r1 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with elliptic group-based + Ephemeral Diffie Hellman key exchange over curve secp521r1"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-ecdhe-x25519 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with elliptic group-based + Ephemeral Diffie Hellman key exchange over curve x25519"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity psk-ecdhe-x448 { + base key-exchange-algorithm; + description + "Key exchange using pre-shared key with elliptic group-based + Ephemeral Diffie Hellman key exchange over curve x448"; + reference + "RFC 8446: + The Transport Layer Security (TLS) Protocol Version 1.3"; + } + + identity diffie-hellman-group14-sha1 { + base key-exchange-algorithm; + description + "Using DH group14 and SHA1 for key exchange"; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer Protocol"; + } + + identity diffie-hellman-group14-sha256 { + base key-exchange-algorithm; + description + "Using DH group14 and SHA256 for key exchange"; + reference + "RFC 8268: + More Modular Exponentiation (MODP) Diffie-Hellman (DH) + Key Exchange (KEX) Groups for Secure Shell (SSH)"; + } + + identity diffie-hellman-group15-sha512 { + base key-exchange-algorithm; + description + "Using DH group15 and SHA512 for key exchange"; + reference + "RFC 8268: + More Modular Exponentiation (MODP) Diffie-Hellman (DH) + Key Exchange (KEX) Groups for Secure Shell (SSH)"; + } + + identity diffie-hellman-group16-sha512 { + base key-exchange-algorithm; + description + "Using DH group16 and SHA512 for key exchange"; + reference + "RFC 8268: + More Modular Exponentiation (MODP) Diffie-Hellman (DH) + Key Exchange (KEX) Groups for Secure Shell (SSH)"; + } + + identity diffie-hellman-group17-sha512 { + base key-exchange-algorithm; + description + "Using DH group17 and SHA512 for key exchange"; + + reference + "RFC 8268: + More Modular Exponentiation (MODP) Diffie-Hellman (DH) + Key Exchange (KEX) Groups for Secure Shell (SSH)"; + } + + identity diffie-hellman-group18-sha512 { + base key-exchange-algorithm; + description + "Using DH group18 and SHA512 for key exchange"; + reference + "RFC 8268: + More Modular Exponentiation (MODP) Diffie-Hellman (DH) + Key Exchange (KEX) Groups for Secure Shell (SSH)"; + } + + identity ecdh-sha2-secp256r1 { + base key-exchange-algorithm; + description + "Elliptic curve-based Diffie Hellman key exchange over curve + secp256r1 and using SHA2 for MAC generation"; + reference + "RFC 6239: Suite B Cryptographic Suites for Secure Shell + (SSH)"; + } + + identity ecdh-sha2-secp384r1 { + base key-exchange-algorithm; + description + "Elliptic curve-based Diffie Hellman key exchange over curve + secp384r1 and using SHA2 for MAC generation"; + reference + "RFC 6239: Suite B Cryptographic Suites for Secure Shell + (SSH)"; + } + + identity rsaes-oaep { + base key-exchange-algorithm; + description + "RSAES-OAEP combines the RSAEP and RSADP primitives with the + EME-OAEP encoding method"; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + identity rsaes-pkcs1-v1_5 { + base key-exchange-algorithm; + description + " RSAES-PKCS1-v1_5 combines the RSAEP and RSADP primitives + with the EME-PKCS1-v1_5 encoding method"; + reference + "RFC 8017: + PKCS #1: RSA Cryptography Specifications Version 2.2."; + } + + /**********************************************************/ + /* Typedefs for identityrefs to above base identities */ + /**********************************************************/ + + typedef hash-algorithm-ref { + type identityref { + base hash-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'hash-algorithm' base identity."; + } + + typedef signature-algorithm-ref { + type identityref { + base signature-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'signature-algorithm' base identity."; + } + + typedef mac-algorithm-ref { + type identityref { + base mac-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'mac-algorithm' base identity."; + } + + typedef encryption-algorithm-ref { + type identityref { + base encryption-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'encryption-algorithm' + base identity."; + } + + typedef encryption-and-mac-algorithm-ref { + type identityref { + base encryption-and-mac-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'encryption-and-mac-algorithm' + base identity."; + } + + typedef asymmetric-key-algorithm-ref { + type identityref { + base asymmetric-key-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'asymmetric-key-algorithm' + base identity."; + } + + typedef key-exchange-algorithm-ref { + type identityref { + base key-exchange-algorithm; + } + description + "This typedef enables importing modules to easily define an + identityref to the 'key-exchange-algorithm' base identity."; + } + + /***************************************************/ + /* Typedefs for ASN.1 structures from RFC 5280 */ + /***************************************************/ + + typedef x509 { + type binary; + description + "A Certificate structure, as specified in RFC 5280, + encoded using ASN.1 distinguished encoding rules (DER), + as specified in ITU-T X.690."; + reference + "RFC 5280: + Internet X.509 Public Key Infrastructure Certificate + and Certificate Revocation List (CRL) Profile + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + + typedef crl { + type binary; + description + "A CertificateList structure, as specified in RFC 5280, + encoded using ASN.1 distinguished encoding rules (DER), + as specified in ITU-T X.690."; + reference + "RFC 5280: + Internet X.509 Public Key Infrastructure Certificate + and Certificate Revocation List (CRL) Profile + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + + /***********************************************/ + /* Typedefs for ASN.1 structures from 5652 */ + /***********************************************/ + + typedef cms { + type binary; + description + "A ContentInfo structure, as specified in RFC 5652, + encoded using ASN.1 distinguished encoding rules (DER), + as specified in ITU-T X.690."; + reference + "RFC 5652: + Cryptographic Message Syntax (CMS) + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + + typedef data-content-cms { + type cms; + description + "A CMS structure whose top-most content type MUST be the + data content type, as described by Section 4 in RFC 5652."; + reference + "RFC 5652: Cryptographic Message Syntax (CMS)"; + } + + typedef signed-data-cms { + type cms; + description + "A CMS structure whose top-most content type MUST be the + signed-data content type, as described by Section 5 in + RFC 5652."; + reference + "RFC 5652: Cryptographic Message Syntax (CMS)"; + } + + typedef enveloped-data-cms { + type cms; + description + "A CMS structure whose top-most content type MUST be the + enveloped-data content type, as described by Section 6 + in RFC 5652."; + reference + "RFC 5652: Cryptographic Message Syntax (CMS)"; + } + + typedef digested-data-cms { + type cms; + description + "A CMS structure whose top-most content type MUST be the + digested-data content type, as described by Section 7 + in RFC 5652."; + reference + "RFC 5652: Cryptographic Message Syntax (CMS)"; + } + + typedef encrypted-data-cms { + type cms; + description + "A CMS structure whose top-most content type MUST be the + encrypted-data content type, as described by Section 8 + in RFC 5652."; + reference + "RFC 5652: Cryptographic Message Syntax (CMS)"; + } + + typedef authenticated-data-cms { + type cms; + description + "A CMS structure whose top-most content type MUST be the + authenticated-data content type, as described by Section 9 + in RFC 5652."; + reference + "RFC 5652: Cryptographic Message Syntax (CMS)"; + } + + /***************************************************/ + /* Typedefs for structures related to RFC 4253 */ + /***************************************************/ + + typedef ssh-host-key { + type binary; + description + "The binary public key data for this SSH key, as + specified by RFC 4253, Section 6.6, i.e.: + + string certificate or public key format + identifier + byte[n] key/certificate data."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + } + + /*********************************************************/ + /* Typedefs for ASN.1 structures related to RFC 5280 */ + /*********************************************************/ + + typedef trust-anchor-cert-x509 { + type x509; + description + "A Certificate structure that MUST encode a self-signed + root certificate."; + } + + typedef end-entity-cert-x509 { + type x509; + description + "A Certificate structure that MUST encode a certificate + that is neither self-signed nor having Basic constraint + CA true."; + } + + /*********************************************************/ + /* Typedefs for ASN.1 structures related to RFC 5652 */ + /*********************************************************/ + + typedef trust-anchor-cert-cms { + type signed-data-cms; + description + "A CMS SignedData structure that MUST contain the chain of + X.509 certificates needed to authenticate the certificate + presented by a client or end-entity. + + The CMS MUST contain only a single chain of certificates. + The client or end-entity certificate MUST only authenticate + to last intermediate CA certificate listed in the chain. + + In all cases, the chain MUST include a self-signed root + certificate. In the case where the root certificate is + itself the issuer of the client or end-entity certificate, + only one certificate is present. + + This CMS structure MAY (as applicable where this type is + used) also contain suitably fresh (as defined by local + policy) revocation objects with which the device can + verify the revocation status of the certificates. + + This CMS encodes the degenerate form of the SignedData + structure that is commonly used to disseminate X.509 + certificates and revocation objects (RFC 5280)."; + reference + "RFC 5280: + Internet X.509 Public Key Infrastructure Certificate + and Certificate Revocation List (CRL) Profile."; + } + + typedef end-entity-cert-cms { + type signed-data-cms; + description + "A CMS SignedData structure that MUST contain the end + entity certificate itself, and MAY contain any number + of intermediate certificates leading up to a trust + anchor certificate. The trust anchor certificate + MAY be included as well. + + The CMS MUST contain a single end entity certificate. + The CMS MUST NOT contain any spurious certificates. + + This CMS structure MAY (as applicable where this type is + used) also contain suitably fresh (as defined by local + policy) revocation objects with which the device can + verify the revocation status of the certificates. + + This CMS encodes the degenerate form of the SignedData + structure that is commonly used to disseminate X.509 + certificates and revocation objects (RFC 5280)."; + reference + "RFC 5280: + Internet X.509 Public Key Infrastructure Certificate + and Certificate Revocation List (CRL) Profile."; + } + + /**********************************************/ + /* Groupings for keys and/or certificates */ + /**********************************************/ + + grouping public-key-grouping { + description + "A public key. + + The 'algorithm' and 'public-key' nodes are not + mandatory because they MAY be defined in . + Implementations SHOULD assert that these values are + either configured or that they exist in ."; + leaf algorithm { + nacm:default-deny-write; + type asymmetric-key-algorithm-ref; + must '../public-key'; + description + "Identifies the key's algorithm. More specifically, + this leaf specifies how the 'public-key' binary leaf + is encoded."; + reference + "RFC CCCC: Common YANG Data Types for Cryptography"; + } + leaf public-key { + nacm:default-deny-write; + type binary; + must '../algorithm'; + description + "A binary that contains the value of the public key. The + interpretation of the content is defined by the key + algorithm. For example, a DSA key is an integer, an RSA + key is represented as RSAPublicKey as defined in + RFC 8017, and an Elliptic Curve Cryptography (ECC) key + is represented using the 'publicKey' described in + RFC 5915."; + reference + "RFC 8017: Public-Key Cryptography Standards (PKCS) #1: + RSA Cryptography Specifications Version 2.2. + RFC 5915: Elliptic Curve Private Key Structure."; + } + } + + grouping asymmetric-key-pair-grouping { + description + "A private/public key pair. + The 'algorithm', 'public-key', and 'private-key' nodes are + not mandatory because they MAY be defined in . + Implementations SHOULD assert that these values are either + configured or that they exist in ."; + uses public-key-grouping; + leaf private-key { + nacm:default-deny-all; + type union { + type binary; + type enumeration { + enum permanently-hidden { + description + "The private key is inaccessible due to being + protected by the system (e.g., a cryptographic + hardware module). + + How such keys are backed-up and restored, if + at all, is implementation specific. + + Servers MUST fail any attempt by a client to + configure this value directly. This value is + not set by clients, but rather is set by the + 'generate-hidden-key' and 'install-hidden-key' + actions."; + } + } + } + must '../public-key'; + description + "A binary that contains the value of the private key. The + interpretation of the content is defined by the key + algorithm. For example, a DSA key is an integer, an RSA + key is represented as RSAPrivateKey as defined in + RFC 8017, and an Elliptic Curve Cryptography (ECC) key + is represented as ECPrivateKey as defined in RFC 5915."; + reference + "RFC 8017: Public-Key Cryptography Standards (PKCS) #1: + RSA Cryptography Specifications Version 2.2. + RFC 5915: Elliptic Curve Private Key Structure."; + } // private-key + + action generate-hidden-key { + nacm:default-deny-all; + description + "Requests the device to generate a hidden key using the + specified asymmetric key algorithm. This action is + used to request the system to generate a key that is + 'permanently-hidden', perhaps protected by a cryptographic + hardware module. The resulting asymmetric key values are + considered operational state and hence present only in + and bound to the lifetime of the parent + 'config true' node. Subsequent invocations of this or + the 'install-hidden-key' action are denied with error-tag + 'data-exists'."; + input { + leaf algorithm { + type asymmetric-key-algorithm-ref; + mandatory true; + description + "The algorithm to be used when generating the + asymmetric key."; + reference + "RFC CCCC: Common YANG Data Types for Cryptography"; + } + } + } // generate-hidden-key + + action install-hidden-key { + nacm:default-deny-all; + description + "Requests the device to load the specified values into + a hidden key. The resulting asymmetric key values are + considered operational state and hence present only in + and bound to the lifetime of the parent + 'config true' node. Subsequent invocations of this + or the 'generate-hidden-key' action are denied with + error-tag 'data-exists'."; + input { + leaf algorithm { + type asymmetric-key-algorithm-ref; + mandatory true; + description + "The algorithm to be used when generating the + asymmetric key."; + reference + "RFC CCCC: Common YANG Data Types for Cryptography"; + } + leaf public-key { + type binary; + description + "A binary that contains the value of the public key. + The interpretation of the content is defined by the key + algorithm. For example, a DSA key is an integer, an + RSA key is represented as RSAPublicKey as defined in + RFC 8017, and an Elliptic Curve Cryptography (ECC) key + is represented using the 'publicKey' described in + RFC 5915."; + reference + "RFC 8017: Public-Key Cryptography Standards (PKCS) #1: + RSA Cryptography Specifications Version 2.2. + RFC 5915: Elliptic Curve Private Key Structure."; + } + leaf private-key { + type binary; + description + "A binary that contains the value of the private key. + The interpretation of the content is defined by the key + algorithm. For example, a DSA key is an integer, an RSA + key is represented as RSAPrivateKey as defined in + RFC 8017, and an Elliptic Curve Cryptography (ECC) key + is represented as ECPrivateKey as defined in RFC 5915."; + reference + "RFC 8017: Public-Key Cryptography Standards (PKCS) #1: + RSA Cryptography Specifications Version 2.2. + RFC 5915: Elliptic Curve Private Key Structure."; + } + } + } // install-hidden-key + } // asymmetric-key-pair-grouping + + + grouping trust-anchor-cert-grouping { + description + "A trust anchor certificate, and a notification for when + it is about to (or already has) expire."; + leaf cert { + nacm:default-deny-write; + type trust-anchor-cert-cms; + description + "The binary certificate data for this certificate."; + reference + "RFC YYYY: Common YANG Data Types for Cryptography"; + } + notification certificate-expiration { + description + "A notification indicating that the configured certificate + is either about to expire or has already expired. When to + send notifications is an implementation specific decision, + but it is RECOMMENDED that a notification be sent once a + month for 3 months, then once a week for four weeks, and + then once a day thereafter until the issue is resolved."; + leaf expiration-date { + type yang:date-and-time; + mandatory true; + description + "Identifies the expiration date on the certificate."; + } + } + } + + grouping trust-anchor-certs-grouping { + description + "A list of trust anchor certificates, and a notification + for when one is about to (or already has) expire."; + leaf-list cert { + nacm:default-deny-write; + type trust-anchor-cert-cms; + description + "The binary certificate data for this certificate."; + reference + "RFC YYYY: Common YANG Data Types for Cryptography"; + } + notification certificate-expiration { + description + "A notification indicating that the configured certificate + is either about to expire or has already expired. When to + send notifications is an implementation specific decision, + but it is RECOMMENDED that a notification be sent once a + month for 3 months, then once a week for four weeks, and + then once a day thereafter until the issue is resolved."; + leaf expiration-date { + type yang:date-and-time; + mandatory true; + description + "Identifies the expiration date on the certificate."; + } + } + } + + grouping end-entity-cert-grouping { + description + "An end entity certificate, and a notification for when + it is about to (or already has) expire."; + leaf cert { + nacm:default-deny-write; + type end-entity-cert-cms; + description + "The binary certificate data for this certificate."; + reference + "RFC YYYY: Common YANG Data Types for Cryptography"; + } + notification certificate-expiration { + description + "A notification indicating that the configured certificate + is either about to expire or has already expired. When to + send notifications is an implementation specific decision, + but it is RECOMMENDED that a notification be sent once a + month for 3 months, then once a week for four weeks, and + then once a day thereafter until the issue is resolved."; + leaf expiration-date { + type yang:date-and-time; + mandatory true; + description + "Identifies the expiration date on the certificate."; + } + } + } + + grouping end-entity-certs-grouping { + description + "A list of end entity certificates, and a notification for + when one is about to (or already has) expire."; + leaf-list cert { + nacm:default-deny-write; + type end-entity-cert-cms; + description + "The binary certificate data for this certificate."; + reference + "RFC YYYY: Common YANG Data Types for Cryptography"; + } + notification certificate-expiration { + description + "A notification indicating that the configured certificate + is either about to expire or has already expired. When to + send notifications is an implementation specific decision, + but it is RECOMMENDED that a notification be sent once a + month for 3 months, then once a week for four weeks, and + then once a day thereafter until the issue is resolved."; + leaf expiration-date { + type yang:date-and-time; + mandatory true; + description + "Identifies the expiration date on the certificate."; + } + } + } + + grouping asymmetric-key-pair-with-cert-grouping { + description + "A private/public key pair and an associated certificate."; + uses asymmetric-key-pair-grouping; + uses end-entity-cert-grouping; + + action generate-certificate-signing-request { + nacm:default-deny-all; + description + "Generates a certificate signing request structure for + the associated asymmetric key using the passed subject + and attribute values. The specified assertions need + to be appropriate for the certificate's use. For + example, an entity certificate for a TLS server + SHOULD have values that enable clients to satisfy + RFC 6125 processing."; + input { + leaf subject { + type binary; + mandatory true; + description + "The 'subject' field per the CertificationRequestInfo + structure as specified by RFC 2986, Section 4.1 + encoded using the ASN.1 distinguished encoding + rules (DER), as specified in ITU-T X.690."; + reference + "RFC 2986: + PKCS #10: Certification Request Syntax + Specification Version 1.7. + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + leaf attributes { + type binary; + description + "The 'attributes' field from the structure + CertificationRequestInfo as specified by RFC 2986, + Section 4.1 encoded using the ASN.1 distinguished + encoding rules (DER), as specified in ITU-T X.690."; + reference + "RFC 2986: + PKCS #10: Certification Request Syntax + Specification Version 1.7. + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + } + output { + leaf certificate-signing-request { + type binary; + mandatory true; + description + "A CertificationRequest structure as specified by + RFC 2986, Section 4.2 encoded using the ASN.1 + distinguished encoding rules (DER), as specified + in ITU-T X.690."; + reference + "RFC 2986: + PKCS #10: Certification Request Syntax + Specification Version 1.7. + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + } + } // generate-certificate-signing-request + } // asymmetric-key-pair-with-cert-grouping + + + grouping asymmetric-key-pair-with-certs-grouping { + description + "A private/public key pair and associated certificates."; + uses asymmetric-key-pair-grouping; + container certificates { + nacm:default-deny-write; + description + "Certificates associated with this asymmetric key. + More than one certificate supports, for instance, + a TPM-protected asymmetric key that has both IDevID + and LDevID certificates associated."; + list certificate { + key "name"; + description + "A certificate for this asymmetric key."; + leaf name { + type string; + description + "An arbitrary name for the certificate. If the name + matches the name of a certificate that exists + independently in (i.e., an IDevID), + then the 'cert' node MUST NOT be configured."; + } + uses end-entity-cert-grouping; + } + } // certificates + + action generate-certificate-signing-request { + nacm:default-deny-all; + description + "Generates a certificate signing request structure for + the associated asymmetric key using the passed subject + and attribute values. The specified assertions need + to be appropriate for the certificate's use. For + example, an entity certificate for a TLS server + SHOULD have values that enable clients to satisfy + RFC 6125 processing."; + input { + leaf subject { + type binary; + mandatory true; + description + "The 'subject' field per the CertificationRequestInfo + structure as specified by RFC 2986, Section 4.1 + encoded using the ASN.1 distinguished encoding + rules (DER), as specified in ITU-T X.690."; + reference + "RFC 2986: + PKCS #10: Certification Request Syntax + Specification Version 1.7. + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + leaf attributes { + type binary; + description + "The 'attributes' field from the structure + CertificationRequestInfo as specified by RFC 2986, + Section 4.1 encoded using the ASN.1 distinguished + encoding rules (DER), as specified in ITU-T X.690."; + reference + "RFC 2986: + PKCS #10: Certification Request Syntax + Specification Version 1.7. + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + } + output { + leaf certificate-signing-request { + type binary; + mandatory true; + description + "A CertificationRequest structure as specified by + RFC 2986, Section 4.2 encoded using the ASN.1 + distinguished encoding rules (DER), as specified + in ITU-T X.690."; + reference + "RFC 2986: + PKCS #10: Certification Request Syntax + Specification Version 1.7. + ITU-T X.690: + Information technology - ASN.1 encoding rules: + Specification of Basic Encoding Rules (BER), + Canonical Encoding Rules (CER) and Distinguished + Encoding Rules (DER)."; + } + } + } // generate-certificate-signing-request + } // asymmetric-key-pair-with-certs-grouping +} diff --git a/radio/fhi_72/mplane/yang/models/ietf-netconf-acm.yang b/radio/fhi_72/mplane/yang/models/ietf-netconf-acm.yang new file mode 100644 index 0000000000..ec9687a9d7 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/ietf-netconf-acm.yang @@ -0,0 +1,440 @@ +module ietf-netconf-acm { + + namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm"; + + prefix nacm; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + Author: Andy Bierman + + Author: Martin Bjorklund + "; + + description + "Network Configuration Access Control Model. + Copyright (c) 2012 - 2018 IETF Trust and the persons + identified as authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 8341; see + the RFC itself for full legal notices."; + + revision "2018-02-14" { + description + "Added support for YANG 1.1 actions and notifications tied to + data nodes. Clarified how NACM extensions can be used by + other data models."; + reference + "RFC 8341: Network Configuration Access Control Model"; + } + + revision "2012-02-22" { + description + "Initial version."; + reference + "RFC 6536: Network Configuration Protocol (NETCONF) + Access Control Model"; + } + + /* + * Extension statements + */ + + extension default-deny-write { + description + "Used to indicate that the data model node + represents a sensitive security system parameter. + If present, the NETCONF server will only allow the designated + 'recovery session' to have write access to the node. An + explicit access control rule is required for all other users. + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + The 'default-deny-write' extension MAY appear within a data + definition statement. It is ignored otherwise."; + } + + extension default-deny-all { + description + "Used to indicate that the data model node + controls a very sensitive security system parameter. + If present, the NETCONF server will only allow the designated + 'recovery session' to have read, write, or execute access to + the node. An explicit access control rule is required for all + other users. + If the NACM module is used, then it must be enabled (i.e., + /nacm/enable-nacm object equals 'true'), or this extension + is ignored. + The 'default-deny-all' extension MAY appear within a data + definition statement, 'rpc' statement, or 'notification' + statement. It is ignored otherwise."; + } + + /* + * Derived types + */ + + typedef user-name-type { + type string { + length "1..max"; + } + description + "General-purpose username string."; + } + + typedef matchall-string-type { + type string { + pattern '\*'; + } + description + "The string containing a single asterisk '*' is used + to conceptually represent all possible values + for the particular leaf using this data type."; + } + + typedef access-operations-type { + type bits { + bit create { + description + "Any protocol operation that creates a + new data node."; + } + bit read { + description + "Any protocol operation or notification that + returns the value of a data node."; + } + bit update { + description + "Any protocol operation that alters an existing + data node."; + } + bit delete { + description + "Any protocol operation that removes a data node."; + } + bit exec { + description + "Execution access to the specified protocol operation."; + } + } + description + "Access operation."; + } + + typedef group-name-type { + type string { + length "1..max"; + pattern '[^\*].*'; + } + description + "Name of administrative group to which + users can be assigned."; + } + + typedef action-type { + type enumeration { + enum permit { + description + "Requested action is permitted."; + } + enum deny { + description + "Requested action is denied."; + } + } + description + "Action taken by the server when a particular + rule matches."; + } + + typedef node-instance-identifier { + type yang:xpath1.0; + description + "Path expression used to represent a special + data node, action, or notification instance-identifier + string. + A node-instance-identifier value is an + unrestricted YANG instance-identifier expression. + All the same rules as an instance-identifier apply, + except that predicates for keys are optional. If a key + predicate is missing, then the node-instance-identifier + represents all possible server instances for that key. + This XML Path Language (XPath) expression is evaluated in the + following context: + o The set of namespace declarations are those in scope on + the leaf element where this type is used. + o The set of variable bindings contains one variable, + 'USER', which contains the name of the user of the + current session. + o The function library is the core function library, but + note that due to the syntax restrictions of an + instance-identifier, no functions are allowed. + o The context node is the root node in the data tree. + The accessible tree includes actions and notifications tied + to data nodes."; + } + + /* + * Data definition statements + */ + + container nacm { + nacm:default-deny-all; + + description + "Parameters for NETCONF access control model."; + + leaf enable-nacm { + type boolean; + default "true"; + description + "Enables or disables all NETCONF access control + enforcement. If 'true', then enforcement + is enabled. If 'false', then enforcement + is disabled."; + } + + leaf read-default { + type action-type; + default "permit"; + description + "Controls whether read access is granted if + no appropriate rule is found for a + particular read request."; + } + + leaf write-default { + type action-type; + default "deny"; + description + "Controls whether create, update, or delete access + is granted if no appropriate rule is found for a + particular write request."; + } + + leaf exec-default { + type action-type; + default "permit"; + description + "Controls whether exec access is granted if no appropriate + rule is found for a particular protocol operation request."; + } + + leaf enable-external-groups { + type boolean; + default "true"; + description + "Controls whether the server uses the groups reported by the + NETCONF transport layer when it assigns the user to a set of + NACM groups. If this leaf has the value 'false', any group + names reported by the transport layer are ignored by the + server."; + } + + leaf denied-operations { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request was denied."; + } + + leaf denied-data-writes { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request to alter + a configuration datastore was denied."; + } + + leaf denied-notifications { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that + a notification was dropped for a subscription because + access to the event type was denied."; + } + + container groups { + description + "NETCONF access control groups."; + + list group { + key name; + + description + "One NACM group entry. This list will only contain + configured entries, not any entries learned from + any transport protocols."; + + leaf name { + type group-name-type; + description + "Group name associated with this entry."; + } + + leaf-list user-name { + type user-name-type; + description + "Each entry identifies the username of + a member of the group associated with + this entry."; + } + } + } + + list rule-list { + key name; + ordered-by user; + description + "An ordered collection of access control rules."; + + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule-list."; + } + leaf-list group { + type union { + type matchall-string-type; + type group-name-type; + } + description + "List of administrative groups that will be + assigned the associated access rights + defined by the 'rule' list. + The string '*' indicates that all groups apply to the + entry."; + } + + list rule { + key name; + ordered-by user; + description + "One access control rule. + Rules are processed in user-defined order until a match is + found. A rule matches if 'module-name', 'rule-type', and + 'access-operations' match the request. If a rule + matches, the 'action' leaf determines whether or not + access is granted."; + + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule."; + } + + leaf module-name { + type union { + type matchall-string-type; + type string; + } + default "*"; + description + "Name of the module associated with this rule. + This leaf matches if it has the value '*' or if the + object being accessed is defined in the module with the + specified module name."; + } + choice rule-type { + description + "This choice matches if all leafs present in the rule + match the request. If no leafs are present, the + choice matches all requests."; + case protocol-operation { + leaf rpc-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if + its value equals the requested protocol operation + name."; + } + } + case notification { + leaf notification-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if its + value equals the requested notification name."; + } + } + + case data-node { + leaf path { + type node-instance-identifier; + mandatory true; + description + "Data node instance-identifier associated with the + data node, action, or notification controlled by + this rule. + Configuration data or state data + instance-identifiers start with a top-level + data node. A complete instance-identifier is + required for this type of path value. + The special value '/' refers to all possible + datastore contents."; + } + } + } + + leaf access-operations { + type union { + type matchall-string-type; + type access-operations-type; + } + default "*"; + description + "Access operations associated with this rule. + This leaf matches if it has the value '*' or if the + bit corresponding to the requested operation is set."; + } + + leaf action { + type action-type; + mandatory true; + description + "The access control action associated with the + rule. If a rule has been determined to match a + particular request, then this object is used + to determine whether to permit or deny the + request."; + } + + leaf comment { + type string; + description + "A textual description of the access rule."; + } + } + } + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-file-management.yang b/radio/fhi_72/mplane/yang/models/o-ran-file-management.yang new file mode 100644 index 0000000000..ee07645a44 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-file-management.yang @@ -0,0 +1,213 @@ +module o-ran-file-management { + yang-version 1.1; + namespace "urn:o-ran:file-management:1.0"; + prefix "o-ran-file-mgmt"; + + import ietf-crypto-types { + prefix "ct"; + } + + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the configuration and operations for handling upload. + + Copyright 2019 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2019-07-03" { + description + "version 1.1.0 + + 1) backward compatible changes to correct sFTP Server Authentication . + 2) minor fixes according to lack of descriptions + 3) backward compatible changes to introduce groupings"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + grouping file-path-grouping { + description "Complete logical path of the file to upload/download + (no wildcard is allowed) ex : /o-RAN/log/syslog.1"; + + leaf local-logical-file-path { + type string; + mandatory true; + description "Local logical file path"; + } + + leaf remote-file-path { + type string; + mandatory true; + description "URI specifying the remote-file-path on O-DU/NMS. + Format:sftp://@[:port]/path"; + } + } + + grouping output-status-grouping { + description "Status grouping"; + + leaf status { + type enumeration { + enum SUCCESS { + description "";} + enum FAILURE { + description "";} + } + description "Operation status"; + } + + leaf reject-reason { + when "../status = 'FAILURE'"; + type string; + description ""; + } + } + + grouping credential-information { + description "Type of authentication to use for SFTP upload or download."; + choice credentials { + case password { + container password { + presence true; + leaf password { + type string; + mandatory true; + description + "password needed for O-RU authentication."; + } + description + "password for O-RU authentication method in use"; + } + container server { + list keys { + key algorithm; + ordered-by user; + uses ct:public-key-grouping; + description + "List of allowed algorithms with its keys"; + } + description + "Key for sFTP server authentication"; + } + } + case certificate { + container certificate { + presence true; + description + "certificate authentication method in use"; + } + } + description ""; + } + } + + grouping retrieve-input { + description "Grouping for information retrieval RPC input"; + leaf logical-path { + type string; + mandatory true; + description "O-RAN unit of which the files are to be listed. + ex : O-RAN/log, o-RAN/PM, O-RAN/transceiver"; + } + leaf file-name-filter { + type string; + description "Filter which are to be applied on the result list of file names (* is allowed as wild-card)."; + } + } + + grouping retrieve-output { + description "Grouping for information retrieval RPC output"; + uses output-status-grouping; + leaf-list file-list { + when "../status = 'SUCCESS'"; + type string; + description "List of files in the unit with the filter applied."; + } + } + +// RPCs + + rpc file-upload { + description "File upload over SFTP from equipment to NETCONF client"; + input { + uses file-path-grouping; + uses credential-information; + } + output { + uses output-status-grouping; + } + } + + rpc retrieve-file-list { + description "List all the files in the logical O-RAN unit (* is allowed as wild-card)."; + input { + uses retrieve-input; + + } + output { + uses retrieve-output; + } + } + + notification file-upload-notification { + uses file-path-grouping; + uses output-status-grouping; + description ""; + } + + rpc file-download { + description + "Management plane triggered to generate the download file of O-RU."; + input { + uses file-path-grouping; + uses credential-information; + } + output { + uses output-status-grouping; + } + } + + notification file-download-event { + uses file-path-grouping; + uses output-status-grouping; + description ""; + } +} diff --git a/radio/fhi_72/mplane/yang/models/o-ran-performance-management.yang b/radio/fhi_72/mplane/yang/models/o-ran-performance-management.yang new file mode 100644 index 0000000000..fb8298f663 --- /dev/null +++ b/radio/fhi_72/mplane/yang/models/o-ran-performance-management.yang @@ -0,0 +1,1168 @@ +module o-ran-performance-management { + yang-version 1.1; + namespace "urn:o-ran:performance-management:1.0"; + prefix "o-ran-pm"; + + import ietf-yang-types { + prefix "yang-types"; + revision-date 2013-07-15; + } + + // import idetifier for O-RU + import ietf-hardware { + prefix "hw"; + } + + // import ietf-interface + import ietf-interfaces { + prefix "if"; + } + + // import ietf-inet-type + import ietf-inet-types { + prefix "inet"; + } + + // import port-number + import o-ran-interfaces { + prefix "o-ran-int"; + } + + // import ru-mac-address, o-du-mac-address and vlan-id + import o-ran-processing-element { + prefix "o-ran-elements"; + } + + import o-ran-file-management { + prefix "o-ran-fm"; + } + + import iana-hardware { + prefix ianahw; + } + + organization "O-RAN Alliance"; + + contact + "www.o-ran.org"; + + description + "This module defines the configuration for performance measurement for + transceiver and rx-window measurement objects. + + NOTE, whereas this YANG model may define support of schema nodes associated + with O-RU measurements as optional, the CU-Plane specification may further + specify whether, according to a particular version of the CU plane + specification, which specific measurements are mandatory to support + from an O-RU perspective. In such a situation, the definition of mandatory + performance counters in sub-section 7.1 of the CU-plane specification shall + take precedence. + + Copyright 2020 the O-RAN Alliance. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the above disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the above disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the Members of the O-RAN Alliance nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission."; + + revision "2020-04-17" { + description + "version 3.0.0 + + 1) updated top level model description concerning optionality of measurements + 2) added new rx window counters + 3) added new TX stats measurements + 4) added new EPE measurements + 5) fixed typo in enumeration - TX_POPWER + 6) introduced config false data indicating which type of measurmeents are supported"; + + reference "ORAN-WG4.M.0-v03.00"; + } + + revision "2019-07-03" { + description + "version 2.0.0 + + 1) added new measurement objects for QSFP + 2) backward compatible changes to correct sFTP Server Authentication. + 3) simplifying file management and authentication to reuse from o-ran-file-management module + 4) minor fixes according to lack of descriptions and reference + 5) added to descriptions to indicate applicability of leafs and Containers + to separate O-RAN use cases + 6) backward compatible changes to introduce groupings."; + + reference "ORAN-WG4.M.0-v02.00"; + } + + revision "2019-02-04" { + description + "version 1.0.0 + + 1) imported model from xRAN + 2) changed namespace and reference from xran to o-ran"; + + reference "ORAN-WG4.M.0-v01.00"; + } + + + feature GRANULARITY-TRANSPORT-MEASUREMENT { + description + "This feature indicates that the O-RU supports an optional object-unit TRANSPORT in rx-window-measurement."; + } + + feature GRANULARITY-EAXC-ID-MEASUREMENT { + description + "This feature indicates that the O-RU supports an optional object-unit EAXC_ID in rx-window-measurement."; + } + + grouping start-and-end-time { + description + "Definition for start and end time for an event"; + + leaf start-time { + type yang-types:date-and-time; + description + "Start time for measurement of object stats"; + } + leaf end-time { + type yang-types:date-and-time; + description + "End time for measurement of object stats"; + } + } + + grouping epe-measurement-result-grouping { + description + "energy, power and environmental measurement-result are listed for O-RU"; + + list epe-measurement-result { + key "object-unit-id"; + config false; + leaf object-unit-id { + type leafref { + path "/hw:hardware/hw:component/hw:class"; + } + + description + "the hardware component type is used for the object-unit-id for the + EPE measurements. For example, the object-unit-id will be set to + or-hw:O-RAN-RADIO if the measurement applies to the complete O-RU + self-contained sub-system. + + Other hardware-classes include: or-hw:O-RU-POWER-AMPLIFIER, + ianahw:power-supply, ianahw:fan, ianahw:cpu"; + } + leaf min { + type decimal64 { + fraction-digits 4; + } + + description + "minimum value for the measurment-object"; + } + leaf max { + type decimal64 { + fraction-digits 4; + } + description + "maximum value for the measurment-object"; + } + leaf average { + type decimal64 { + fraction-digits 4; + } + description + "average value of the measurement-object"; + } + } + } + + grouping transceiver-measurement-result-grouping { + description + "transceiver-measurement-result are listed per port-number"; + + list transceiver-measurement-result { + key "object-unit-id"; + config false; + leaf object-unit-id { + type leafref { + path "/if:interfaces/if:interface/o-ran-int:port-reference/o-ran-int:port-number"; + } + + description + "port-number is used for the object-unit-id for the + transceiver-measurement-result, for which object-unit is + PORT_NUMBER only"; + } + container min { + description + "minimum value with recorded time are included for the + measurement-object"; + + leaf value { + type decimal64 { + fraction-digits 4; + } + + description + "minimum value for the measurment-object"; + } + leaf time { + type yang-types:date-and-time; + + description + "recorded time for the minimum value"; + } + } + container max { + description + "maximum value with recorded time are included for the + measurement-object"; + + leaf value { + type decimal64 { + fraction-digits 4; + } + + description + "maximum value for the measurment-object"; + } + leaf time { + type yang-types:date-and-time; + + description + "recorded time for the maximum value"; + } + } + container first { + description + "first value with the recorded time are included for the + measurement-object"; + + leaf value { + type decimal64 { + fraction-digits 4; + } + + description + "first value of the measurement-object"; + } + leaf time { + type yang-types:date-and-time; + + description + "recorded time for the first value"; + } + } + container latest { + description + "latest value with the recorded time are included for the + measurement-object"; + + leaf value { + type decimal64 { + fraction-digits 4; + } + + description + "latest value of the measurement-object"; + } + leaf time { + type yang-types:date-and-time; + + description + "recorded time for the latest value"; + } + } + leaf-list frequeny-table { + type uint32; + + description + "frequency-table for the measurment-object are included per bin. + The configuration parameters for this frequency-table are defined + by bin-count, lower-bound and upper-bound"; + } + + description + "List of transceiver measurement results"; + } + } + + grouping rx-window-measurement-result-grouping{ + description + "Group of measurement reasults for rx window measurements"; + + choice object-unit-id { + config false; + case RU { + leaf name{ + type leafref { + path "/hw:hardware/hw:component/hw:name"; + } + + description + "the name of O-RU module or one of its child ports + in ietf-hardware/component is used when O-RU is selected as + object-unit for the reception window stats."; + } + leaf count { + type uint64; + mandatory true; + + description + "the number of data packet are counted for the reception + window stats per O-RU."; + } + } + + case TRANSPORT { + list tr-measured-result{ + leaf name{ + type leafref{ + path "/o-ran-elements:processing-elements/o-ran-elements:ru-elements/o-ran-elements:name"; + } + + description + "the name of ru-elements in o-ran-processing-elements + when TRANSPORT is selected as object-unit for the reception + window stats."; + } + leaf count { + type uint64; + mandatory true; + + description + "the number of data packet are counted for the reception + window stats."; + } + + description + "the number of data packet are counted for the reception + window stats per TRANSPORT."; + } + } + + case EAXC_ID { + list eaxc-measured-result { + leaf eaxc-id{ + type uint16; + + description + "eaxc-id is used + when EAXC_ID is selected as object-unit for the reception + window stats. + EAXC_ID consists of DU-Port-Id, Band-Selector, CC-id and + RU-Port-Id to be used in header of C/U-plane data packet."; + } + leaf count { + type uint64; + mandatory true; + + description + "the number of data packet are counted for the reception + window stats."; + } + leaf transport-name { + type leafref{ + path "/o-ran-elements:processing-elements/o-ran-elements:ru-elements/o-ran-elements:name"; + } + + description + "the name of ru-elements in o-ran-processing-elements for the + transport information corresponding to this eaxc-id"; + } + + description + "the number of data packet are counted for the reception + window stats per EAXC-ID."; + } + } + + description + "measurement-result for the reception window stats depends on the + configured object-unit, RU, TRANSPORT or EAXC_ID"; + } + } + + grouping tx-measurement-result-grouping{ + description + "Group of measurement reasults for tx stats"; + + choice object-unit-id { + config false; + case RU { + leaf name{ + type leafref { + path "/hw:hardware/hw:component/hw:name"; + } + + description + "the name of O-RU module or one of its child ports + in ietf-hardware/component is used when O-RU is selected as + object-unit for the reception window stats."; + } + leaf count { + type uint64; + mandatory true; + + description + "the number of data packet are counted for the tx stats per O-RU."; + } + } + + case TRANSPORT { + list tr-measured-result{ + leaf name{ + type leafref{ + path "/o-ran-elements:processing-elements/o-ran-elements:ru-elements/o-ran-elements:name"; + } + + description + "the name of ru-elements in o-ran-processing-elements + when TRANSPORT is selected as object-unit for the tx stats."; + } + leaf count { + type uint64; + mandatory true; + + description + "the number of data packet are counted for the tx stats."; + } + + description + "the number of data packet are counted for the tx stats per TRANSPORT."; + } + } + + case EAXC_ID { + list eaxc-measured-result { + leaf eaxc-id{ + type uint16; + + description + "eaxc-id is used + when EAXC_ID is selected as object-unit for the tx stats. + EAXC_ID consists of DU-Port-Id, Band-Selector, CC-id and + RU-Port-Id to be used in header of C/U-plane data packet."; + } + leaf count { + type uint64; + mandatory true; + + description + "the number of data packet are counted for the tx stats."; + } + leaf transport-name { + type leafref{ + path "/o-ran-elements:processing-elements/o-ran-elements:ru-elements/o-ran-elements:name"; + } + + description + "the name of ru-elements in o-ran-processing-elements for the + transport information corresponding to this eaxc-id"; + } + + description + "the number of data packet are counted for the tx stats per EAXC-ID."; + } + } + + description + "measurement-result for the tx stats depends on the + configured object-unit, RU, TRANSPORT or EAXC_ID"; + } + } + + + grouping measurement-group { + description + "Group of measurement results"; + + uses measurement-capabilities; + leaf enable-SFTP-upload { + type boolean; + default false; + description + "Flag to enable upload of performance measurement result files."; + } + + leaf enable-random-file-upload { + type boolean; + default false; + description + "Flag to enable upload of performance measurement result files at + random within file-upload-interval."; + } + + list remote-SFTP-uploads { + key remote-SFTP-upload-path; + description + "SFTP upload can be done to one or more than one SFTP servers"; + + leaf remote-SFTP-upload-path { + type inet:uri; + description + "URI specifying the remote location where the files are to uploaded. + The following format is possible: + sftp://@[:]/path"; + } + + uses o-ran-fm:credential-information; + } + +// transceiver measurements applicable to all O-RAN HW functions + + leaf transceiver-measurement-interval { + type uint16; + units seconds; + description + "measurement interval to measure the performance of transceiver + measurement objects periodically."; + } + +// EPE measurements applicable to all O-RAN HW functions + + leaf epe-measurement-interval { + type uint16; + units seconds; + description + "measurement interval to measure the energy, power and environmental + measurement objects periodically."; + } + +// RX Window measurements applicable to O-RAN WG4 defined functions + + leaf rx-window-measurement-interval { + type uint16; + units seconds; + description + "measurement interval to measure the performance of reception + window measurement objects periodically."; + } + + leaf tx-measurement-interval { + type uint16; + units seconds; + description + "measurement interval to measure the tx (outbound) + window measurement objects periodically."; + } + + leaf notification-interval { + type uint16; + units seconds; + description + "notification interval for the measurement result to be notified + periodically."; + } + + leaf file-upload-interval { + type uint16; + units seconds; + description + "file upload interval for the measurement result file to be + uploaded periodically."; + } + + leaf max-bin-count{ + type uint16; + config false; + mandatory true; + description + "indicates the maximum value of configurable bin-count for frequency + table in transceiver-measurement-objects as one of module + capabilities."; + } + + list transceiver-measurement-objects { + key "measurement-object"; + description + "optional list used to report transceiver measurements + applicable to any O-RAN defined hardware function"; + leaf measurement-object { + type enumeration { + enum RX_POWER { + description + "Measured Rx input power in mW for SFP or lane 1 of QSFP"; + } + enum RX_POWER_LANE_2 { + description + "Measured Rx input power in mW for lane 2 of QSFP"; + } + enum RX_POWER_LANE_3 { + description + "Measured Rx input power in mW for lane 3 of QSFP"; + } + enum RX_POWER_LANE_4 { + description + "Measured Rx input power in mW for lane 4 of QSFP"; + } + enum TX_POPWER { + status deprecated; + description + "Measured Tx input power in mW."; + } + enum TX_POWER { + description + "Measured Tx input power in mW."; + } + enum TX_POWER_LANE_2 { + description + "Measured Tx input power in mW for lane 2 of QSFP"; + } + enum TX_POWER_LANE_3 { + description + "Measured Tx input power in mW for lane 3 of QSFP"; + } + enum TX_POWER_LANE_4 { + description + "Measured Tx input power in mW for lane 4 of QSFP"; + } + enum TX_BIAS_COUNT { + description + "Internally measured Tx Bias Current in mA for SFP or lane 1 of QSFP"; + } + enum TX_BIAS_COUNT_LANE_2 { + description + "Internally measured Tx Bias Current in mA for lane 2 of QSFP"; + } + enum TX_BIAS_COUNT_LANE_3 { + description + "Internally measured Tx Bias Current in mA for lane 3 of QSFP"; + } + enum TX_BIAS_COUNT_LANE_4 { + description + "Internally measured Tx Bias Current in mA for lane 4 of QSFP"; + } + enum VOLTAGE { + description + "Internally measured transceiver supply voltage in mV"; + } + enum TEMPERATURE { + description + "Internally measured optional laser temperature in degrees Celsius."; + } + } + description "Target metric to measure the performance"; + } + + leaf active { + type boolean; + default false; + description + "Enable/disable the performance measurement per Object"; + } + + leaf-list report-info { + type enumeration { + enum MAXIMUM { + description + "to report maximum value and its recorded time within the + measurement-interval for the measurement-object."; + } + enum MINIMUM { + description + "to report minimum value and its recorded time within the + measurement-interval for the measurement-object."; + } + enum FIRST { + description + "to report first value and its recorded time within the + measurement-interval for the measurement-object."; + } + enum LATEST { + description + "to report latest value and its recorded time within the + measurement-interval for the measurement-object."; + } + enum FREQUENCY_TABLE { + description + "to report frequency bin table within the + measurement-interval for the measurement-object."; + } + } + description "The reporting info to the measurement object."; + } + + leaf object-unit { + type enumeration { + enum PORT_NUMBER { + description + "unit to measure the performance per object-id"; + } + } + mandatory true; + description "unit to measure the performance per object-id."; + } + + leaf function { + type enumeration { + enum RAW { + description + "the value is expressed by real value."; + } + enum LOG_10 { + description + "the value is expressed by logarithm with base 10."; + } + } + + description + "the value to be recorded for transceiver-measurement + by real value or log 10."; + } + + leaf bin-count { + type uint16; + + description + "the number of bin for the frequency table. + This value shall be less than max-bin-count"; + } + + leaf lower-bound { + type decimal64 { + fraction-digits 4; + } + + description + "the lower value of the first bin of frequency table."; + } + + leaf upper-bound { + type decimal64 { + fraction-digits 4; + } + + description + "the upper value of the last bin of frequency table."; + } + uses transceiver-measurement-result-grouping; +// configuration and measurement result for the transceiver-measurement + + } + + list rx-window-measurement-objects { + key "measurement-object"; + description + "optional list used to report RX Window measurements + applicable to O-RAN WG4 define O-RU functions"; + leaf measurement-object { + type enumeration { + enum RX_ON_TIME { + description + "the number of data packets, received on time within + the reception window."; + } + enum RX_EARLY { + description + "the number of data packets, received before + the reception window."; + } + enum RX_LATE { + description + "the number of data packets, received after + the reception window."; + } + enum RX_CORRUPT { + description + "the number of data packets, which are corrupt or whose header + is incorrect."; + } + enum RX_DUPL { + status deprecated; + description + "the number of data packets, which is duplicated with other packets, + received within the measurement period."; + } + enum RX_TOTAL { + description + "the total number of received packets (data and control) within the measurement period."; + } + enum RX_ON_TIME_C { + description + "the number of control packets, received on time within + the reception window."; + } + enum RX_EARLY_C { + description + "the number of control packets, received before + the reception window."; + } + enum RX_LATE_C { + description + "the number of control packets, received after + the reception window."; + } + enum RX_SEQID_ERR { + description + "the number of data packets, received with an erroneous sequence ID."; + } + enum RX_SEQID_ERR_C { + description + "the number of control packets, received with an erroneous sequence ID."; + } + enum RX_ERR_DROP { + description + "The total number of inbound messages which are discarded by the receiving + O-RAN entity for any reason."; + } + } + description + "target reception window metric to measure the performance."; + } + + leaf active { + type boolean; + default false; + description + "Enable/disable the performance measurement per reception window + measurement object."; + } + + leaf object-unit { + type enumeration { + enum RU { + description + "the reception window stats are counted per hardware component. + This may be the parent 'module' or child 'port' component."; + } + enum TRANSPORT { + if-feature GRANULARITY-TRANSPORT-MEASUREMENT; + description + "the reception window stats are counted per transport flow. + When there are multiple transport flows between O-DU and O-RU, + e.g. multiple sets of o-du mac address, ru mac address and + vlan-id, the reception window stats per transport flow + are counted in this case. + This configuration is allowed only when O-RU supports + a feature GRANULARITY-TRANSPORT-MEASUREMENT."; + } + enum EAXC_ID { + if-feature GRANULARITY-EAXC-ID-MEASUREMENT; + + description + "the reception window stats are counted per eAxC ID, which is + used in the header of receivd data packet. + This configuration is allowed only when O-RU supports + a feature GRANULARITY-EAXC-ID-MEASUREMENT."; + } + } + description + "unit to measure the performance per object-id."; + } + + leaf report-info { + type enumeration { + enum COUNT { + description + "the number of data packet are counted for the reception + window stats."; + } + } + description + "The reporting info to the measurement object."; + } + + uses rx-window-measurement-result-grouping; +// configuration and measurement result for the reception window stats + + } + + + list tx-measurement-objects { + key "measurement-object"; + description + "optional list used to report TX measurements + applicable to O-RAN WG4 define O-RU functions"; + leaf measurement-object { + type enumeration { + enum TX_TOTAL { + description + "the number of outbound packets (data and control), transmitted within + the measurement period"; + } + enum TX_TOTAL_C { + description + "the number of outbound control packets, transmitted within + the measurement period. + This counter is required only if RU supports LAA/LBT capabilities."; + } + } + description + "CU-plane transmission counters"; + } + + leaf active { + type boolean; + default false; + description + "Enable/disable the measurement per measurement object."; + } + + leaf object-unit { + type enumeration { + enum RU { + description + "the transmission stats are counted per hardware component. + This may be the parent 'module' or child 'port' component."; + } + enum TRANSPORT { + if-feature GRANULARITY-TRANSPORT-MEASUREMENT; + description + "the transmission stats are counted per transport flow. + When there are multiple transport flows between O-DU and O-RU, + e.g. multiple sets of o-du mac address, ru mac address and + vlan-id, the transmission stats per transport flow + are counted in this case. + This configuration is allowed only when O-RU supports + a feature GRANULARITY-TRANSPORT-MEASUREMENT."; + } + enum EAXC_ID { + if-feature GRANULARITY-EAXC-ID-MEASUREMENT; + + description + "the transmission stats are counted per eAxC ID, which is + used in the header of receivd data packet. + This configuration is allowed only when O-RU supports + a feature GRANULARITY-EAXC-ID-MEASUREMENT."; + } + } + description + "unit to measure the performance per object-id."; + } + + leaf report-info { + type enumeration { + enum COUNT { + description + "the number of data packet are counted for the reception + window stats."; + } + } + description + "The reporting info to the measurement object."; + } + + uses tx-measurement-result-grouping; + // configuration and measurement result for the tx stats + + } + + list epe-measurement-objects { + key "measurement-object"; + description + "optional list used to report energy, power and environmental + measurements applicable to any O-RAN defined hardware function"; + leaf measurement-object { + type enumeration { + enum TEMPERATURE { + description + "Measured temperature in degrees celcius"; + } + enum POWER { + description + "Measured power consumed, in watts (W)"; + } + } + description "Target metric to measure the performance"; + } + + leaf active { + type boolean; + default false; + description + "Enable/disable the performance measurement per Object"; + } + + leaf-list report-info { + type enumeration { + enum MAXIMUM { + description + "to report maximum value and its recorded time within the + measurement-interval for the measurement-object."; + } + enum MINIMUM { + description + "to report minimum value and its recorded time within the + measurement-interval for the measurement-object."; + } + enum AVERAGE { + description + "to report average value within the + measurement-interval for the measurement-object."; + } + } + description "The reporting info to the measurement object."; + } + + + uses epe-measurement-result-grouping; + // configuration and measurement result for the epe-measurement + + } + + + } + + grouping measurement-capabilities { + container measurement-capabilitites { + config false; + description "the type of measurement objects supported by the O-RU"; + + list transceiver-objects { + key measurement-object; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/transceiver-measurement-objects/measurement-object"; + } + } + } + list rx-window-objects { + key measurement-object; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/rx-window-measurement-objects/measurement-object"; + } + } + } + list tx-stats-objects { + key measurement-object; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/tx-measurement-objects/measurement-object"; + } + } + } + list epe-stats-objects { + key "measurement-object"; + description + "An optional list describing the energy, power and environmental measurements supported + by the O-RU. Measurements are defined per hardware component."; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/epe-measurement-objects/measurement-object"; + } + } + leaf-list component-class { + type identityref { + base ianahw:hardware-class; + } + description + "An indication of the general hardware type of the + component for which EPE measurements are supported."; + + } + } + } + } + + grouping measurement-notification { + list transceiver-stats { + key "measurement-object"; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/transceiver-measurement-objects/measurement-object"; + } + + description + "measurement-object for the transceiver-measurement"; + } + + uses start-and-end-time; + uses transceiver-measurement-result-grouping; + + description + "measurement result of transceiver-measurement per measurement-object"; + } + + list rx-window-stats { + key "measurement-object"; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/rx-window-measurement-objects/measurement-object"; + } + + description + "measurement-object for the reception window measurement"; + } + uses start-and-end-time; + uses rx-window-measurement-result-grouping; + + description + "measurement result for the reception window measurement per + measurement-object"; + + } + + list tx-stats { + key "measurement-object"; + leaf measurement-object { + type leafref { + path "/performance-measurement-objects/tx-measurement-objects/measurement-object"; + } + + description + "measurement-object for the tx stats measurement"; + } + uses start-and-end-time; + uses tx-measurement-result-grouping; + + description + "measurement result for the tx stats measurement per + measurement-object"; + + } + + container epe-stats { + description + "container for the epe stats measurement"; + + uses start-and-end-time; + uses epe-measurement-result-grouping; + + + } + + description + "notification may contain measurement result for transceiver-stats + and/or rx-window-stats"; + } + + // Top level container + + container performance-measurement-objects { + description + "configuration for performance management and measurement-result are + included"; + uses measurement-group; + } + +// Notifications + + notification measurement-result-stats { + description + "Notification may contain measurement results for transceiver-stats + and/or rx-window-stats"; + uses measurement-notification; + } +} diff --git a/radio/fhi_72/oran-params.h b/radio/fhi_72/oran-params.h index 42aabd99bb..baeefbc68d 100644 --- a/radio/fhi_72/oran-params.h +++ b/radio/fhi_72/oran-params.h @@ -35,6 +35,7 @@ #define ORAN_CONFIG_DU_ADDR "du_addr" // only needed for M-plane #define ORAN_CONFIG_VLAN_TAG "vlan_tag" // only needed for M-plane #define ORAN_CONFIG_RU_ADDR "ru_addr" // not needed if M-plane used +#define ORAN_CONFIG_RU_USERNAME "ru_username" // only needed for M-plane #define ORAN_CONFIG_RU_IP_ADDR "ru_ip_addr" // only needed for M-plane #define ORAN_CONFIG_MTU "mtu" // not needed if M-plane used #define ORAN_CONFIG_FILE_PREFIX "file_prefix" @@ -56,6 +57,7 @@ {ORAN_CONFIG_DU_ADDR, "Ether addr of DU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ {ORAN_CONFIG_VLAN_TAG, "VLAN tag\n", PARAMFLAG_MANDATORY, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ {ORAN_CONFIG_RU_ADDR, "Ether addr of RU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ + {ORAN_CONFIG_RU_USERNAME, "Username of RU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ {ORAN_CONFIG_RU_IP_ADDR, "IP addr of RU\n", PARAMFLAG_MANDATORY, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \ {ORAN_CONFIG_MTU, "MTU of Eth interface\n", 0, .uptr=NULL, .defuintval=1500, TYPE_UINT, 0}, \ {ORAN_CONFIG_FILE_PREFIX, "DPDK file-prefix\n", 0, .strptr=NULL, .defstrval="wls_0", TYPE_STRING, 0}, \ @@ -82,6 +84,7 @@ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ { .s3a = { config_checkstr_assign_integer, \ {"PA", "VA"}, {0, 1}, 2} }, \ { .s5 = { NULL } }, \ diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 4a141275d7..3bdbe1df12 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -338,6 +338,11 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d if (!ru_ready[i] && ru_session->ru_notif.config_change && ru_session->ru_notif.rx_carrier_state && ru_session->ru_notif.tx_carrier_state) { MP_LOG_I("RU \"%s\" is now ready.\n", ru_session->ru_ip_add); ru_ready[i] = true; + if (!ru_session->pm_stats.start_up_timing) { + success = pm_conf(ru_session, "true"); + if (success) + MP_LOG_I("Sucessfully activated PM after start-up procedure for RU \"%s\".\n", ru_session->ru_ip_add); + } } else { all_rus_ready = false; break; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf index 72d174cfb3..3dd36be9c7 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-du.sa.band77.273prb.fhi72.8x8-benetel650_650-mplane.conf @@ -205,7 +205,7 @@ RUs = ( local_rf = "no"; nb_tx = 8; nb_rx = 8; - att_tx = 0; + att_tx = 35; att_rx = 0; bands = [77]; max_pdschReferenceSignalPower = -27; @@ -240,6 +240,7 @@ fhi_72 = { du_key_pair = ("/home/eurecom/.ssh/id_rsa.pub", "/home/eurecom/.ssh/id_rsa"); du_addr = ("00:11:22:33:44:66", "00:11:22:33:44:67", "00:11:22:33:44:68", "00:11:22:33:44:69"); vlan_tag = (5, 5, 6, 6); + ru_username = ("oranbenetel", "oranbenetel"); ru_ip_addr = ("192.168.80.5", "192.168.80.6"); fh_config = ( # RAN650 #1 diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf index be35562fd7..ed996cac27 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.273prb.fhi72.4x4-benetel550-mplane.conf @@ -208,7 +208,7 @@ RUs = ( local_rf = "no"; nb_tx = 4; nb_rx = 4; - att_tx = 0; + att_tx = 24; att_rx = 0; bands = [78]; max_pdschReferenceSignalPower = -27; @@ -260,6 +260,7 @@ fhi_72 = { du_key_pair = ("/home/eurecom/.ssh/id_rsa.pub", "/home/eurecom/.ssh/id_rsa"); du_addr = ("00:11:22:33:44:68","00:11:22:33:44:69"); vlan_tag = (11, 11); + ru_username = ("oranbenetel"); ru_ip_addr = ("192.168.80.10"); fh_config = ({ T1a_cp_dl = (419, 470);