Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-RAN
Commits
44ce13d7
Commit
44ce13d7
authored
Aug 02, 2018
by
Raymond Knopp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added ru_control.c (extraction of RU state-machine and support functions for fronthaul)
parent
011818e9
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
757 additions
and
0 deletions
+757
-0
targets/RT/USER/ru_control.c
targets/RT/USER/ru_control.c
+757
-0
No files found.
targets/RT/USER/ru_control.c
0 → 100644
View file @
44ce13d7
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file lte-ru.c
* \brief Top-level threads for RU entity
* \author R. Knopp, F. Kaltenberger, Navid Nikaein
* \date 2012
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
* \note
* \warning
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
#include <linux/sched.h>
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
#include <sys/sysinfo.h>
#include "rt_wrapper.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#include "assertions.h"
#include "msc.h"
#include "PHY/types.h"
#include "PHY/defs_common.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
#include "../../ARCH/COMMON/common_lib.h"
#include "../../ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
#include "PHY/phy_extern.h"
#include "LAYER2/MAC/mac_extern.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "SCHED/sched_eNB.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/INIT/phy_init.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
#include "UTIL/LOG/log_extern.h"
#include "UTIL/OTG/otg_tx.h"
#include "UTIL/OTG/otg_externs.h"
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "enb_config.h"
void
configure_ru
(
int
idx
,
void
*
arg
);
void
configure_rru
(
int
idx
,
void
*
arg
);
int
attach_rru
(
RU_t
*
ru
);
void
fill_rf_config
(
RU_t
*
ru
,
char
*
rf_config_file
);
void
*
ru_thread_control
(
void
*
param
);
extern
void
phy_init_RU
(
RU_t
*
);
extern
const
char
ru_states
[
6
][
9
];
const
char
rru_format_options
[
4
][
20
]
=
{
"OAI_IF5_only"
,
"OAI_IF4p5_only"
,
"OAI_IF5_and_IF4p5"
,
"MBP_IF5"
};
const
char
rru_formats
[
3
][
20
]
=
{
"OAI_IF5"
,
"MBP_IF5"
,
"OAI_IF4p5"
};
const
char
ru_if_formats
[
4
][
20
]
=
{
"LOCAL_RF"
,
"REMOTE_OAI_IF5"
,
"REMOTE_MBP_IF5"
,
"REMOTE_OAI_IF4p5"
};
extern
int
oai_exit
;
extern
void
wait_eNBs
(
void
);
int
send_tick
(
RU_t
*
ru
){
RRU_CONFIG_msg_t
rru_config_msg
;
rru_config_msg
.
type
=
RAU_tick
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
;
LOG_I
(
PHY
,
"Sending RAU tick to RRU %d
\n
"
,
ru
->
idx
);
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d cannot access remote radio
\n
"
,
ru
->
idx
);
return
0
;
}
int
send_config
(
RU_t
*
ru
,
RRU_CONFIG_msg_t
rru_config_msg
){
rru_config_msg
.
type
=
RRU_config
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_config_t
);
LOG_I
(
PHY
,
"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d
\n
"
,
ru
->
idx
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
num_bands
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
band_list
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
tx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
rx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_tx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_rx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_DL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_UL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
threequarter_fs
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_FreqOffset
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_ConfigIndex
[
0
]);
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d failed send configuration to remote radio
\n
"
,
ru
->
idx
);
return
0
;
}
int
send_capab
(
RU_t
*
ru
){
RRU_CONFIG_msg_t
rru_config_msg
;
RRU_capabilities_t
*
cap
;
int
i
=
0
;
rru_config_msg
.
type
=
RRU_capabilities
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_capabilities_t
);
cap
=
(
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
];
LOG_I
(
PHY
,
"Sending Capabilities (len %d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)
\n
"
,
(
int
)
rru_config_msg
.
len
,
ru
->
num_bands
,
ru
->
max_pdschReferenceSignalPower
,
ru
->
max_rxgain
,
ru
->
nb_tx
,
ru
->
nb_rx
);
switch
(
ru
->
function
)
{
case
NGFI_RRU_IF4p5
:
cap
->
FH_fmt
=
OAI_IF4p5_only
;
break
;
case
NGFI_RRU_IF5
:
cap
->
FH_fmt
=
OAI_IF5_only
;
break
;
case
MBP_RRU_IF5
:
cap
->
FH_fmt
=
MBP_IF5
;
break
;
default:
AssertFatal
(
1
==
0
,
"RU_function is unknown %d
\n
"
,
RC
.
ru
[
0
]
->
function
);
break
;
}
cap
->
num_bands
=
ru
->
num_bands
;
for
(
i
=
0
;
i
<
ru
->
num_bands
;
i
++
)
{
LOG_I
(
PHY
,
"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d
\n
"
,
ru
->
band
[
i
],
ru
->
nb_rx
,
ru
->
nb_tx
,
ru
->
max_pdschReferenceSignalPower
,
ru
->
max_rxgain
);
cap
->
band_list
[
i
]
=
ru
->
band
[
i
];
cap
->
nb_rx
[
i
]
=
ru
->
nb_rx
;
cap
->
nb_tx
[
i
]
=
ru
->
nb_tx
;
cap
->
max_pdschReferenceSignalPower
[
i
]
=
ru
->
max_pdschReferenceSignalPower
;
cap
->
max_rxgain
[
i
]
=
ru
->
max_rxgain
;
}
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d failed send capabilities to RAU
\n
"
,
ru
->
idx
);
return
0
;
}
int
attach_rru
(
RU_t
*
ru
)
{
ssize_t
msg_len
,
len
;
RRU_CONFIG_msg_t
rru_config_msg
;
int
received_capabilities
=
0
;
wait_eNBs
();
// Wait for capabilities
while
(
received_capabilities
==
0
)
{
memset
((
void
*
)
&
rru_config_msg
,
0
,
sizeof
(
rru_config_msg
));
rru_config_msg
.
type
=
RAU_tick
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
;
LOG_I
(
PHY
,
"Sending RAU tick to RRU %d
\n
"
,
ru
->
idx
);
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d cannot access remote radio
\n
"
,
ru
->
idx
);
msg_len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_capabilities_t
);
// wait for answer with timeout
if
((
len
=
ru
->
ifdevice
.
trx_ctlrecv_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
msg_len
))
<
0
)
{
LOG_I
(
PHY
,
"Waiting for RRU %d
\n
"
,
ru
->
idx
);
}
else
if
(
rru_config_msg
.
type
==
RRU_capabilities
)
{
AssertFatal
(
rru_config_msg
.
len
==
msg_len
,
"Received capabilities with incorrect length (%d!=%d)
\n
"
,(
int
)
rru_config_msg
.
len
,(
int
)
msg_len
);
LOG_I
(
PHY
,
"Received capabilities from RRU %d (len %d/%d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)
\n
"
,
ru
->
idx
,
(
int
)
rru_config_msg
.
len
,(
int
)
msg_len
,
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
num_bands
,
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
max_pdschReferenceSignalPower
[
0
],
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
max_rxgain
[
0
],
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
nb_tx
[
0
],
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
nb_rx
[
0
]);
received_capabilities
=
1
;
}
else
{
LOG_E
(
PHY
,
"Received incorrect message %d from RRU %d
\n
"
,
rru_config_msg
.
type
,
ru
->
idx
);
}
}
configure_ru
(
ru
->
idx
,
(
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
]);
rru_config_msg
.
type
=
RRU_config
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_config_t
);
LOG_I
(
PHY
,
"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)
\n
"
,
ru
->
idx
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
num_bands
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
band_list
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
tx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
rx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_tx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_rx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_DL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_UL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
threequarter_fs
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_FreqOffset
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_ConfigIndex
[
0
]);
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d failed send configuration to remote radio
\n
"
,
ru
->
idx
);
return
0
;
}
int
connect_rau
(
RU_t
*
ru
)
{
RRU_CONFIG_msg_t
rru_config_msg
;
ssize_t
msg_len
;
int
tick_received
=
0
;
int
configuration_received
=
0
;
RRU_capabilities_t
*
cap
;
int
i
;
int
len
;
// wait for RAU_tick
while
(
tick_received
==
0
)
{
msg_len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
;
if
((
len
=
ru
->
ifdevice
.
trx_ctlrecv_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
msg_len
))
<
0
)
{
LOG_I
(
PHY
,
"Waiting for RAU
\n
"
);
}
else
{
if
(
rru_config_msg
.
type
==
RAU_tick
)
{
LOG_I
(
PHY
,
"Tick received from RAU
\n
"
);
tick_received
=
1
;
}
else
LOG_E
(
PHY
,
"Received erroneous message (%d)from RAU, expected RAU_tick
\n
"
,
rru_config_msg
.
type
);
}
}
// send capabilities
rru_config_msg
.
type
=
RRU_capabilities
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_capabilities_t
);
cap
=
(
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
];
LOG_I
(
PHY
,
"Sending Capabilities (len %d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)
\n
"
,
(
int
)
rru_config_msg
.
len
,
ru
->
num_bands
,
ru
->
max_pdschReferenceSignalPower
,
ru
->
max_rxgain
,
ru
->
nb_tx
,
ru
->
nb_rx
);
switch
(
ru
->
function
)
{
case
NGFI_RRU_IF4p5
:
cap
->
FH_fmt
=
OAI_IF4p5_only
;
break
;
case
NGFI_RRU_IF5
:
cap
->
FH_fmt
=
OAI_IF5_only
;
break
;
case
MBP_RRU_IF5
:
cap
->
FH_fmt
=
MBP_IF5
;
break
;
default:
AssertFatal
(
1
==
0
,
"RU_function is unknown %d
\n
"
,
RC
.
ru
[
0
]
->
function
);
break
;
}
cap
->
num_bands
=
ru
->
num_bands
;
for
(
i
=
0
;
i
<
ru
->
num_bands
;
i
++
)
{
LOG_I
(
PHY
,
"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d
\n
"
,
ru
->
band
[
i
],
ru
->
nb_rx
,
ru
->
nb_tx
,
ru
->
max_pdschReferenceSignalPower
,
ru
->
max_rxgain
);
cap
->
band_list
[
i
]
=
ru
->
band
[
i
];
cap
->
nb_rx
[
i
]
=
ru
->
nb_rx
;
cap
->
nb_tx
[
i
]
=
ru
->
nb_tx
;
cap
->
max_pdschReferenceSignalPower
[
i
]
=
ru
->
max_pdschReferenceSignalPower
;
cap
->
max_rxgain
[
i
]
=
ru
->
max_rxgain
;
}
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d failed send capabilities to RAU
\n
"
,
ru
->
idx
);
// wait for configuration
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_config_t
);
while
(
configuration_received
==
0
)
{
if
((
len
=
ru
->
ifdevice
.
trx_ctlrecv_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
))
<
0
)
{
LOG_I
(
PHY
,
"Waiting for configuration from RAU
\n
"
);
}
else
{
LOG_I
(
PHY
,
"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)
\n
"
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
num_bands
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
band_list
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
tx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
rx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_tx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_rx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_DL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_UL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
threequarter_fs
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_FreqOffset
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_ConfigIndex
[
0
]);
configure_rru
(
ru
->
idx
,
(
void
*
)
&
rru_config_msg
.
msg
[
0
]);
configuration_received
=
1
;
}
}
return
0
;
}
int
check_capabilities
(
RU_t
*
ru
,
RRU_capabilities_t
*
cap
)
{
FH_fmt_options_t
fmt
=
cap
->
FH_fmt
;
int
i
;
int
found_band
=
0
;
LOG_I
(
PHY
,
"RRU %d, num_bands %d, looking for band %d
\n
"
,
ru
->
idx
,
cap
->
num_bands
,
ru
->
frame_parms
.
eutra_band
);
for
(
i
=
0
;
i
<
cap
->
num_bands
;
i
++
)
{
LOG_I
(
PHY
,
"band %d on RRU %d
\n
"
,
cap
->
band_list
[
i
],
ru
->
idx
);
if
(
ru
->
frame_parms
.
eutra_band
==
cap
->
band_list
[
i
])
{
found_band
=
1
;
break
;
}
}
if
(
found_band
==
0
)
{
LOG_I
(
PHY
,
"Couldn't find target EUTRA band %d on RRU %d
\n
"
,
ru
->
frame_parms
.
eutra_band
,
ru
->
idx
);
return
(
-
1
);
}
switch
(
ru
->
if_south
)
{
case
LOCAL_RF
:
AssertFatal
(
1
==
0
,
"This RU should not have a local RF, exiting
\n
"
);
return
(
0
);
break
;
case
REMOTE_IF5
:
if
(
fmt
==
OAI_IF5_only
||
fmt
==
OAI_IF5_and_IF4p5
)
return
(
0
);
break
;
case
REMOTE_IF4p5
:
if
(
fmt
==
OAI_IF4p5_only
||
fmt
==
OAI_IF5_and_IF4p5
)
return
(
0
);
break
;
case
REMOTE_MBP_IF5
:
if
(
fmt
==
MBP_IF5
)
return
(
0
);
break
;
default:
LOG_I
(
PHY
,
"No compatible Fronthaul interface found for RRU %d
\n
"
,
ru
->
idx
);
return
(
-
1
);
}
return
(
-
1
);
}
void
configure_ru
(
int
idx
,
void
*
arg
)
{
RU_t
*
ru
=
RC
.
ru
[
idx
];
RRU_config_t
*
config
=
(
RRU_config_t
*
)
arg
;
RRU_capabilities_t
*
capabilities
=
(
RRU_capabilities_t
*
)
arg
;
int
ret
;
LOG_I
(
PHY
,
"Received capabilities from RRU %d
\n
"
,
idx
);
if
(
capabilities
->
FH_fmt
<
MAX_FH_FMTs
)
LOG_I
(
PHY
,
"RU FH options %s
\n
"
,
rru_format_options
[
capabilities
->
FH_fmt
]);
AssertFatal
((
ret
=
check_capabilities
(
ru
,
capabilities
))
==
0
,
"Cannot configure RRU %d, check_capabilities returned %d
\n
"
,
idx
,
ret
);
// take antenna capabilities of RRU
ru
->
nb_tx
=
capabilities
->
nb_tx
[
0
];
ru
->
nb_rx
=
capabilities
->
nb_rx
[
0
];
// Pass configuration to RRU
LOG_I
(
PHY
,
"Using %s fronthaul (%d), band %d
\n
"
,
ru_if_formats
[
ru
->
if_south
],
ru
->
if_south
,
ru
->
frame_parms
.
eutra_band
);
// wait for configuration
config
->
FH_fmt
=
ru
->
if_south
;
config
->
num_bands
=
1
;
config
->
band_list
[
0
]
=
ru
->
frame_parms
.
eutra_band
;
config
->
tx_freq
[
0
]
=
ru
->
frame_parms
.
dl_CarrierFreq
;
config
->
rx_freq
[
0
]
=
ru
->
frame_parms
.
ul_CarrierFreq
;
config
->
tdd_config
[
0
]
=
ru
->
frame_parms
.
tdd_config
;
config
->
tdd_config_S
[
0
]
=
ru
->
frame_parms
.
tdd_config_S
;
config
->
att_tx
[
0
]
=
ru
->
att_tx
;
config
->
att_rx
[
0
]
=
ru
->
att_rx
;
config
->
N_RB_DL
[
0
]
=
ru
->
frame_parms
.
N_RB_DL
;
config
->
N_RB_UL
[
0
]
=
ru
->
frame_parms
.
N_RB_UL
;
config
->
threequarter_fs
[
0
]
=
ru
->
frame_parms
.
threequarter_fs
;
if
(
ru
->
if_south
==
REMOTE_IF4p5
)
{
config
->
prach_FreqOffset
[
0
]
=
ru
->
frame_parms
.
prach_config_common
.
prach_ConfigInfo
.
prach_FreqOffset
;
config
->
prach_ConfigIndex
[
0
]
=
ru
->
frame_parms
.
prach_config_common
.
prach_ConfigInfo
.
prach_ConfigIndex
;
LOG_I
(
PHY
,
"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d
\n
"
,
config
->
prach_FreqOffset
[
0
],
config
->
prach_ConfigIndex
[
0
]);
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
int
i
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
config
->
emtc_prach_CElevel_enable
[
0
][
i
]
=
ru
->
frame_parms
.
prach_emtc_config_common
.
prach_ConfigInfo
.
prach_CElevel_enable
[
i
];
config
->
emtc_prach_FreqOffset
[
0
][
i
]
=
ru
->
frame_parms
.
prach_emtc_config_common
.
prach_ConfigInfo
.
prach_FreqOffset
[
i
];
config
->
emtc_prach_ConfigIndex
[
0
][
i
]
=
ru
->
frame_parms
.
prach_emtc_config_common
.
prach_ConfigInfo
.
prach_ConfigIndex
[
i
];
}
#endif
}
init_frame_parms
(
&
ru
->
frame_parms
,
1
);
phy_init_RU
(
ru
);
}
void
configure_rru
(
int
idx
,
void
*
arg
)
{
RRU_config_t
*
config
=
(
RRU_config_t
*
)
arg
;
RU_t
*
ru
=
RC
.
ru
[
idx
];
ru
->
frame_parms
.
eutra_band
=
config
->
band_list
[
0
];
ru
->
frame_parms
.
dl_CarrierFreq
=
config
->
tx_freq
[
0
];
ru
->
frame_parms
.
ul_CarrierFreq
=
config
->
rx_freq
[
0
];
if
(
ru
->
frame_parms
.
dl_CarrierFreq
==
ru
->
frame_parms
.
ul_CarrierFreq
)
{
ru
->
frame_parms
.
frame_type
=
TDD
;
ru
->
frame_parms
.
tdd_config
=
config
->
tdd_config
[
0
];
ru
->
frame_parms
.
tdd_config_S
=
config
->
tdd_config_S
[
0
];
}
else
ru
->
frame_parms
.
frame_type
=
FDD
;
ru
->
att_tx
=
config
->
att_tx
[
0
];
ru
->
att_rx
=
config
->
att_rx
[
0
];
ru
->
frame_parms
.
N_RB_DL
=
config
->
N_RB_DL
[
0
];
ru
->
frame_parms
.
N_RB_UL
=
config
->
N_RB_UL
[
0
];
ru
->
frame_parms
.
threequarter_fs
=
config
->
threequarter_fs
[
0
];
ru
->
frame_parms
.
pdsch_config_common
.
referenceSignalPower
=
ru
->
max_pdschReferenceSignalPower
-
config
->
att_tx
[
0
];
if
(
ru
->
function
==
NGFI_RRU_IF4p5
)
{
ru
->
frame_parms
.
att_rx
=
ru
->
att_rx
;
ru
->
frame_parms
.
att_tx
=
ru
->
att_tx
;
LOG_I
(
PHY
,
"Setting ru->function to NGFI_RRU_IF4p5, prach_FrequOffset %d, prach_ConfigIndex %d, att (%d,%d)
\n
"
,
config
->
prach_FreqOffset
[
0
],
config
->
prach_ConfigIndex
[
0
],
ru
->
att_tx
,
ru
->
att_rx
);
ru
->
frame_parms
.
prach_config_common
.
prach_ConfigInfo
.
prach_FreqOffset
=
config
->
prach_FreqOffset
[
0
];
ru
->
frame_parms
.
prach_config_common
.
prach_ConfigInfo
.
prach_ConfigIndex
=
config
->
prach_ConfigIndex
[
0
];
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
ru
->
frame_parms
.
prach_emtc_config_common
.
prach_ConfigInfo
.
prach_CElevel_enable
[
i
]
=
config
->
emtc_prach_CElevel_enable
[
0
][
i
];
ru
->
frame_parms
.
prach_emtc_config_common
.
prach_ConfigInfo
.
prach_FreqOffset
[
i
]
=
config
->
emtc_prach_FreqOffset
[
0
][
i
];
ru
->
frame_parms
.
prach_emtc_config_common
.
prach_ConfigInfo
.
prach_ConfigIndex
[
i
]
=
config
->
emtc_prach_ConfigIndex
[
0
][
i
];
}
#endif
}
init_frame_parms
(
&
ru
->
frame_parms
,
1
);
fill_rf_config
(
ru
,
ru
->
rf_config_file
);
// phy_init_RU(ru);
}
void
*
ru_thread_control
(
void
*
param
)
{
RU_t
*
ru
=
(
RU_t
*
)
param
;
RU_proc_t
*
proc
=
&
ru
->
proc
;
RRU_CONFIG_msg_t
rru_config_msg
;
ssize_t
msg_len
;
int
len
,
ret
;
// Start IF device if any
if
(
ru
->
start_if
)
{
LOG_I
(
PHY
,
"Starting IF interface for RU %d
\n
"
,
ru
->
idx
);
AssertFatal
(
ru
->
start_if
(
ru
,
NULL
)
==
0
,
"Could not start the IF device
\n
"
);
if
(
ru
->
if_south
!=
LOCAL_RF
)
wait_eNBs
();
}
ru
->
state
=
(
ru
->
function
==
eNodeB_3GPP
)
?
RU_RUN
:
RU_IDLE
;
LOG_I
(
PHY
,
"Control channel ON for RU %d
\n
"
,
ru
->
idx
);
while
(
!
oai_exit
)
// Change the cond
{
msg_len
=
sizeof
(
RRU_CONFIG_msg_t
);
// TODO : check what should be the msg len
if
(
ru
->
state
==
RU_IDLE
&&
ru
->
if_south
!=
LOCAL_RF
)
send_tick
(
ru
);
if
((
len
=
ru
->
ifdevice
.
trx_ctlrecv_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
msg_len
))
<
0
)
{
LOG_D
(
PHY
,
"Waiting msg for RU %d
\n
"
,
ru
->
idx
);
}
else
{
switch
(
rru_config_msg
.
type
)
{
case
RAU_tick
:
// RRU
if
(
ru
->
if_south
!=
LOCAL_RF
){
LOG_I
(
PHY
,
"Received Tick msg...Ignoring
\n
"
);
}
else
{
LOG_I
(
PHY
,
"Tick received from RAU
\n
"
);
if
(
send_capab
(
ru
)
==
0
)
ru
->
state
=
RU_CONFIG
;
}
break
;
case
RRU_capabilities
:
// RAU
if
(
ru
->
if_south
==
LOCAL_RF
)
LOG_E
(
PHY
,
"Received RRU_capab msg...Ignoring
\n
"
);
else
{
msg_len
=
sizeof
(
RRU_CONFIG_msg_t
)
-
MAX_RRU_CONFIG_SIZE
+
sizeof
(
RRU_capabilities_t
);
AssertFatal
(
rru_config_msg
.
len
==
msg_len
,
"Received capabilities with incorrect length (%d!=%d)
\n
"
,(
int
)
rru_config_msg
.
len
,(
int
)
msg_len
);
LOG_I
(
PHY
,
"Received capabilities from RRU %d (len %d/%d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)
\n
"
,
ru
->
idx
,
(
int
)
rru_config_msg
.
len
,(
int
)
msg_len
,
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
num_bands
,
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
max_pdschReferenceSignalPower
[
0
],
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
max_rxgain
[
0
],
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
nb_tx
[
0
],
((
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
nb_rx
[
0
]);
configure_ru
(
ru
->
idx
,(
RRU_capabilities_t
*
)
&
rru_config_msg
.
msg
[
0
]);
// send config
if
(
send_config
(
ru
,
rru_config_msg
)
==
0
)
ru
->
state
=
RU_CONFIG
;
}
break
;
case
RRU_config
:
// RRU
if
(
ru
->
if_south
==
LOCAL_RF
){
LOG_I
(
PHY
,
"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)
\n
"
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
num_bands
,
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
band_list
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
tx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
rx_freq
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_tx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
att_rx
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_DL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
N_RB_UL
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
threequarter_fs
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_FreqOffset
[
0
],
((
RRU_config_t
*
)
&
rru_config_msg
.
msg
[
0
])
->
prach_ConfigIndex
[
0
]);
configure_rru
(
ru
->
idx
,
(
void
*
)
&
rru_config_msg
.
msg
[
0
]);
fill_rf_config
(
ru
,
ru
->
rf_config_file
);
init_frame_parms
(
&
ru
->
frame_parms
,
1
);
ru
->
frame_parms
.
nb_antennas_rx
=
ru
->
nb_rx
;
phy_init_RU
(
ru
);
//if (ru->is_slave == 1) lte_sync_time_init(&ru->frame_parms);
if
(
ru
->
rfdevice
.
is_init
!=
1
){
ret
=
openair0_device_load
(
&
ru
->
rfdevice
,
&
ru
->
openair0_cfg
);
}
if
(
ru
->
rfdevice
.
trx_config_func
)
AssertFatal
((
ru
->
rfdevice
.
trx_config_func
(
&
ru
->
rfdevice
,
&
ru
->
openair0_cfg
)
==
0
),
"Failed to configure RF device for RU %d
\n
"
,
ru
->
idx
);
if
(
setup_RU_buffers
(
ru
)
!=
0
)
{
printf
(
"Exiting, cannot initialize RU Buffers
\n
"
);
exit
(
-
1
);
}
// send CONFIG_OK
rru_config_msg
.
type
=
RRU_config_ok
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
);
LOG_I
(
PHY
,
"Sending CONFIG_OK to RAU %d
\n
"
,
ru
->
idx
);
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"RU %d failed send CONFIG_OK to RAU
\n
"
,
ru
->
idx
);
reset_proc
(
ru
);
ru
->
state
=
RU_READY
;
}
else
LOG_E
(
PHY
,
"Received RRU_config msg...Ignoring
\n
"
);
break
;
case
RRU_config_ok
:
// RAU
if
(
ru
->
if_south
==
LOCAL_RF
)
LOG_E
(
PHY
,
"Received RRU_config_ok msg...Ignoring
\n
"
);
else
{
if
(
setup_RU_buffers
(
ru
)
!=
0
)
{
printf
(
"Exiting, cannot initialize RU Buffers
\n
"
);
exit
(
-
1
);
}
// Set state to RUN for Master RU, Others on SYNC
ru
->
state
=
(
ru
->
is_slave
==
1
)
?
RU_SYNC
:
RU_RUN
;
ru
->
in_synch
=
0
;
LOG_I
(
PHY
,
"Signaling main thread that RU %d (is_slave %d) is ready in state %s
\n
"
,
ru
->
idx
,
ru
->
is_slave
,
ru_states
[
ru
->
state
]);
pthread_mutex_lock
(
&
RC
.
ru_mutex
);
RC
.
ru_mask
&=
~
(
1
<<
ru
->
idx
);
pthread_cond_signal
(
&
RC
.
ru_cond
);
pthread_mutex_unlock
(
&
RC
.
ru_mutex
);
wait_sync
(
"ru_thread_control"
);
// send start
rru_config_msg
.
type
=
RRU_start
;
rru_config_msg
.
len
=
sizeof
(
RRU_CONFIG_msg_t
);
// TODO: set to correct msg len
LOG_I
(
PHY
,
"Sending Start to RRU %d
\n
"
,
ru
->
idx
);
AssertFatal
((
ru
->
ifdevice
.
trx_ctlsend_func
(
&
ru
->
ifdevice
,
&
rru_config_msg
,
rru_config_msg
.
len
)
!=-
1
),
"Failed to send msg to RU %d
\n
"
,
ru
->
idx
);
pthread_mutex_lock
(
&
proc
->
mutex_ru
);
proc
->
instance_cnt_ru
=
1
;
pthread_mutex_unlock
(
&
proc
->
mutex_ru
);
if
(
pthread_cond_signal
(
&
proc
->
cond_ru_thread
)
!=
0
)
{
LOG_E
(
PHY
,
"ERROR pthread_cond_signal for RU %d
\n
"
,
ru
->
idx
);
exit_fun
(
"ERROR pthread_cond_signal"
);
break
;
}
}
break
;
case
RRU_start
:
// RRU
if
(
ru
->
if_south
==
LOCAL_RF
){
LOG_I
(
PHY
,
"Start received from RAU
\n
"
);
if
(
ru
->
state
==
RU_READY
){
LOG_I
(
PHY
,
"Signaling main thread that RU %d is ready
\n
"
,
ru
->
idx
);
pthread_mutex_lock
(
&
RC
.
ru_mutex
);
RC
.
ru_mask
&=
~
(
1
<<
ru
->
idx
);
pthread_cond_signal
(
&
RC
.
ru_cond
);
pthread_mutex_unlock
(
&
RC
.
ru_mutex
);
wait_sync
(
"ru_thread_control"
);
ru
->
state
=
(
ru
->
is_slave
==
1
)
?
RU_SYNC
:
RU_RUN
;
ru
->
cmd
=
EMPTY
;
pthread_mutex_lock
(
&
proc
->
mutex_ru
);
proc
->
instance_cnt_ru
=
1
;
pthread_mutex_unlock
(
&
proc
->
mutex_ru
);
if
(
pthread_cond_signal
(
&
proc
->
cond_ru_thread
)
!=
0
)
{
LOG_E
(
PHY
,
"ERROR pthread_cond_signal for RU %d
\n
"
,
ru
->
idx
);
exit_fun
(
"ERROR pthread_cond_signal"
);
break
;
}
}
else
LOG_E
(
PHY
,
"RRU not ready, cannot start
\n
"
);
}
else
LOG_E
(
PHY
,
"Received RRU_start msg...Ignoring
\n
"
);
break
;
case
RRU_sync_ok
:
//RAU
if
(
ru
->
if_south
==
LOCAL_RF
)
LOG_E
(
PHY
,
"Received RRU_config_ok msg...Ignoring
\n
"
);
else
{
if
(
ru
->
is_slave
==
1
){
LOG_I
(
PHY
,
"Received RRU_sync_ok from RRU %d
\n
"
,
ru
->
idx
);
// Just change the state of the RRU to unblock ru_thread()
ru
->
state
=
RU_RUN
;
}
else
LOG_E
(
PHY
,
"Received RRU_sync_ok from a master RRU...Ignoring
\n
"
);
}
break
;
case
RRU_frame_resynch
:
//RRU
if
(
ru
->
if_south
!=
LOCAL_RF
)
LOG_E
(
PHY
,
"Received RRU frame resynch message, should not happen in RAU
\n
"
);
else
{
LOG_I
(
PHY
,
"Received RRU_frame_resynch command
\n
"
);
ru
->
cmd
=
RU_FRAME_RESYNCH
;
ru
->
cmdval
=
((
uint16_t
*
)
&
rru_config_msg
.
msg
[
0
])[
0
];
LOG_I
(
PHY
,
"Received Frame Resynch messaage with value %d
\n
"
,
ru
->
cmdval
);
}
break
;
case
RRU_stop
:
// RRU
if
(
ru
->
if_south
==
LOCAL_RF
){
LOG_I
(
PHY
,
"Stop received from RAU
\n
"
);
if
(
ru
->
state
==
RU_RUN
||
ru
->
state
==
RU_ERROR
){
LOG_I
(
PHY
,
"Stopping RRU
\n
"
);
ru
->
state
=
RU_READY
;
// TODO: stop ru_thread
}
else
{
LOG_I
(
PHY
,
"RRU not running, can't stop
\n
"
);
}
}
else
LOG_E
(
PHY
,
"Received RRU_stop msg...Ignoring
\n
"
);
break
;
default:
if
(
ru
->
if_south
!=
LOCAL_RF
){
if
(
ru
->
state
==
RU_IDLE
){
// Keep sending TICK
send_tick
(
ru
);
}
}
break
;
}
// switch
}
//else
}
//while
return
(
NULL
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment