mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 05:00:31 +00:00
Compare commits
15 Commits
pre-commit
...
metanoia-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35a3c546bf | ||
|
|
d03404c2c4 | ||
|
|
a775e032f1 | ||
|
|
96e9780805 | ||
|
|
d4d9654e6c | ||
|
|
d700242b03 | ||
|
|
0761d5a97e | ||
|
|
96b9472644 | ||
|
|
00b4171949 | ||
|
|
37207002e9 | ||
|
|
c7269fa030 | ||
|
|
32ec185215 | ||
|
|
9dbd370f57 | ||
|
|
8c06b94332 | ||
|
|
ff56903fc3 |
@@ -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 = ("<path-to>/.ssh/id_rsa.pub", "<path-to>/.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" = <get-schema> for module "ietf-yang-metadata".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "yang".
|
||||
[HW] [MPLANE] RPC request to RU "192.168.80.9" = <get-schema> for module "ietf-inet-types".
|
||||
@@ -1636,6 +1649,59 @@ sequenceDiagram
|
||||
<vlan-id xmlns="urn:o-ran:interfaces:1.0">9</vlan-id>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<performance-measurement-objects xmlns="urn:o-ran:performance-management:1.0">
|
||||
<rx-window-measurement-interval>10</rx-window-measurement-interval>
|
||||
<tx-measurement-interval>10</tx-measurement-interval>
|
||||
<notification-interval>10</notification-interval>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_TOTAL</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME_C</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY_C</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE_C</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<tx-measurement-objects>
|
||||
<measurement-object>TX_TOTAL</measurement-object>
|
||||
<active>false</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</tx-measurement-objects>
|
||||
</performance-measurement-objects>
|
||||
<processing-elements xmlns="urn:o-ran:processing-element:1.0">
|
||||
<transport-session-type>ETH-INTERFACE</transport-session-type>
|
||||
<ru-elements>
|
||||
@@ -1729,8 +1795,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1746,8 +1814,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1763,8 +1833,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1780,8 +1852,10 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
@@ -1797,9 +1871,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1807,6 +1887,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>0</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint0</name>
|
||||
@@ -1814,9 +1895,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1824,6 +1911,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>4</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxEndpoint1</name>
|
||||
@@ -1831,9 +1919,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1841,6 +1935,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>1</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint1</name>
|
||||
@@ -1848,9 +1943,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1858,6 +1959,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>5</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxEndpoint2</name>
|
||||
@@ -1865,9 +1967,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1875,6 +1983,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>2</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint2</name>
|
||||
@@ -1882,9 +1991,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1892,6 +2007,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>6</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxEndpoint3</name>
|
||||
@@ -1899,9 +2015,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1909,6 +2031,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>3</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<low-level-rx-endpoints>
|
||||
<name>LowLevelRxPrachEndpoint3</name>
|
||||
@@ -1916,9 +2039,15 @@ sequenceDiagram
|
||||
<iq-bitwidth>9</iq-bitwidth>
|
||||
<compression-type>STATIC</compression-type>
|
||||
</compression>
|
||||
<cp-length>0</cp-length>
|
||||
<cp-length-other>0</cp-length-other>
|
||||
<frame-structure>193</frame-structure>
|
||||
<cp-type>NORMAL</cp-type>
|
||||
<cp-length>352</cp-length>
|
||||
<cp-length-other>288</cp-length-other>
|
||||
<offset-to-absolute-frequency-center>0</offset-to-absolute-frequency-center>
|
||||
<ul-fft-sampling-offsets>
|
||||
<scs>KHZ_30</scs>
|
||||
<ul-fft-sampling-offset>0</ul-fft-sampling-offset>
|
||||
</ul-fft-sampling-offsets>
|
||||
<e-axcid>
|
||||
<o-du-port-bitmask>61440</o-du-port-bitmask>
|
||||
<band-sector-bitmask>3840</band-sector-bitmask>
|
||||
@@ -1926,6 +2055,7 @@ sequenceDiagram
|
||||
<ru-port-bitmask>15</ru-port-bitmask>
|
||||
<eaxc-id>7</eaxc-id>
|
||||
</e-axcid>
|
||||
<non-time-managed-delay-enabled>true</non-time-managed-delay-enabled>
|
||||
</low-level-rx-endpoints>
|
||||
<tx-array-carriers>
|
||||
<name>TxArray0</name>
|
||||
@@ -1933,7 +2063,7 @@ sequenceDiagram
|
||||
<center-of-channel-bandwidth>3950400000</center-of-channel-bandwidth>
|
||||
<channel-bandwidth>100000000</channel-bandwidth>
|
||||
<active>ACTIVE</active>
|
||||
<gain>0.0</gain>
|
||||
<gain>24.0</gain>
|
||||
<downlink-radio-frame-offset>0</downlink-radio-frame-offset>
|
||||
<downlink-sfn-offset>0</downlink-sfn-offset>
|
||||
</tx-array-carriers>
|
||||
@@ -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" = <commit> 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" = <edit-config>:
|
||||
<performance-measurement-objects xmlns="urn:o-ran:performance-management:1.0">
|
||||
<rx-window-measurement-interval>10</rx-window-measurement-interval>
|
||||
<tx-measurement-interval>10</tx-measurement-interval>
|
||||
<notification-interval>10</notification-interval>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_TOTAL</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_ON_TIME_C</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_EARLY_C</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<rx-window-measurement-objects>
|
||||
<measurement-object>RX_LATE_C</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</rx-window-measurement-objects>
|
||||
<tx-measurement-objects>
|
||||
<measurement-object>TX_TOTAL</measurement-object>
|
||||
<active>true</active>
|
||||
<object-unit>RU</object-unit>
|
||||
<report-info>COUNT</report-info>
|
||||
</tx-measurement-objects>
|
||||
</performance-measurement-objects>
|
||||
|
||||
[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" = <validate> 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" = <commit> 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".
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
@@ -909,11 +909,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;
|
||||
@@ -924,7 +925,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;
|
||||
@@ -932,7 +933,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.
|
||||
@@ -1117,7 +1126,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);
|
||||
|
||||
if(!emulate_rf) {
|
||||
// Start IF device if any
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 <libyang/libyang.h>
|
||||
#include <nc_client.h>
|
||||
|
||||
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 <edit-config> RPC.\n");
|
||||
|
||||
MP_LOG_I("RPC request to RU \"%s\" = <edit-config>:\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] <edit-config> 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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "connect-mplane.h"
|
||||
#include "init-mplane.h"
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
@@ -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\" = <connect> with username \"%s\" and port ID \"%d\".\n", ru_session->ru_ip_add, user, port);
|
||||
MP_LOG_I("RPC request to RU \"%s\" = <connect> 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();
|
||||
|
||||
@@ -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 <libyang/libyang.h>
|
||||
#include <nc_client.h>
|
||||
@@ -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,18 +182,25 @@ 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 <edit-config> 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");
|
||||
//const char *usage_state = get_ru_xml_node(operational_ds, "usage-state");
|
||||
const char *usage_state = "busy";
|
||||
MP_LOG_I("Usage state = \"%s\" for RU \"%s\".\n", usage_state, ru_session->ru_ip_add);
|
||||
if (strcmp(usage_state, "busy") == 0) { // carriers are already activated
|
||||
ru_session->ru_notif.rx_carrier_state = true;
|
||||
@@ -201,5 +215,19 @@ bool manage_ru(ru_session_t *ru_session, const openair0_config_t *oai, const siz
|
||||
free(operational_ds);
|
||||
free(watchdog_answer);
|
||||
|
||||
sleep(100);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -33,7 +33,14 @@ 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_metanoia_setting(xran_mplane_t *xran_mplane, const uint32_t interface_mtu, const uint16_t first_iq_width, const int max_num_ant)
|
||||
{
|
||||
xran_mplane->mtu = interface_mtu;
|
||||
xran_mplane->iq_width = first_iq_width;
|
||||
xran_mplane->prach_offset = 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 +57,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 +76,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,10 +106,28 @@ bool get_config_for_xran(const char *buffer, const int max_num_ant, xran_mplane_
|
||||
// RU port ID
|
||||
xran_mplane->ru_port = 0;
|
||||
|
||||
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);
|
||||
// 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 (ru_vendor && strcasecmp(ru_vendor, "BENETEL") == 0) {
|
||||
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);
|
||||
fix_metanoia_setting(xran_mplane, interface_mtu, first_iq_width, max_num_ant);
|
||||
//AssertError(false, return false, "[MPLANE] %s RU currently not supported.\n", ru_vendor);
|
||||
}
|
||||
|
||||
MP_LOG_I("Storing the following information to forward to xran:\n\
|
||||
@@ -109,7 +142,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 +155,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 +190,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 (ru_vendor && 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-measurement-objects", &pm_stats->rx_window_meas, &pm_stats->rx_num);
|
||||
|
||||
// Tx
|
||||
get_ru_xml_list(buffer, "tx-measurement-objects", &pm_stats->tx_meas, &pm_stats->tx_num);
|
||||
|
||||
MP_LOG_I("Successfully retreived all performance measurement names.\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,40 @@ 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)
|
||||
static LY_ERR fill_uplane_ch_common_v2(const bool rx_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 (rx_dir == true) {
|
||||
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 +147,20 @@ 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");
|
||||
}
|
||||
|
||||
|
||||
if (rx_dir == true) {
|
||||
ret = lyd_new_term(compression_node, NULL, "fs-offset", "8", 0, NULL);
|
||||
VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"fs-offset\" 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 +169,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 +190,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(true, 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(false, 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 +265,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 <gain-correction-range>
|
||||
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 +296,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 +320,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 +328,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 +339,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 +399,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 +473,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");
|
||||
|
||||
// <o-ran-processing-element>
|
||||
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 +492,49 @@ bool configure_ru_from_yang(struct ly_ctx **ctx, const ru_session_t *ru_session,
|
||||
|
||||
// <o-ran-uplane-conf>
|
||||
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);
|
||||
// <o-ran-pm>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
|
||||
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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
|
||||
#include <libyang/libyang.h>
|
||||
|
||||
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 */
|
||||
|
||||
1783
radio/fhi_72/mplane/yang/models/ietf-crypto-types.yang
Normal file
1783
radio/fhi_72/mplane/yang/models/ietf-crypto-types.yang
Normal file
File diff suppressed because it is too large
Load Diff
440
radio/fhi_72/mplane/yang/models/ietf-netconf-acm.yang
Normal file
440
radio/fhi_72/mplane/yang/models/ietf-netconf-acm.yang
Normal file
@@ -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: <https://datatracker.ietf.org/wg/netconf/>
|
||||
WG List: <mailto:netconf@ietf.org>
|
||||
Author: Andy Bierman
|
||||
<mailto:andy@yumaworks.com>
|
||||
Author: Martin Bjorklund
|
||||
<mailto:mbj@tail-f.com>";
|
||||
|
||||
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.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
213
radio/fhi_72/mplane/yang/models/o-ran-file-management.yang
Normal file
213
radio/fhi_72/mplane/yang/models/o-ran-file-management.yang
Normal file
@@ -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://<username>@<host>[: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 "";
|
||||
}
|
||||
}
|
||||
1168
radio/fhi_72/mplane/yang/models/o-ran-performance-management.yang
Normal file
1168
radio/fhi_72/mplane/yang/models/o-ran-performance-management.yang
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1693,7 +1693,6 @@ module o-ran-uplane-conf {
|
||||
uses cf:compression-details;
|
||||
|
||||
leaf fs-offset {
|
||||
if-feature cf:CONFIGURABLE-FS-OFFSET;
|
||||
type uint8;
|
||||
default 0;
|
||||
description
|
||||
|
||||
@@ -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 } }, \
|
||||
|
||||
@@ -330,7 +330,7 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d
|
||||
AssertFatal(false, "[MPLANE] Stopping M-plane.\n");
|
||||
}
|
||||
|
||||
while (true) {
|
||||
/* while (true) {
|
||||
sleep(1);
|
||||
bool all_rus_ready = true;
|
||||
for (int i = 0; i < ru_session_list.num_rus; i++) {
|
||||
@@ -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;
|
||||
@@ -346,7 +351,7 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d
|
||||
if (all_rus_ready) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
eth->mplane_priv = (void *)&ru_session_list;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user