Merge remote-tracking branch 'origin/multi-ue-test' into integration_2025_w35 (!3425)

RFSim test for 10 UEs/process

This MR adds a testcase and changes required to run 10 UEs in a single
process with RFSim

- Added deregistration for all connected UEs
- Refactored MAC/RRC instance handling
- made map_current_symbol thread safe
- made opeanir0_cfg thread safe and local
- Added 10UE/process testcase
This commit is contained in:
Robert Schmidt
2025-08-28 08:59:05 +02:00
31 changed files with 877 additions and 286 deletions
+90
View File
@@ -455,3 +455,93 @@ l2sim4g_ext_dn:
Host: "%%current_host%%"
NetworkScript: docker exec l2sim4g-trf-gen ip a show dev eth0
CmdPrefix: docker exec l2sim4g-trf-gen
rfsim5g_multiue1:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue1
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue1
AttachScript: docker start rfsim5g-oai-nr-ue
DetachScript: docker stop rfsim5g-oai-nr-ue
MTU: 1500
rfsim5g_multiue2:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue2
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue2
AttachScript: true
DetachScript: true
MTU: 1500
rfsim5g_multiue3:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue3
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue3
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue4:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue4
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue4
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue5:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue5
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue5
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue6:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue6
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue6
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue7:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue7
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue7
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue8:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue8
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue8
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue9:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue9
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue9
AttachScript: "true"
DetachScript: "true"
MTU: 1500
rfsim5g_multiue10:
Host: "%%current_host%%"
NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue10
CmdPrefix: docker exec rfsim5g-oai-nr-ue
IF: oaitun_ue10
AttachScript: "true"
DetachScript: "true"
MTU: 1500
@@ -0,0 +1,210 @@
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>rfsim-5gnr-tdd-multiue</htmlTabRef>
<htmlTabName>Monolithic SA TDD gNB multiue</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
111111
800813
000001
000002
000003
000008
020001
020002
020003
020004
020105
444445
030001
030002
444444
100001
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>mysql oai-amf oai-smf oai-upf oai-ext-dn</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G gNB RF sim SA</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>oai-gnb</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<services>oai-nr-ue</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000008">
<class>Attach_UE</class>
<desc>Attach OAI UE (Wait for IP)</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
</testCase>
<testCase id="020001">
<class>Ping</class>
<desc>Ping ext-dn from NR-UE</desc>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020002">
<class>Ping</class>
<desc>Ping NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_multiue1</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020003">
<class>Ping</class>
<desc>Ping ext-dn from Second NR-UE</desc>
<id>rfsim5g_multiue2</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020004">
<class>Ping</class>
<desc>Ping Second NR-UE from ext-dn</desc>
<id>rfsim5g_ext_dn</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_multiue2</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020005">
<class>Ping</class>
<desc>Ping ext-dn from both UEs</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2</id>
<nodes>acamas acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="020105">
<class>Ping</class>
<desc>Ping ext-dn from all UEs</desc>
<id>rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10</id>
<nodes>acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<ping_args>-c 20 -i 0.25 -s 1016</ping_args>
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</testCase>
<testCase id="030001">
<class>Iperf</class>
<desc>Iperf (DL/3Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 3M -t 20 -R</iperf_args>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="030002">
<class>Iperf</class>
<desc>Iperf (UL/1Mbps/UDP)(30 sec)</desc>
<iperf_args>-u -b 1M -t 20</iperf_args>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
<svr_id>rfsim5g_ext_dn</svr_id>
<svr_node>acamas</svr_node>
<iperf_packetloss_threshold>5</iperf_packetloss_threshold>
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
</testCase>
<testCase id="444444">
<class>Detach_UE</class>
<desc>Detach OAI UEs</desc>
<id>rfsim5g_multiue1</id>
<nodes>acamas</nodes>
</testCase>
<testCase id="100001">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_multiue</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<images>oai-gnb-asan oai-nr-ue</images>
</testCase>
</testCaseList>
@@ -0,0 +1,146 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:8.0
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 30
networks:
public_net:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-amf/etc/config.yaml
depends_on:
- mysql
networks:
public_net:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-smf/etc/config.yaml
depends_on:
- oai-amf
networks:
public_net:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
- ../5g_rfsimulator/mini_nonrf_config.yaml:/openair-upf/etc/config.yaml
depends_on:
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
networks:
public_net:
ipv4_address: 192.168.71.134
interface_name: eth0
traffic_net:
ipv4_address: 192.168.72.134
interface_name: eth1
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:focal
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"
depends_on:
- oai-upf
networks:
traffic_net:
ipv4_address: 192.168.72.135
healthcheck:
test: /bin/bash -c "ping -c 2 192.168.72.134"
interval: 10s
timeout: 5s
retries: 5
oai-gnb:
image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
environment:
USE_ADDITIONAL_OPTIONS: -E --rfsim --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
depends_on:
- oai-ext-dn
networks:
public_net:
ipv4_address: 192.168.71.140
volumes:
- ../../conf_files/gnb.sa.band78.106prb.rfsim.yaml:/opt/oai-gnb/etc/gnb.yaml
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue:
image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
container_name: rfsim5g-oai-nr-ue
cap_drop:
- ALL
cap_add:
- NET_ADMIN # for interface bringup
- NET_RAW # for ping
environment:
USE_ADDITIONAL_OPTIONS: -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time --num-ues 10
depends_on:
- oai-gnb
networks:
public_net:
ipv4_address: 192.168.71.150
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- ./nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
driver: bridge
name: rfsim5g-oai-public-net
ipam:
config:
- subnet: 192.168.71.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-public"
traffic_net:
driver: bridge
name: rfsim5g-oai-traffic-net
ipam:
config:
- subnet: 192.168.72.128/26
driver_opts:
com.docker.network.bridge.name: "rfsim5g-traffic"
@@ -0,0 +1,75 @@
uicc0 = {
imsi = "208990100001100";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc1 = {
imsi = "208990100001101";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc2 = {
imsi = "208990100001102";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc3 = {
imsi = "208990100001103";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc4 = {
imsi = "208990100001104";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc5 = {
imsi = "208990100001105";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc6 = {
imsi = "208990100001106";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc7 = {
imsi = "208990100001107";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc8 = {
imsi = "208990100001108";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
uicc9 = {
imsi = "208990100001109";
key = "fec86ba6eb707ed08905757b1bb44b8f";
opc= "C42449363BBAD02B66D16BC975D77CC1";
dnn= "oai";
nssai_sst=1;
}
thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
+1 -1
View File
@@ -62,7 +62,7 @@ add_dependencies(telnetsrv telnetsrv_ci)
message(STATUS "Add CI specific telnet functions for nrUE in telnetsrv_ciUE.so")
add_library(telnetsrv_ciUE MODULE telnetsrv_ciUE.c)
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(telnetsrv_ciUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
add_dependencies(telnetsrv telnetsrv_ciUE)
message(STATUS "Add bearer specific telnet functions in libtelnetsrv_bearer.so")
-1
View File
@@ -126,7 +126,6 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
+24 -25
View File
@@ -414,7 +414,7 @@ static void UE_synch(void *arg) {
syncData_t *syncD = (syncData_t *)arg;
PHY_VARS_NR_UE *UE = syncD->UE;
UE->is_synchronized = 0;
openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card];
openair0_config_t *cfg0 = &UE->openair0_cfg[UE->rf_map.card];
if (UE->target_Nid_cell != -1) {
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
@@ -523,7 +523,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
if (UE->received_config_request) {
if (openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
if (UE->openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
flags = TX_BURST_MIDDLE;
// In case of Sidelink, USRP write needed only in case transmission
// needs to be done in this slot and not based on tdd ULDL configuration.
@@ -696,8 +696,8 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) {
fp->dl_CarrierFreq = dl_CarrierFreq;
fp->ul_CarrierFreq = ul_CarrierFreq;
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
nr_rf_card_config_freq(&UE->openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &UE->openair0_cfg[UE->rf_map.card]);
init_symbol_rotation(fp);
}
@@ -731,12 +731,14 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
// process what RRC thread sent to MAC
MessageDef *msg = NULL;
do {
itti_poll_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
} while (msg);
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&get_mac_inst(UE->Mod_id)->input_nf);
if (!elt) {
break;
}
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
delNotifiedFIFO_elt(elt);
} while (true);
if (UE->if_inst)
UE->if_inst->slot_indication(UE->Mod_id, false);
@@ -966,7 +968,7 @@ void *UE_thread(void *arg)
void *rxp[NB_ANTENNAS_RX];
enum stream_status_e stream_status = STREAM_STATUS_UNSYNC;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
int tmp = openair0_device_load(&(UE->rfdevice), &UE->openair0_cfg[0]);
AssertFatal(tmp == 0, "Could not load the device\n");
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
sl_nr_phy_config_request_t *sl_cfg = NULL;
@@ -1032,12 +1034,10 @@ void *UE_thread(void *arg)
decoded_frame_rx = UE->SL_UE_PHY_PARAMS.sync_params.DFN;
else {
// We must wait the RRC layer decoded the MIB and sent us the frame number
MessageDef *msg = NULL;
itti_receive_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
else
LOG_E(PHY, "It seems we arbort while trying to sync\n");
notifiedFIFO_elt_t *elt = pullNotifiedFIFO(&mac->input_nf);
AssertFatal(elt != NULL, "fifo error while waiting for MIB");
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
delNotifiedFIFO_elt(elt);
decoded_frame_rx = mac->mib_frame;
}
LOG_A(PHY,
@@ -1284,20 +1284,19 @@ void *UE_thread(void *arg)
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
{
NR_UE_RRC_INST_t *rrc_inst = nr_rrc_init_ue(uecap_file, nb_inst, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac_inst = nr_l2_init_ue(nb_inst);
AssertFatal(mac_inst, "Couldn't allocate MAC module\n");
for (int instance_id = 0; instance_id < nb_inst; instance_id++) {
NR_UE_RRC_INST_t* rrc = nr_rrc_init_ue(uecap_file, instance_id, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac = nr_l2_init_ue(instance_id);
for (int i = 0; i < nb_inst; i++) {
NR_UE_MAC_INST_t *mac = get_mac_inst(i);
mac->if_module = nr_ue_if_module_init(i);
nr_rrc_set_mac_queue(instance_id, &mac->input_nf);
mac->if_module = nr_ue_if_module_init(instance_id);
AssertFatal(mac->if_module, "can not initialize IF module\n");
if (!IS_SA_MODE(get_softmodem_params()) && !get_softmodem_params()->sl_mode) {
init_nsa_message(&rrc_inst[i], reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac_inst[i].crnti, NULL, send_srb0_rrc);
init_nsa_message(rrc, reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac->crnti, NULL, send_srb0_rrc);
}
//TODO: Move this call to RRC
start_sidelink((&rrc_inst[i])->ue_id);
start_sidelink(instance_id);
}
}
+46 -43
View File
@@ -121,8 +121,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
// UE and OAI config variables
openair0_config_t openair0_cfg[MAX_CARDS];
int16_t node_synch_ref[MAX_NUM_CCs];
int otg_enabled;
double cpuf;
@@ -249,41 +247,42 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
}
static void init_openair0()
void init_openair0(PHY_VARS_NR_UE *ue)
{
int card;
int freq_off = 0;
NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
bool is_sidelink = (get_softmodem_params()->sl_mode) ? true : false;
if (is_sidelink)
frame_parms = &PHY_vars_UE_g[0][0]->SL_UE_PHY_PARAMS.sl_frame_params;
frame_parms = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
for (card=0; card<MAX_CARDS; card++) {
openair0_config_t *cfg = &ue->openair0_cfg[card];
uint64_t dl_carrier, ul_carrier;
openair0_cfg[card].configFilename = NULL;
openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3;
openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame;
cfg->configFilename = NULL;
cfg->sample_rate = frame_parms->samples_per_subframe * 1e3;
cfg->samples_per_frame = frame_parms->samples_per_frame;
if (frame_parms->frame_type==TDD)
openair0_cfg[card].duplex_mode = duplex_mode_TDD;
cfg->duplex_mode = duplex_mode_TDD;
else
openair0_cfg[card].duplex_mode = duplex_mode_FDD;
cfg->duplex_mode = duplex_mode_FDD;
openair0_cfg[card].Mod_id = 0;
openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
openair0_cfg[card].tune_offset = get_softmodem_params()->tune_offset;
openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
cfg->Mod_id = 0;
cfg->num_rb_dl = frame_parms->N_RB_DL;
cfg->clock_source = get_softmodem_params()->clock_source;
cfg->time_source = get_softmodem_params()->timing_source;
cfg->tune_offset = get_softmodem_params()->tune_offset;
cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx);
cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx);
LOG_I(PHY,
"HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
card,
openair0_cfg[card].sample_rate,
openair0_cfg[card].tx_num_channels,
openair0_cfg[card].rx_num_channels,
duplex_mode_txt[openair0_cfg[card].duplex_mode]);
cfg->sample_rate,
cfg->tx_num_channels,
cfg->rx_num_channels,
duplex_mode_txt[cfg->duplex_mode]);
if (is_sidelink) {
dl_carrier = frame_parms->dl_CarrierFreq;
@@ -291,16 +290,18 @@ static void init_openair0()
} else
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_freq(cfg, ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
nr_rf_card_config_gain(cfg, rx_gain_off);
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args) openair0_cfg[card].sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev) openair0_cfg[card].tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev) openair0_cfg[card].rx_subdev = get_nrUE_params()->rx_subdev;
cfg->configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args)
cfg->sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev)
cfg->tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev)
cfg->rx_subdev = get_nrUE_params()->rx_subdev;
}
}
@@ -326,9 +327,11 @@ static void trigger_stop(int sig)
static void trigger_deregistration(int sig)
{
if (!stop_immediately && IS_SA_MODE(get_softmodem_params())) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
for (int ue_inst = 0; ue_inst < NB_UE_INST; ue_inst++) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, ue_inst, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, ue_inst, msg);
}
stop_immediately = true;
static const char m[] = "Press ^C again to trigger immediate shutdown\n";
__attribute__((unused)) int unused = write(STDOUT_FILENO, m, sizeof(m) - 1);
@@ -386,7 +389,6 @@ int main(int argc, char **argv)
}
//set_softmodem_sighandler();
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
// initialize logging
logInit();
@@ -425,12 +427,11 @@ int main(int argc, char **argv)
char *pckg = strdup(OAI_PACKAGE_VERSION);
LOG_I(HW, "Version: %s\n", pckg);
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g) * NB_UE_INST);
PHY_vars_UE_g = calloc_or_fail(NB_UE_INST, sizeof(*PHY_vars_UE_g));
for (int inst = 0; inst < NB_UE_INST; inst++) {
PHY_vars_UE_g[inst] = malloc(sizeof(*PHY_vars_UE_g[inst]) * MAX_NUM_CCs);
PHY_vars_UE_g[inst] = calloc_or_fail(MAX_NUM_CCs, sizeof(*PHY_vars_UE_g[inst]));
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[inst][CC_id] = malloc(sizeof(*PHY_vars_UE_g[inst][CC_id]));
memset(PHY_vars_UE_g[inst][CC_id], 0, sizeof(*PHY_vars_UE_g[inst][CC_id]));
PHY_vars_UE_g[inst][CC_id] = calloc_or_fail(1, sizeof(*PHY_vars_UE_g[inst][CC_id]));
// All instances use the same coding interface
PHY_vars_UE_g[inst][CC_id]->nrLDPC_coding_interface = nrLDPC_coding_interface;
}
@@ -498,12 +499,14 @@ int main(int argc, char **argv)
get_softmodem_params()->numerology,
nr_band);
} else {
MessageDef *msg = NULL;
do {
itti_poll_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
} while (msg);
do {
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&mac->input_nf);
if (!elt) {
break;
}
process_msg_rcc_to_mac(NotifiedFifoData(elt), inst);
delNotifiedFIFO_elt(elt);
} while (true);
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band);
}
@@ -538,10 +541,10 @@ int main(int argc, char **argv)
get_nrUE_params()->ofdm_offset_divisor);
sl_ue_phy_init(UE[CC_id]);
}
init_openair0(UE[CC_id]);
}
}
init_openair0();
lock_memory_to_ram();
if (IS_SOFTMODEM_DOSCOPE) {
+1
View File
@@ -5,6 +5,7 @@
#include "common/utils/threadPool/thread-pool.h"
#include "PHY/defs_nr_UE.h"
#define MAX_NUM_NR_UE_INST 32
extern int NB_UE_INST;
extern uint16_t ue_id_g;
@@ -449,12 +449,15 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, &ch_pwr, mean_val);
// adjusting the rx_gains for channel peak power
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size);
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(frame_params->ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm =
10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm = 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
//prs measurements
// prs measurements
prs_meas[rxAnt]->gNB_id = gNB_id;
prs_meas[rxAnt]->sfn = proc->frame_rx;
prs_meas[rxAnt]->slot = proc->nr_slot_rx;
@@ -152,6 +152,7 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS);
bool use_SSS,
openair0_config_t *openair0_cfg);
/** @}*/
#endif
@@ -157,7 +157,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB;
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg);
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
gNB_id,
@@ -235,7 +237,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
float rsrp_db_per_re = 10 * log10(rsrp_avg);
openair0_config_t *cfg0 = &openair0_cfg[0];
openair0_config_t *cfg0 = &ue->openair0_cfg[0];
ue->measurements.ssb_rsrp_dBm[ssb_index] = rsrp_db_per_re + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0])
@@ -271,8 +273,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
const uint8_t k_length = 8;
uint8_t l_sss = (ue->symbol_offset + 2) % ue->frame_parms.symbols_per_slot;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
double rx_gain = openair0_cfg[0].rx_gain[0];
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
double rx_gain = ue->openair0_cfg[0].rx_gain[0];
double rx_gain_offset = ue->openair0_cfg[0].rx_gain_offset[0];
ue->measurements.n0_power_tot = 0;
@@ -344,7 +346,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS)
bool use_SSS,
openair0_config_t *openair0_cfg)
{
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
+1 -1
View File
@@ -238,7 +238,7 @@ static int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
*rsrp = rsrp_sum/meas_count;
*rsrp_dBm = dB_fixed(*rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm);
@@ -518,7 +518,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
sync_params->DFN,
sync_params->slot_offset);
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false);
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false, UE->openair0_cfg);
UE->init_sync_frame = sync_params->remaining_frames;
result.rx_offset = sync_params->rx_offset;
+18 -10
View File
@@ -91,8 +91,8 @@ The function pointers are set once before calling the mapping funcion for
all symbols based on different parameters. Then the mapping is done for
each symbol by calling the function pointers.
*/
static void (*map_dmrs_ptr)(const unsigned int, const c16_t *, c16_t *);
static void (*map_data_dmrs_ptr)(const unsigned int num_cdm_no_data, const c16_t *, c16_t *);
typedef void (*map_dmrs_func_t)(const unsigned int, const c16_t *, c16_t *);
typedef void (*map_data_dmrs_func_t)(const unsigned int, const c16_t *, c16_t *);
/*
The following set of functions map dmrs and/or data REs in one RB based on
@@ -191,7 +191,9 @@ static void map_over_dc(const unsigned int right_dc,
const c16_t **ptrs,
const c16_t **dmrs,
const c16_t **data,
c16_t **out)
c16_t **out,
map_dmrs_func_t map_data_dmrs_ptr,
map_dmrs_func_t map_dmrs_ptr)
{
// if first RE is DC no need to map in this function
if (right_dc == 0)
@@ -277,7 +279,9 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
const c16_t *dmrs_seq,
const c16_t *ptrs_seq,
const c16_t **data,
c16_t *out)
c16_t *out,
map_dmrs_func_t map_dmrs_ptr,
map_data_dmrs_func_t map_data_dmrs_ptr)
{
const unsigned int abs_start_rb = p.bwp_start + p.start_rb;
const unsigned int start_sc = (p.first_sc_offset + abs_start_rb * NR_NB_SC_PER_RB) % p.fft_size;
@@ -297,7 +301,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
// map RB at DC
if (rb_over_dc) {
// if DC is in middle of RB, the following function handles it.
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, NULL, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, NULL, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
// else just move the pointer and following function will map the rb
@@ -315,7 +319,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
for (unsigned int rb = 0; rb < p.nb_rb; rb++) {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, dmrs_per_rb, data_per_rb, p.delta, 0, NULL, &p_mod_dmrs, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -339,7 +343,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
if (rb < non_ptrs_rb || ptrs_idx_rb % p.K_ptrs) {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -351,7 +355,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
} else {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, ptrs_idx_re, &p_mod_ptrs, NULL, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, ptrs_idx_re, &p_mod_ptrs, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -370,7 +374,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p,
for (unsigned int rb = 0; rb < p.nb_rb; rb++) {
if (rb == dc_rb) {
if (rb_over_dc) {
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp);
map_over_dc(rb_over_dc, n_cdm, p.fft_size, 0, 0, p.delta, 0, NULL, NULL, &data_tmp, &out_tmp, map_data_dmrs_ptr, map_dmrs_ptr);
continue;
} else {
out_tmp -= p.fft_size;
@@ -420,6 +424,8 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
c16_t *out)
{
// asign the function pointers
map_dmrs_func_t map_dmrs_ptr = NULL;
map_data_dmrs_func_t map_data_dmrs_ptr = NULL;
if (p.dmrs_type == pusch_dmrs_type1) {
map_dmrs_ptr = map_dmrs_type1_cdm1_rb;
map_data_dmrs_ptr = (p.num_cdm_no_data == 1) ? map_data_dmrs_type1_cdm1_rb : NULL;
@@ -460,7 +466,9 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
mod_dmrs_amp,
mod_ptrs_amp,
&cur_data, // increments every symbol
out + l * p.fft_size);
out + l * p.fft_size,
map_dmrs_ptr,
map_data_dmrs_ptr);
}
}
+1
View File
@@ -336,6 +336,7 @@ typedef struct {
/// Top-level PHY Data Structure for UE
typedef struct PHY_VARS_NR_UE_s {
openair0_config_t openair0_cfg[MAX_CARDS];
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Component carrier ID for this PHY instance
@@ -227,7 +227,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
sym = (sym == 0) ? 5 : sym + 1;
}
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false, ue->openair0_cfg);
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
+1 -2
View File
@@ -924,8 +924,7 @@ printf("%d\n", slot);
init_nr_ue_transport(UE);
nr_l2_init_ue(1);
UE_mac = get_mac_inst(0);
UE_mac = nr_l2_init_ue(0);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0);
+1 -2
View File
@@ -780,8 +780,7 @@ int main(int argc, char *argv[])
init_nr_ue_transport(UE);
//Configure UE
nr_l2_init_ue(1);
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
NR_UE_MAC_INST_t* UE_mac = nr_l2_init_ue(0);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
-8
View File
@@ -85,14 +85,6 @@ MESSAGE_DEF(NAS_INIT_NOS1_IF, MESSAGE_PRIORITY_MED, nas_nos1_msg_t, nas_init_nos
MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFrameProcess, nr_rrc_frame_process)
// UE: RRC -> MAC messages
MESSAGE_DEF(NR_MAC_RRC_CONFIG_RESET, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_reset_t, nr_mac_rrc_config_reset)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_CG, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_cg_t, nr_mac_rrc_config_cg)
MESSAGE_DEF(NR_MAC_RRC_RESUME_RB, MESSAGE_PRIORITY_MED, nr_mac_rrc_resume_rb_t, nr_mac_rrc_resume_rb)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_MIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_mib_t, nr_mac_rrc_config_mib)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_SIB1, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_sib1_t, nr_mac_rrc_config_sib1)
MESSAGE_DEF(NR_MAC_RRC_CONFIG_OTHER_SIB, MESSAGE_PRIORITY_MED, nr_mac_rrc_config_other_sib_t, nr_mac_rrc_config_other_sib)
// eNB: RLC -> RRC messages
MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication)
MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req)
+21 -6
View File
@@ -105,12 +105,6 @@
#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa
#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req
#define NR_MAC_RRC_CONFIG_RESET(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_reset
#define NR_MAC_RRC_CONFIG_CG(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_cg
#define NR_MAC_RRC_RESUME_RB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_resume_rb
#define NR_MAC_RRC_CONFIG_MIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_mib
#define NR_MAC_RRC_CONFIG_SIB1(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_sib1
#define NR_MAC_RRC_CONFIG_OTHER_SIB(mSGpTR) (mSGpTR)->ittiMsg.nr_mac_rrc_config_other_sib
#define NR_RRC_RLC_MAXRTX(mSGpTR) (mSGpTR)->ittiMsg.nr_rlc_maxrtx_indication
@@ -497,4 +491,25 @@ typedef struct {
bool can_start_ra;
} nr_mac_rrc_config_other_sib_t;
enum payload_type {
NR_MAC_RRC_CONFIG_RESET,
NR_MAC_RRC_CONFIG_CG,
NR_MAC_RRC_CONFIG_MIB,
NR_MAC_RRC_CONFIG_SIB1,
NR_MAC_RRC_CONFIG_OTHER_SIB,
NR_MAC_RRC_RESUME_RB
};
typedef struct {
enum payload_type payload_type;
union {
nr_mac_rrc_config_reset_t config_reset;
nr_mac_rrc_config_cg_t config_cg;
nr_mac_rrc_config_mib_t config_mib;
nr_mac_rrc_config_sib1_t config_sib1;
nr_mac_rrc_config_other_sib_t config_other_sib;
nr_mac_rrc_resume_rb_t resume_rb;
} payload;
} nr_mac_rrc_message_t;
#endif /* RRC_MESSAGES_TYPES_H_ */
+1
View File
@@ -654,6 +654,7 @@ typedef struct NR_UE_MAC_INST_s {
bool msg3_C_RNTI;
pthread_mutex_t if_mutex;
ue_mac_stats_t stats;
notifiedFIFO_t input_nf;
} NR_UE_MAC_INST_t;
static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ta, int scs)
+25 -23
View File
@@ -38,7 +38,7 @@
#include "nr_rlc/nr_rlc_oai_api.h"
#include "RRC/NR_UE/rrc_proto.h"
#include <pthread.h>
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
static NR_UE_MAC_INST_t *nr_ue_mac_inst[MAX_NUM_NR_UE_INST] = {0};
void send_srb0_rrc(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data)
{
@@ -70,6 +70,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
mac->p_Max_alt = INT_MIN;
mac->msg3_C_RNTI = false;
mac->ntn_ta.ntn_params_changed = false;
initNotifiedFIFO(&mac->input_nf);
reset_mac_inst(mac);
// need to inizialize because might not been setup (optional timer)
@@ -124,37 +125,38 @@ NR_UE_L2_STATE_t nr_ue_get_sync_state(module_id_t mod_id)
return mac->state;
}
NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst)
NR_UE_MAC_INST_t *nr_l2_init_ue(int instance_id)
{
//init mac here
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(nb_inst, sizeof(NR_UE_MAC_INST_t));
AssertFatal(nr_ue_mac_inst, "Couldn't allocate %d instances of MAC module\n", nb_inst);
AssertFatal(instance_id < MAX_NUM_NR_UE_INST, "instance_id %d is out of range\n", instance_id);
AssertFatal(nr_ue_mac_inst[instance_id] == NULL, "MAC instance %d already initialized\n", instance_id);
nr_ue_mac_inst[instance_id] = calloc_or_fail(1, sizeof(NR_UE_MAC_INST_t));
for (int j = 0; j < nb_inst; j++) {
NR_UE_MAC_INST_t *mac = &nr_ue_mac_inst[j];
mac->ue_id = j;
nr_ue_init_mac(mac);
int ret = pthread_mutex_init(&mac->if_mutex, NULL);
AssertFatal(ret == 0, "Mutex init failed\n");
nr_ue_mac_default_configs(mac);
if (IS_SA_MODE(get_softmodem_params()))
ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology));
NR_UE_MAC_INST_t *mac = nr_ue_mac_inst[instance_id];
mac->ue_id = instance_id;
nr_ue_init_mac(mac);
int ret = pthread_mutex_init(&mac->if_mutex, NULL);
AssertFatal(ret == 0, "Mutex init failed\n");
nr_ue_mac_default_configs(mac);
if (IS_SA_MODE(get_softmodem_params()))
ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology));
static bool initialized = false;
if (!initialized) {
int rc = nr_rlc_module_init(NR_RLC_OP_MODE_UE);
AssertFatal(rc == 0, "Could not initialize RLC layer\n");
initialized = true;
}
int rc = nr_rlc_module_init(NR_RLC_OP_MODE_UE);
AssertFatal(rc == 0, "Could not initialize RLC layer\n");
nr_rlc_activate_srb0(instance_id, NULL, send_srb0_rrc);
for (int j = 0; j < nb_inst; j++) {
nr_rlc_activate_srb0(j, NULL, send_srb0_rrc);
}
return (nr_ue_mac_inst);
return nr_ue_mac_inst[instance_id];
}
NR_UE_MAC_INST_t *get_mac_inst(module_id_t module_id)
{
NR_UE_MAC_INST_t *mac = &nr_ue_mac_inst[(int)module_id];
AssertFatal(mac, "Couldn't get MAC inst %d\n", module_id);
AssertFatal(module_id < MAX_NUM_NR_UE_INST, "module_id %d is out of range\n", module_id);
NR_UE_MAC_INST_t *mac = nr_ue_mac_inst[module_id];
if (mac == NULL) return NULL;
AssertFatal(mac->ue_id == module_id, "MAC ID %d doesn't match with input %d\n", mac->ue_id, module_id);
return mac;
}
+7 -2
View File
@@ -755,8 +755,13 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dlsch_pdu->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2;
} else {
dlsch_pdu->SubcarrierSpacing = current_DL_BWP->scs;
if (nr_timer_is_active(&mac->ra.response_window_timer) && rnti_type == TYPE_RA_RNTI_) {
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
if (rnti_type == TYPE_RA_RNTI_) {
if (nr_timer_is_active(&mac->ra.response_window_timer)) {
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
} else {
// Discard the DCI
return -1;
}
} else {
dl_conf_req->pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
}
+1 -1
View File
@@ -1312,7 +1312,7 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio
// resume RAR response window timer if MSG2 decoding failed
nr_timer_suspension(&mac->ra.response_window_timer);
} else {
LOG_I(PHY, "RAR-Msg2 decoded\n");
LOG_I(PHY, "[UE %d] RAR-Msg2 decoded\n", mac->ue_id);
}
ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
break;
+18 -20
View File
@@ -121,42 +121,40 @@ void nr_mac_rrc_data_ind_ue(const module_id_t module_id,
}
}
void process_msg_rcc_to_mac(MessageDef *msg)
void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id)
{
instance_t ue_id = ITTI_MSG_DESTINATION_INSTANCE(msg);
switch (ITTI_MSG_ID(msg)) {
switch (msg->payload_type) {
case NR_MAC_RRC_CONFIG_RESET:
nr_rrc_mac_config_req_reset(ue_id, NR_MAC_RRC_CONFIG_RESET(msg).cause);
nr_rrc_mac_config_req_reset(instance_id, msg->payload.config_reset.cause);
break;
case NR_MAC_RRC_CONFIG_CG:
nr_rrc_mac_config_req_cg(ue_id, 0, NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig, NR_MAC_RRC_CONFIG_CG(msg).UE_NR_Capability);
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig);
nr_rrc_mac_config_req_cg(instance_id, 0, msg->payload.config_cg.cellGroupConfig, msg->payload.config_cg.UE_NR_Capability);
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, msg->payload.config_cg.cellGroupConfig);
break;
case NR_MAC_RRC_CONFIG_MIB:
nr_rrc_mac_config_req_mib(ue_id,
nr_rrc_mac_config_req_mib(instance_id,
0,
NR_MAC_RRC_CONFIG_MIB(msg).bcch->message.choice.mib,
NR_MAC_RRC_CONFIG_MIB(msg).get_sib,
NR_MAC_RRC_CONFIG_MIB(msg).access_barred);
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, NR_MAC_RRC_CONFIG_MIB(msg).bcch);
msg->payload.config_mib.bcch->message.choice.mib,
msg->payload.config_mib.get_sib,
msg->payload.config_mib.access_barred);
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, msg->payload.config_mib.bcch);
break;
case NR_MAC_RRC_CONFIG_SIB1: {
NR_SIB1_t *sib1 = NR_MAC_RRC_CONFIG_SIB1(msg).sib1;
bool can_start_ra = NR_MAC_RRC_CONFIG_SIB1(msg).can_start_ra;
nr_rrc_mac_config_req_sib1(ue_id, 0, sib1, can_start_ra);
SEQUENCE_free(&asn_DEF_NR_SIB1, NR_MAC_RRC_CONFIG_SIB1(msg).sib1, ASFM_FREE_EVERYTHING);
NR_SIB1_t *sib1 = msg->payload.config_sib1.sib1;
bool can_start_ra = msg->payload.config_sib1.can_start_ra;
nr_rrc_mac_config_req_sib1(instance_id, 0, sib1, can_start_ra);
SEQUENCE_free(&asn_DEF_NR_SIB1, msg->payload.config_sib1.sib1, ASFM_FREE_EVERYTHING);
} break;
case NR_MAC_RRC_CONFIG_OTHER_SIB: {
bool can_start_ra = NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra;
nr_rrc_mac_config_other_sib(ue_id, NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, can_start_ra);
bool can_start_ra = msg->payload.config_other_sib.can_start_ra;
nr_rrc_mac_config_other_sib(instance_id, msg->payload.config_other_sib.sib19, can_start_ra);
} break;
case NR_MAC_RRC_RESUME_RB:
nr_rrc_mac_resume_rb(ue_id, NR_MAC_RRC_RESUME_RB(msg).is_srb, NR_MAC_RRC_RESUME_RB(msg).rb_id);
nr_rrc_mac_resume_rb(instance_id, msg->payload.resume_rb.is_srb, msg->payload.resume_rb.rb_id);
break;
default:
LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", ITTI_MSG_ID(msg));
LOG_E(NR_MAC, "Unexpected msg from RRC: %d\n", msg->payload_type);
}
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
}
void nr_mac_rrc_inactivity_timer_ind(const module_id_t mod_id)
+1 -1
View File
@@ -42,6 +42,6 @@ void nr_mac_rrc_msg3_ind(const module_id_t mod_id, const int rnti, bool prepare_
void nr_ue_rrc_timer_trigger(int instance, int frame, int gnb_id);
void nr_mac_rrc_ra_ind(const module_id_t mod_id, bool success);
void nsa_sendmsg_to_lte_ue(const void *message, size_t msg_len, Rrc_Msg_Type_t msg_type);
void process_msg_rcc_to_mac(MessageDef *msg);
void process_msg_rcc_to_mac(nr_mac_rrc_message_t *msg, int instance_id);
#endif
+163 -124
View File
@@ -72,7 +72,7 @@
#include "nr_nas_msg.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
static NR_UE_RRC_INST_t *NR_UE_rrc_inst;
static NR_UE_RRC_INST_t *NR_UE_rrc_inst[MAX_NUM_NR_UE_INST] = {0};
/* NAS Attach request with IMSI */
static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = {
0x07,
@@ -149,9 +149,29 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers);
NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance)
/**
* @brief Sends an RRC message to the connected UE MAC instance.
*
* @param rrc UE RRC instance structure
* @param msg RRC message to be sent to MAC
*/
static void nr_rrc_send_msg_to_mac(NR_UE_RRC_INST_t *rrc, nr_mac_rrc_message_t *msg)
{
return &NR_UE_rrc_inst[instance];
AssertFatal(rrc->mac_input_nf != NULL, "MAC input NF is NULL for UE %ld\n", rrc->ue_id);
notifiedFIFO_elt_t *nf_msg = newNotifiedFIFO_elt(sizeof(nr_mac_rrc_message_t), 0, NULL, NULL);
nr_mac_rrc_message_t *rrc_msg = NotifiedFifoData(nf_msg);
memcpy(rrc_msg, msg, sizeof(nr_mac_rrc_message_t));
pushNotifiedFIFO(rrc->mac_input_nf, nf_msg);
}
NR_UE_RRC_INST_t *get_NR_UE_rrc_inst(int instance)
{
AssertFatal(instance >= 0 && instance < MAX_NUM_NR_UE_INST, "RRC instance %d out of bounds\n", instance);
NR_UE_RRC_INST_t *rrc = NR_UE_rrc_inst[instance];
if (rrc == NULL)
return NULL;
AssertFatal(rrc->ue_id == instance, "RRC ID %d doesn't match with input %d\n", (int)rrc->ue_id, instance);
return rrc;
}
static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id)
@@ -281,7 +301,6 @@ static void nr_rrc_process_ntnconfig(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *S
static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, NR_UE_RRC_INST_t *rrc, int frame)
{
instance_t ue_id = rrc->ue_id;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN);
// Dump contents
@@ -365,10 +384,12 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si,
}
if (sib19) {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_OTHER_SIB);
asn_copy(&asn_DEF_NR_SIB19_r17, (void **)&NR_MAC_RRC_CONFIG_OTHER_SIB(msg).sib19, sib19);
NR_MAC_RRC_CONFIG_OTHER_SIB(msg).can_start_ra = rrc->is_NTN_UE;
itti_send_msg_to_task(TASK_MAC_UE, ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_OTHER_SIB;
nr_mac_rrc_config_other_sib_t *sib19_msg = &rrc_msg.payload.config_other_sib;
asn_copy(&asn_DEF_NR_SIB19_r17, (void **)&sib19_msg->sib19, sib19);
sib19_msg->can_start_ra = rrc->is_NTN_UE;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT);
}
@@ -502,10 +523,13 @@ static void nr_rrc_process_sib1(NR_UE_RRC_INST_t *rrc, NR_UE_RRC_SI_INFO *SI_inf
nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1);
// RRC storage of SIB1 timers and constants (eg needed in re-establishment)
UPDATE_IE(rrc->timers_and_constants.sib1_TimersAndConstants, sib1->ue_TimersAndConstants, NR_UE_TimersAndConstants_t);
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_SIB1);
NR_MAC_RRC_CONFIG_SIB1(msg).sib1 = sib1;
NR_MAC_RRC_CONFIG_SIB1(msg).can_start_ra = !rrc->is_NTN_UE;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_SIB1;
nr_mac_rrc_config_sib1_t *config_sib1 = &rrc_msg.payload.config_sib1;
config_sib1->sib1 = sib1;
config_sib1->can_start_ra = !rrc->is_NTN_UE;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCReconfiguration_v1530_IEs_t *rec_1530, int gNB_index)
@@ -644,12 +668,12 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc, int gNB_
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
AssertFatal(!IS_SA_MODE(get_softmodem_params()), "secondaryCellGroup only used in NSA for now\n");
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_CG);
// cellGroupConfig will be managed by MAC
NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig = cellGroupConfig;
// UE_NR_Capability remain a race condition between this rrc thread and mac thread
NR_MAC_RRC_CONFIG_CG(msg).UE_NR_Capability = rrc->UECap.UE_NR_Capability;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG;
nr_mac_rrc_config_cg_t *config_cg = &rrc_msg.payload.config_cg;
config_cg->cellGroupConfig = cellGroupConfig;
config_cg->UE_NR_Capability = rrc->UECap.UE_NR_Capability;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
if (ie->measConfig) {
LOG_I(NR_RRC, "RRCReconfiguration includes Measurement Configuration\n");
@@ -731,67 +755,63 @@ static bool verify_ue_cap(NR_UE_NR_Capability_t *UE_NR_Capability, int nb_antenn
return true;
}
NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx)
NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int instance_id, int num_ant_tx)
{
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(nb_inst, sizeof(NR_UE_RRC_INST_t));
AssertFatal(NR_UE_rrc_inst, "Couldn't allocate %d instances of RRC module\n", nb_inst);
AssertFatal(instance_id < MAX_NUM_NR_UE_INST, "RRC instance %d out of bounds\n", instance_id);
AssertFatal(NR_UE_rrc_inst[instance_id] == NULL, "RRC instance %d already initialized\n", instance_id);
NR_UE_rrc_inst[instance_id] = calloc_or_fail(1, sizeof(NR_UE_RRC_INST_t));
NR_UE_RRC_INST_t *rrc = NR_UE_rrc_inst[instance_id];
rrc->ue_id = instance_id;
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
rrc->selected_plmn_identity = 1;
rrc->ra_trigger = RA_NOT_RUNNING;
rrc->dl_bwp_id = 0;
rrc->ul_bwp_id = 0;
rrc->as_security_activated = false;
rrc->detach_after_release = false;
rrc->reconfig_after_reestab = false;
/* 5G-S-TMSI */
rrc->fiveG_S_TMSI = UINT64_MAX;
rrc->access_barred = false;
for(int nr_ue = 0; nr_ue < nb_inst; nr_ue++) {
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[nr_ue];
rrc->ue_id = nr_ue;
// fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
rrc->selected_plmn_identity = 1;
rrc->ra_trigger = RA_NOT_RUNNING;
rrc->dl_bwp_id = 0;
rrc->ul_bwp_id = 0;
rrc->as_security_activated = false;
rrc->detach_after_release = false;
rrc->reconfig_after_reestab = false;
/* 5G-S-TMSI */
rrc->fiveG_S_TMSI = UINT64_MAX;
rrc->access_barred = false;
FILE *f = NULL;
if (uecap_file)
f = fopen(uecap_file, "r");
if (f) {
char UE_NR_Capability_xer[65536];
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
}
else {
asn_dec_rval_t dec_rval =
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
assert(dec_rval.code == RC_OK);
}
fclose(f);
/* Verify consistency of num PHY antennas vs UE Capabilities */
verify_ue_cap(rrc->UECap.UE_NR_Capability, num_ant_tx);
FILE *f = NULL;
if (uecap_file)
f = fopen(uecap_file, "r");
if (f) {
char UE_NR_Capability_xer[65536];
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
LOG_E(NR_RRC, "UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
} else {
asn_dec_rval_t dec_rval =
xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&rrc->UECap.UE_NR_Capability, UE_NR_Capability_xer, size);
assert(dec_rval.code == RC_OK);
}
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
set_default_timers_and_constants(&rrc->timers_and_constants);
for (int j = 0; j < NR_NUM_SRB; j++)
rrc->Srb[j] = RB_NOT_PRESENT;
for (int j = 1; j <= MAX_DRBS_PER_UE; j++)
set_DRB_status(rrc, j, RB_NOT_PRESENT);
// SRB0 activated by default
rrc->Srb[0] = RB_ESTABLISHED;
for (int j = 0; j < NR_MAX_NUM_LCID; j++)
rrc->active_RLC_entity[j] = false;
for (int i = 0; i < NB_CNX_UE; i++) {
rrcPerNB_t *ptr = &rrc->perNB[i];
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
init_SI_timers(&ptr->SInfo);
}
init_sidelink(rrc);
fclose(f);
/* Verify consistency of num PHY antennas vs UE Capabilities */
verify_ue_cap(rrc->UECap.UE_NR_Capability, num_ant_tx);
}
return NR_UE_rrc_inst;
memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants));
set_default_timers_and_constants(&rrc->timers_and_constants);
for (int j = 0; j < NR_NUM_SRB; j++)
rrc->Srb[j] = RB_NOT_PRESENT;
for (int j = 1; j <= MAX_DRBS_PER_UE; j++)
set_DRB_status(rrc, j, RB_NOT_PRESENT);
// SRB0 activated by default
rrc->Srb[0] = RB_ESTABLISHED;
for (int j = 0; j < NR_MAX_NUM_LCID; j++)
rrc->active_RLC_entity[j] = false;
for (int i = 0; i < NB_CNX_UE; i++) {
rrcPerNB_t *ptr = &rrc->perNB[i];
ptr->SInfo = (NR_UE_RRC_SI_INFO){0};
init_SI_timers(&ptr->SInfo);
}
init_sidelink(rrc);
return rrc;
}
bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type)
@@ -973,12 +993,13 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
SI_info->sib_pending = true;
}
if (bcch_message->message.present == NR_BCCH_BCH_MessageType_PR_mib) {
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_MIB);
// mac will manage the pointer
NR_MAC_RRC_CONFIG_MIB(msg).bcch = bcch_message;
NR_MAC_RRC_CONFIG_MIB(msg).get_sib = get_sib;
NR_MAC_RRC_CONFIG_MIB(msg).access_barred = barred;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_MIB;
nr_mac_rrc_config_mib_t *config_mib = &rrc_msg.payload.config_mib;
config_mib->bcch = bcch_message;
config_mib->get_sib = get_sib;
config_mib->access_barred = barred;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
} else {
LOG_E(NR_RRC, "RRC-received BCCH message is not a MIB\n");
ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message);
@@ -1036,10 +1057,11 @@ static void nr_rrc_handle_msg3_indication(NR_UE_RRC_INST_t *rrc, rnti_t rnti)
nr_rlc_reconfigure_entity(rrc->ue_id, lc_id, NULL);
// resume SRB1
rrc->Srb[srb_id] = RB_ESTABLISHED;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
NR_MAC_RRC_RESUME_RB(msg).is_srb = true;
NR_MAC_RRC_RESUME_RB(msg).rb_id = 1;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_RESUME_RB;
rrc_msg.payload.resume_rb.is_srb = true;
rrc_msg.payload.resume_rb.rb_id = 1;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
break;
case DURING_HANDOVER:
AssertFatal(1==0, "ra_trigger not implemented yet!\n");
@@ -1260,10 +1282,12 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
nr_rrc_cellgroup_configuration(rrc, cellGroupConfig, gNB_index);
LOG_D(RRC, "Sending CellGroupConfig to MAC the pointer will be managed by mac\n");
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_CG);
NR_MAC_RRC_CONFIG_CG(msg).cellGroupConfig = cellGroupConfig;
NR_MAC_RRC_CONFIG_CG(msg).UE_NR_Capability = rrc->UECap.UE_NR_Capability;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_CG;
nr_mac_rrc_config_cg_t *mac_msg = &rrc_msg.payload.config_cg;
mac_msg->cellGroupConfig = cellGroupConfig;
mac_msg->UE_NR_Capability = rrc->UECap.UE_NR_Capability;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const uint8_t Transaction_id)
@@ -1345,9 +1369,10 @@ static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
// default MAC Cell Group configuration and CCCH configuration
// TODO to be completed
NR_UE_MAC_reset_cause_t cause = RRC_SETUP_REESTAB_RESUME;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
rrc_msg.payload.config_reset.cause = cause;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
// indicate to upper layers fallback of the RRC connection
// TODO
@@ -1411,9 +1436,10 @@ static void nr_rrc_process_rrcreject(NR_UE_RRC_INST_t *rrc, const NR_RRCReject_t
// reset MAC and release the default MAC Cell Group configuration
NR_UE_MAC_reset_cause_t cause = REJECT;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
rrc_msg.payload.config_reset.cause = cause;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
// if waitTime is configured in the RRCReject: start timer T302, with the timer value set to the waitTime
NR_RejectWaitTime_t *waitTime = NULL;
@@ -2121,18 +2147,20 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
// resume SRB2 and DRBs that are suspended
if (rrc->Srb[2] == RB_SUSPENDED) {
rrc->Srb[2] = RB_ESTABLISHED;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
NR_MAC_RRC_RESUME_RB(msg).is_srb = true;
NR_MAC_RRC_RESUME_RB(msg).rb_id = 2;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_RESUME_RB;
rrc_msg.payload.resume_rb.is_srb = true;
rrc_msg.payload.resume_rb.rb_id = 2;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
if (get_DRB_status(rrc, i) == RB_SUSPENDED) {
set_DRB_status(rrc, i, RB_ESTABLISHED);
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_RESUME_RB);
NR_MAC_RRC_RESUME_RB(msg).is_srb = false;
NR_MAC_RRC_RESUME_RB(msg).rb_id = i;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_RESUME_RB;
rrc_msg.payload.resume_rb.is_srb = true;
rrc_msg.payload.resume_rb.rb_id = i;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
}
rrc->reconfig_after_reestab = false;
@@ -2246,7 +2274,7 @@ void *rrc_nrue(void *notUsed)
instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p);
LOG_D(NR_RRC, "[UE %ld] Received %s\n", instance, ITTI_MSG_NAME(msg_p));
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
AssertFatal(instance == rrc->ue_id, "Instance %ld received from ITTI doesn't matach with UE-ID %ld\n", instance, rrc->ue_id);
switch (ITTI_MSG_ID(msg_p)) {
@@ -2335,11 +2363,11 @@ void *rrc_nrue(void *notUsed)
case NR_RRC_DCCH_DATA_IND:
nr_rrc_ue_decode_dcch(rrc,
NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
NR_RRC_DCCH_DATA_IND(msg_p).sdu_p,
NR_RRC_DCCH_DATA_IND(msg_p).sdu_size,
NR_RRC_DCCH_DATA_IND(msg_p).gNB_index,
&NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity);
NR_RRC_DCCH_DATA_IND(msg_p).dcch_index,
NR_RRC_DCCH_DATA_IND(msg_p).sdu_p,
NR_RRC_DCCH_DATA_IND(msg_p).sdu_size,
NR_RRC_DCCH_DATA_IND(msg_p).gNB_index,
&NR_RRC_DCCH_DATA_IND(msg_p).msg_integrity);
/* this is allocated by itti_malloc in PDCP task (deliver_sdu_srb)
then passed to the RRC task and freed after use */
free(NR_RRC_DCCH_DATA_IND(msg_p).sdu_p);
@@ -2511,9 +2539,10 @@ static void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc, NR_Reestab
// reset MAC
// release spCellConfig, if configured
// perform cell selection in accordance with the cell selection process
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
NR_MAC_RRC_CONFIG_RESET(msg).cause = RE_ESTABLISHMENT;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
rrc_msg.payload.config_reset.cause = RE_ESTABLISHMENT;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
static void nr_rrc_ue_generate_rrcReestablishmentComplete(const NR_UE_RRC_INST_t *rrc,
@@ -2541,7 +2570,7 @@ void *recv_msgs_from_lte_ue(void *args_p)
LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
continue;
}
process_lte_nsa_msg(NR_UE_rrc_inst, &msg, recvLen);
process_lte_nsa_msg(get_NR_UE_rrc_inst(0), &msg, recvLen);
}
return NULL;
}
@@ -2679,8 +2708,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
process_nsa_message(get_NR_UE_rrc_inst(0), nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, nr_SecondaryCellGroup_size);
process_nsa_message(get_NR_UE_rrc_inst(0), nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
uint8_t buffer[NR_RRC_BUF_SIZE];
size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
@@ -2886,9 +2915,10 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
// reset MAC
NR_UE_MAC_reset_cause_t cause = (rrc->nrRrcState == RRC_STATE_DETACH_NR) ? DETACH : GO_TO_IDLE;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
rrc_msg.payload.config_reset.cause = cause;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
// enter RRC_IDLE
LOG_I(NR_RRC, "RRC moved into IDLE state\n");
@@ -2917,9 +2947,11 @@ void handle_t300_expiry(NR_UE_RRC_INST_t *rrc)
// reset MAC, release the MAC configuration
NR_UE_MAC_reset_cause_t cause = T300_EXPIRY;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
rrc_msg.payload.config_reset.cause = cause;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
// TODO handle connEstFailureControl
// TODO inform upper layers about the failure to establish the RRC connection
}
@@ -2935,16 +2967,17 @@ void handle_t430_expiry(NR_UE_RRC_INST_t *rrc)
}
// Indicate MAC that UL SYNC is LOST
NR_UE_MAC_reset_cause_t cause = UL_SYNC_LOST_T430_EXPIRED;
MessageDef *msg = itti_alloc_new_message(TASK_RRC_NRUE, 0, NR_MAC_RRC_CONFIG_RESET);
NR_MAC_RRC_CONFIG_RESET(msg).cause = cause;
itti_send_msg_to_task(TASK_MAC_UE, rrc->ue_id, msg);
nr_mac_rrc_message_t rrc_msg = {0};
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
rrc_msg.payload.config_reset.cause = cause;
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
}
//This calls the sidelink preconf message after RRC, MAC instances are created.
void start_sidelink(int instance)
{
NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[instance];
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
if (get_softmodem_params()->sl_mode == 2) {
@@ -2953,3 +2986,9 @@ void start_sidelink(int instance)
}
}
void nr_rrc_set_mac_queue(instance_t instance, notifiedFIFO_t *mac_input_nf)
{
NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(instance);
rrc->mac_input_nf = mac_input_nf;
}
+2
View File
@@ -63,6 +63,7 @@
#include "RRC/NR/nr_rrc_common.h"
#include "as_message.h"
#include "common/utils/nr/nr_common.h"
#include "notified_fifo.h"
#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE
#define MAX_MEAS_OBJ 64
@@ -248,6 +249,7 @@ typedef struct NR_UE_RRC_INST_s {
NR_SL_PreconfigurationNR_r16_t *sl_preconfig;
// NTN params
bool is_NTN_UE;
notifiedFIFO_t *mac_input_nf;
} NR_UE_RRC_INST_t;
#endif
+2
View File
@@ -106,6 +106,8 @@ void nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message(NR_UE_RRC_INST_t *rrc,
const sdu_size_t pdu_len,
const uint16_t rx_slss_id);
void nr_rrc_set_mac_queue(instance_t instance, notifiedFIFO_t *mac_input_nf);
/** @}*/
#endif
+2 -4
View File
@@ -76,9 +76,7 @@
#include "key_nas_deriver.h"
#include "nr-uesoftmodem.h"
#define MAX_NAS_UE 4
static nr_ue_nas_t nr_ue_nas[MAX_NAS_UE] = {0};
static nr_ue_nas_t nr_ue_nas[MAX_NUM_NR_UE_INST] = {0};
#define FOREACH_STATE(TYPE_DEF) \
TYPE_DEF(NAS_SECURITY_NO_SECURITY_CONTEXT, 0) \
@@ -676,7 +674,7 @@ static void derive_ue_keys(uint8_t *buf, nr_ue_nas_t *nas)
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id)
{
DevAssert(module_id < MAX_NAS_UE);
AssertFatal(module_id < MAX_NUM_NR_UE_INST, "Invalid module_id %d\n", module_id);
if (!nr_ue_nas[module_id].uicc) {
nr_ue_nas[module_id].uicc = checkUicc(module_id);
nr_ue_nas[module_id].UE_id = module_id;