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
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
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
wangjie
OpenXG-RAN
Commits
88d57390
Commit
88d57390
authored
Aug 05, 2019
by
laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
continue timestamp
parent
ebb52e38
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
326 additions
and
48 deletions
+326
-48
SystemX-tutorial-design.md
SystemX-tutorial-design.md
+264
-0
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+2
-2
executables/main-fs6.c
executables/main-fs6.c
+23
-18
executables/main-ocp.c
executables/main-ocp.c
+1
-13
executables/split_headers.h
executables/split_headers.h
+7
-4
executables/transport_split.c
executables/transport_split.c
+27
-9
openair1/SCHED/phy_procedures_lte_eNb.c
openair1/SCHED/phy_procedures_lte_eNb.c
+2
-2
No files found.
SystemX-tutorial-design.md
0 → 100644
View file @
88d57390
# OpenAirInterface for SystemX
#Terminology
****
This document use the 5G terminology
****
**Central Unit (CU): **
It is a logical node that includes the gNB
functions like Transfer of user data, Mobility control, Radio access
network sharing, Positioning, Session Management etc., except those
functions allocated exclusively to the DU. CU controls the operation of
DUs over front-haul (Fs) interface. A central unit (CU) may also be
known as BBU/REC/RCC/C-RAN/V-RAN/VNF
**Distributed Unit (DU):**
This logical node includes a subset of the
gNB functions, depending on the functional split option. Its operation
is controlled by the CU. Distributed Unit (DU) also known with other
names like RRH/RRU/RE/RU/PNF.
In OpenAir code, the terminology is often RU and BBU.
#Usage
##EPC and general environment
### OAI EPC
Use the stable OAI EPC, that can run in one machine (VM or standalone)
Draft description:
<https://open-cells.com/index.php/2017/08/22/all-in-one-openairinterface-august-22nd/>
##Standalone 4G
EPC+eNB on one machine, the UE can be commercial or OAI UE.
### USRP B210
Main current issue: traffic is good only on coaxial link between UE and
eNB (probably power management issue).
### Simulated RF
Running eNB+UE both OAI can be done over a virtual RF link.
The UE current status is that threads synchronization is implicit in
some cases. As the RF simulator is very quick, a “sleep()” is required
in the UE main loop
(line 1744, targets/RT/USER/lte-ue.c).
Running also the UE in the same machine is possible with simulated RF.
Running in same machine is simpler, offers about infinite speed for
virtual RF samples transmission.
A specific configuration is required because the EPC Sgi interface has
the same IP tunnel end point as the UE.
So, we have to create a network namespace for the UE and to route data
in/out of the namespace.
```
bash
ip netns delete aNameSpace 2>
;
/dev/null
ip
link
delete v-eth1 2>
;
/dev/null
ip netns add aNameSpace
ip
link
add v-eth1
type
veth peer name v-peer1
ip
link set
v-peer1 netns aNameSpace
ip addr add 10.200.1.1/24 dev v-eth1
ip
link set
v-eth1 up
iptables
-t
nat
-A
POSTROUTING
-s
10.200.1.0/255.255.255.0
-o
enp0s31f6
-j
MASQUERADE
iptables
-A
FORWARD
-i
enp0s31f6
-o
v-eth1
-j
ACCEPT
iptables
-A
FORWARD
-o
enp0s31f6
-i
v-eth1
-j
ACCEPT
ip netns
exec
aNameSpace ip
link set
dev lo up
ip netns
exec
aNameSpace ip addr add 10.200.1.2/24 dev v-peer1
ip netns
exec
aNameSpace ip
link set
v-peer1 up
ip netns
exec
aNameSpace bash
```
After the last command, the Linux shell is in the new namespace, ready
to run the UE.
To make user plan traffic, the traffic generator has to run in the same
namespace
`ip netns exec aNameSpace bash
`
The traffic genenrator has to specify the interface:
`route add default oaitun_ue1
`
or specify the outgoing route in the traffic generator (like option “-I”
in ping command).
## Split 6 DL 4G
The contract describes to reuse the uplink existing if4p5 and to develop
is this work the downlink “functional split 6”.
The customer required after signature to develop also the uplink
functional split 6. This is accepted, as long as the whole work is
research with no delivery completeness warranty.
### Simulation
To be able to verify the new features and to help in all future
developments, Open Cells added and improved the Rf board simulator
during this contract.
We added the channel modeling simulation, that offer to simulate various
3GPP defined channels.
### Main loop
The main log is in RF simulator is in
targets/RT/USER/lte-ru.c and targets/RT/USER/lte-enb.c
As this piece of SW is very complex and doesn’t meet our goals
(functional split 6), a cleaned version replaces these 2 files in
executables/ocp-main.c (openair1/SCHED/prach
\_
procedures.c is also
replaced by this new file as it only launching the RACH actual work in a
way not compatible with our FS6).
The main loop cadences the I/Q samples reception, signal processing and
I/Q samples sending.
The main loop uses extensively function pointers to call the right
processing function depending on the split case.
This is enough for RF board dialog, but the FS6 is higher in SW layers,
we need to cut higher functions inside downlink and uplink procedures.
### DownLink
The main procedure is phy
\_
procedures
\_
eNB
\_
TX
This is building the common channels (beacon, multi-UE signaling).
The FS6 split breaks this function into pieces:
-
The multi-UE signals, built by common
\_
signal
\_
procedures(),
subframe2harq
\_
pid(), generate
\_
dci
\_
top(), subframe2harq
\_
pid()
- These functions will be executed in the DU, nevertheless all
context has to be sent (it is also needed partially for
UL spitting)
- IT should be in the DU also to meet the requirement of pushing
in DU the data encoded with large redundancy (>3 redundancy)
-
the per UE data: pdsch
\_
procedures() that needs further splitting:
- dlsch\_encoding\_all() that makes the encoding: turbo code
and lte\_rate\_matching\_turbo() that will be in the DU (some
unlikely cases can reach redundancy up to x3, when MCS is very
low (negative SINR cases)).
- dlsch\_encoding() output needs to be transmitted between the
DU and the CU for functional split 6.
- dlsch\_scrambling() that will go in the DU
- dlsch\_modulation() that will go in the DU
### Uplink
The uplink require configuration that is part of the DL transmission.
It interprets the signalling to extract the RACH and the per UE data
channels.
Ocp-main.c:rxtx() calls directly the entry procedure
phy
\_
procedures
\_
eNB
\_
uespec
\_
RX() calls:
-
rx
\_
ulsch() that demodulate and extract soft bits per UE.
- This function runs in the DU
- the output data will be processes in the DU, so it needs to be
transmitted to the DU
-
ulsch
\_
decoding() that do lte
\_
rate
\_
matching
\_
turbo
\_
rx()
sub
\_
block
\_
deinterleaving
\_
turbo() then turbo decode
- it runs
-
fill
\_
ulsch
\_
cqi
\_
indication()
- TBD: either runs in DU or output needs to be transmitted to DU
-
fill
\_
crc
\_
indication() , fill
\_
rx
\_
indication() results need also
to be transmitted or made in the DU
### UDP transport layer
A general UDP transport layer is in executables/transport
\_
split.c
Linux offers a UDP socket builtin timeout, that we use.
In and out buffers are memory zones that contains compacted
(concatenated) UDP chunks.
For output, sendSubFrame() sends each UDP chunk
For input, receiveSubFrame() collects all UDP chunks for a group (a
subframe in OAI LTE case). It returns in the following cases:
-
all chunks are received
-
a timeout expired
-
a chunk from the next subframe already arrived
### Functional split 6 usage
The ocp cleaned main hale to be used: run ocp-softmodem instead of
lte-softmodem.
The functionality and parameters is the same, enhanced with FS6 mode.
The environment variable “fs6” enables the fs6 mode and decided to be cu
or du from the fs6 variable content.
Example:
`fs6=cu ./ocp-softmodem -O … (regular lte-softmodem paramters)
`
Run the CU init of the split 6 eNB.
CU and DU IP address and port are configurable in the eNB configuration
file (as X2, GTP, … interfaces).
##5G and F1
Today 5G achievement is limited to physical layer.
The available modulation is 40MHz, that require one X310 or N300 for the
gNB and a X310 or N300 for the nrUE.
### Usage with X310
Linux configuration:
<https://files.ettus.com/manual/page_usrp_x3x0_config.html>
We included most of this configuration included in OAI source code.
Remain to set the NIC (network interface card) MTU to 9000 (jumbo
frames).
### Running 5G
Usage with RFsimulator:
gNB
`sudo RFSIMULATOR=server ./nr-softmodem -O
../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
--parallel-config PARALLEL\_SINGLE\_THREAD`
nrUE
`sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C
3510000000 -d`
cmake_targets/CMakeLists.txt
View file @
88d57390
...
@@ -183,8 +183,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU
...
@@ -183,8 +183,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU
#########################
#########################
# set a flag for changes in the source code
# set a flag for changes in the source code
# these changes are related to hardcoded path to include .h files
# these changes are related to hardcoded path to include .h files
set
(
CMAKE_C_FLAGS_DEBUG
"
${
CMAKE_C_FLAGS
}
-g -DMALLOC_CHECK_=3"
)
set
(
CMAKE_C_FLAGS_DEBUG
"
${
CMAKE_C_FLAGS
}
-g
3
-DMALLOC_CHECK_=3"
)
set
(
CMAKE_C_FLAGS_RELWITHDEBINFO
"
${
CMAKE_C_FLAGS
}
-g
-DMALLOC_CHECK_=3 -O2
"
)
set
(
CMAKE_C_FLAGS_RELWITHDEBINFO
"
${
CMAKE_C_FLAGS
}
-g
3 -DMALLOC_CHECK_=3 -O0
"
)
set
(
GIT_BRANCH
"UNKNOWN"
)
set
(
GIT_BRANCH
"UNKNOWN"
)
...
...
executables/main-fs6.c
View file @
88d57390
...
@@ -653,6 +653,8 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx
...
@@ -653,6 +653,8 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx
hDL
(
bufferZone
)
->
amp
=
AMP
;
hDL
(
bufferZone
)
->
amp
=
AMP
;
}
}
if
(
num_mdci
)
abort
();
if
(
do_meas
==
1
)
stop_meas
(
&
eNB
->
dlsch_common_and_dci
);
if
(
do_meas
==
1
)
stop_meas
(
&
eNB
->
dlsch_common_and_dci
);
if
(
do_meas
==
1
)
start_meas
(
&
eNB
->
dlsch_ue_specific
);
if
(
do_meas
==
1
)
start_meas
(
&
eNB
->
dlsch_ue_specific
);
...
@@ -741,21 +743,21 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx
...
@@ -741,21 +743,21 @@ void phy_procedures_eNB_TX_extract(uint8_t *bufferZone, PHY_VARS_eNB *eNB, L1_rx
return
;
return
;
}
}
void
DL_du_fs6
(
RU_t
*
ru
,
int
frame
,
int
subframe
,
uint64_t
TS
)
{
void
DL_du_fs6
(
RU_t
*
ru
)
{
RU_proc_t
*
ru_proc
=&
ru
->
proc
;
RU_proc_t
*
ru_proc
=&
ru
->
proc
;
for
(
int
i
=
0
;
i
<
ru
->
num_eNB
;
i
++
)
{
for
(
int
i
=
0
;
i
<
ru
->
num_eNB
;
i
++
)
{
initBufferZone
(
bufferZone
);
initBufferZone
(
bufferZone
);
int
nb_blocks
=
receiveSubFrame
(
&
sockFS6
,
TS
,
bufferZone
,
sizeof
(
bufferZone
)
);
int
nb_blocks
=
receiveSubFrame
(
&
sockFS6
,
ru_proc
->
timestamp_tx
,
bufferZone
,
sizeof
(
bufferZone
),
CTsentCUv0
);
L1_rxtx_proc_t
*
L1_proc
=
&
ru
->
eNB_list
[
i
]
->
proc
.
L1_proc_tx
;
L1_proc
->
timestamp_tx
=
hUDP
(
bufferZone
)
->
timestamp
;
L1_proc
->
frame_tx
=
hDL
(
bufferZone
)
->
frame
;
L1_proc
->
subframe_tx
=
hDL
(
bufferZone
)
->
subframe
;
if
(
nb_blocks
>
0
)
if
(
nb_blocks
>
0
)
{
L1_rxtx_proc_t
*
L1_proc
=
&
ru
->
eNB_list
[
i
]
->
proc
.
L1_proc_tx
;
L1_proc
->
timestamp_tx
=
hUDP
(
bufferZone
)
->
timestamp
;
L1_proc
->
frame_tx
=
hDL
(
bufferZone
)
->
frame
;
L1_proc
->
subframe_tx
=
hDL
(
bufferZone
)
->
subframe
;
phy_procedures_eNB_TX_process
(
bufferZone
,
nb_blocks
,
ru
->
eNB_list
[
i
],
&
ru
->
eNB_list
[
i
]
->
proc
.
L1_proc
,
1
);
phy_procedures_eNB_TX_process
(
bufferZone
,
nb_blocks
,
ru
->
eNB_list
[
i
],
&
ru
->
eNB_list
[
i
]
->
proc
.
L1_proc
,
1
);
else
}
else
LOG_E
(
PHY
,
"DL not received for subframe
: %d
\n
"
,
subframe
);
LOG_E
(
PHY
,
"DL not received for subframe
\n
"
);
}
}
/* OAI data model is wrong: hardcode link ru to enb index 0*/
/* OAI data model is wrong: hardcode link ru to enb index 0*/
...
@@ -799,8 +801,14 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) {
...
@@ -799,8 +801,14 @@ void UL_du_fs6(RU_t *ru, int frame, int subframe) {
phy_procedures_eNB_uespec_RX_extract
(
bufferZone
,
FS6_BUF_SIZE
,
eNB
,
&
proc
->
L1_proc
);
phy_procedures_eNB_uespec_RX_extract
(
bufferZone
,
FS6_BUF_SIZE
,
eNB
,
&
proc
->
L1_proc
);
}
}
if
(
hUDP
(
bufferZone
)
->
nbBlocks
==
0
)
{
hUDP
(
bufferZone
)
->
nbBlocks
=
1
;
// We have to send the signaling, even is there is no user plan data (no UE)
hUDP
(
bufferZone
)
->
blockID
=
0
;
hUDP
(
bufferZone
)
->
contentBytes
=
sizeof
(
fs6_ul_t
);
}
for
(
int
i
=
0
;
i
<
ru
->
num_eNB
;
i
++
)
{
for
(
int
i
=
0
;
i
<
ru
->
num_eNB
;
i
++
)
{
sendSubFrame
(
&
sockFS6
,
bufferZone
,
sizeof
(
fs6_ul_t
)
);
sendSubFrame
(
&
sockFS6
,
bufferZone
,
sizeof
(
fs6_ul_t
),
CTsentDUv0
);
}
}
}
}
...
@@ -827,12 +835,12 @@ void DL_cu_fs6(RU_t *ru,int frame, int subframe) {
...
@@ -827,12 +835,12 @@ void DL_cu_fs6(RU_t *ru,int frame, int subframe) {
hUDP
(
bufferZone
)
->
contentBytes
=
sizeof
(
fs6_dl_t
);
hUDP
(
bufferZone
)
->
contentBytes
=
sizeof
(
fs6_dl_t
);
}
}
sendSubFrame
(
&
sockFS6
,
bufferZone
,
sizeof
(
fs6_dl_t
)
);
sendSubFrame
(
&
sockFS6
,
bufferZone
,
sizeof
(
fs6_dl_t
)
,
CTsentCUv0
);
}
}
void
UL_cu_fs6
(
RU_t
*
ru
,
int
frame
,
int
subframe
,
uint64_t
TS
)
{
void
UL_cu_fs6
(
RU_t
*
ru
,
int
frame
,
int
subframe
,
uint64_t
TS
)
{
initBufferZone
(
bufferZone
);
initBufferZone
(
bufferZone
);
int
nb_blocks
=
receiveSubFrame
(
&
sockFS6
,
TS
,
bufferZone
,
sizeof
(
bufferZone
)
);
int
nb_blocks
=
receiveSubFrame
(
&
sockFS6
,
TS
,
bufferZone
,
sizeof
(
bufferZone
)
,
CTsentDUv0
);
if
(
nb_blocks
==
0
)
{
if
(
nb_blocks
==
0
)
{
LOG_W
(
PHY
,
"CU lost a subframe
\n
"
);
LOG_W
(
PHY
,
"CU lost a subframe
\n
"
);
...
@@ -878,7 +886,6 @@ void *cu_fs6(void *arg) {
...
@@ -878,7 +886,6 @@ void *cu_fs6(void *arg) {
void
*
du_fs6
(
void
*
arg
)
{
void
*
du_fs6
(
void
*
arg
)
{
RU_t
*
ru
=
(
RU_t
*
)
arg
;
RU_t
*
ru
=
(
RU_t
*
)
arg
;
//RU_proc_t *proc = &ru->proc;
//RU_proc_t *proc = &ru->proc;
int64_t
AbsoluteSubframe
=-
1
;
fill_rf_config
(
ru
,
ru
->
rf_config_file
);
fill_rf_config
(
ru
,
ru
->
rf_config_file
);
init_frame_parms
(
&
ru
->
frame_parms
,
1
);
init_frame_parms
(
&
ru
->
frame_parms
,
1
);
phy_init_RU
(
ru
);
phy_init_RU
(
ru
);
...
@@ -887,11 +894,9 @@ void *du_fs6(void *arg) {
...
@@ -887,11 +894,9 @@ void *du_fs6(void *arg) {
AssertFatal
(
createUDPsock
(
NULL
,
"7777"
,
"127.0.0.1"
,
"8888"
,
&
sockFS6
),
""
);
AssertFatal
(
createUDPsock
(
NULL
,
"7777"
,
"127.0.0.1"
,
"8888"
,
&
sockFS6
),
""
);
while
(
1
)
{
while
(
1
)
{
AbsoluteSubframe
++
;
L1_rxtx_proc_t
*
proc
=
&
ru
->
eNB_list
[
0
]
->
proc
;
int
subframe
=
AbsoluteSubframe
%
10
;
UL_du_fs6
(
ru
,
proc
->
frame_rx
,
proc
->
subframe_rx
);
int
frame
=
(
AbsoluteSubframe
/
10
)
%
1024
;
DL_du_fs6
(
ru
);
UL_du_fs6
(
ru
,
frame
,
subframe
);
DL_du_fs6
(
ru
,
frame
,
subframe
,
AbsoluteSubframe
);
}
}
return
NULL
;
return
NULL
;
...
...
executables/main-ocp.c
View file @
88d57390
...
@@ -582,13 +582,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
...
@@ -582,13 +582,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
return
(
0
);
return
(
0
);
}
}
void
eNB_top
(
PHY_VARS_eNB
*
eNB
,
int
frame_rx
,
int
subframe_rx
,
char
*
string
,
RU_t
*
ru
)
{
void
eNB_top
(
PHY_VARS_eNB
*
eNB
,
int
dummy1
,
int
dummy2
,
char
*
string
,
RU_t
*
ru
)
{
L1_proc_t
*
proc
=
&
eNB
->
proc
;
L1_proc_t
*
proc
=
&
eNB
->
proc
;
L1_rxtx_proc_t
*
L1_proc
=
&
proc
->
L1_proc
;
L1_rxtx_proc_t
*
L1_proc
=
&
proc
->
L1_proc
;
LTE_DL_FRAME_PARMS
*
fp
=
&
ru
->
frame_parms
;
LTE_DL_FRAME_PARMS
*
fp
=
&
ru
->
frame_parms
;
RU_proc_t
*
ru_proc
=&
ru
->
proc
;
RU_proc_t
*
ru_proc
=&
ru
->
proc
;
proc
->
frame_rx
=
frame_rx
;
proc
->
subframe_rx
=
subframe_rx
;
if
(
!
oai_exit
)
{
if
(
!
oai_exit
)
{
L1_proc
->
timestamp_tx
=
ru_proc
->
timestamp_rx
+
(
sf_ahead
*
fp
->
samples_per_tti
);
L1_proc
->
timestamp_tx
=
ru_proc
->
timestamp_rx
+
(
sf_ahead
*
fp
->
samples_per_tti
);
...
@@ -650,16 +648,6 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
...
@@ -650,16 +648,6 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
proc
->
subframe_tx
=
(
proc
->
subframe_rx
+
sf_ahead
)
%
10
;
proc
->
subframe_tx
=
(
proc
->
subframe_rx
+
sf_ahead
)
%
10
;
proc
->
frame_tx
=
(
proc
->
subframe_rx
>
(
9
-
sf_ahead
))
?
(
proc
->
frame_rx
+
1
)
&
1023
:
proc
->
frame_rx
;
proc
->
frame_tx
=
(
proc
->
subframe_rx
>
(
9
-
sf_ahead
))
?
(
proc
->
frame_rx
+
1
)
&
1023
:
proc
->
frame_rx
;
if
(
proc
->
first_rx
==
0
)
{
AssertFatal
(
proc
->
subframe_rx
==
*
subframe
&&
proc
->
frame_rx
==
*
frame
,
"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d) (proc->frame_rx %d frame %d)
\n
"
,
(
long
long
unsigned
int
)
proc
->
timestamp_rx
,
proc
->
subframe_rx
,
*
subframe
,
proc
->
frame_rx
,
*
frame
);
}
else
{
proc
->
first_rx
=
0
;
*
frame
=
proc
->
frame_rx
;
*
subframe
=
proc
->
subframe_rx
;
}
if
(
rxs
!=
fp
->
samples_per_tti
)
{
if
(
rxs
!=
fp
->
samples_per_tti
)
{
#if defined(USRP_REC_PLAY)
#if defined(USRP_REC_PLAY)
exit_fun
(
"Exiting IQ record/playback"
);
exit_fun
(
"Exiting IQ record/playback"
);
...
...
executables/split_headers.h
View file @
88d57390
...
@@ -18,6 +18,9 @@ typedef struct {
...
@@ -18,6 +18,9 @@ typedef struct {
int
sockHandler
;
int
sockHandler
;
}
UDPsock_t
;
}
UDPsock_t
;
#define CTsentCUv0 0xA500
#define CTsentDUv0 0x5A00
typedef
struct
commonUDP_s
{
typedef
struct
commonUDP_s
{
uint64_t
timestamp
;
// id of the group (subframe for LTE)
uint64_t
timestamp
;
// id of the group (subframe for LTE)
uint16_t
nbBlocks
;
// total number of blocks for this timestamp
uint16_t
nbBlocks
;
// total number of blocks for this timestamp
...
@@ -67,8 +70,8 @@ typedef struct {
...
@@ -67,8 +70,8 @@ typedef struct {
}
fs6_dl_uespec_t
;
}
fs6_dl_uespec_t
;
bool
createUDPsock
(
char
*
sourceIP
,
char
*
sourcePort
,
char
*
destIP
,
char
*
destPort
,
UDPsock_t
*
result
);
bool
createUDPsock
(
char
*
sourceIP
,
char
*
sourcePort
,
char
*
destIP
,
char
*
destPort
,
UDPsock_t
*
result
);
int
receiveSubFrame
(
UDPsock_t
*
sock
,
uint64_t
expectedTS
,
void
*
bufferZone
,
int
bufferSize
);
int
receiveSubFrame
(
UDPsock_t
*
sock
,
uint64_t
expectedTS
,
void
*
bufferZone
,
int
bufferSize
,
uint16_t
contentType
);
int
sendSubFrame
(
UDPsock_t
*
sock
,
void
*
bufferZone
,
ssize_t
secondHeaderSize
);
int
sendSubFrame
(
UDPsock_t
*
sock
,
void
*
bufferZone
,
ssize_t
secondHeaderSize
,
uint16_t
contentType
);
#define initBufferZone(xBuf) \
#define initBufferZone(xBuf) \
uint8_t xBuf[FS6_BUF_SIZE];\
uint8_t xBuf[FS6_BUF_SIZE];\
...
@@ -77,12 +80,12 @@ int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize);
...
@@ -77,12 +80,12 @@ int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize);
#define hUDP(xBuf) ((commonUDP_t *)xBuf)
#define hUDP(xBuf) ((commonUDP_t *)xBuf)
#define hDL(xBuf) (((fs6_dl_t*)((commonUDP_t *)xBuf)+1))
#define hDL(xBuf) (((fs6_dl_t*)((commonUDP_t *)xBuf)+1))
inline
size_t
alignedSize
(
uint8_t
*
ptr
)
{
static
inline
size_t
alignedSize
(
uint8_t
*
ptr
)
{
commonUDP_t
*
header
=
(
commonUDP_t
*
)
ptr
;
commonUDP_t
*
header
=
(
commonUDP_t
*
)
ptr
;
return
((
header
->
contentBytes
+
sizeof
(
commonUDP_t
)
+
blockAlign
-
1
)
/
blockAlign
)
*
blockAlign
;
return
((
header
->
contentBytes
+
sizeof
(
commonUDP_t
)
+
blockAlign
-
1
)
/
blockAlign
)
*
blockAlign
;
}
}
inline
void
*
commonUDPdata
(
uint8_t
*
ptr
)
{
static
inline
void
*
commonUDPdata
(
uint8_t
*
ptr
)
{
return
(
void
*
)
(((
commonUDP_t
*
)
ptr
)
+
1
);
return
(
void
*
)
(((
commonUDP_t
*
)
ptr
)
+
1
);
}
}
...
...
executables/transport_split.c
View file @
88d57390
...
@@ -56,7 +56,8 @@ bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPo
...
@@ -56,7 +56,8 @@ bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPo
int
enable
=
1
;
int
enable
=
1
;
AssertFatal
(
setsockopt
(
result
->
sockHandler
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
enable
,
sizeof
(
enable
))
==
0
,
""
);
AssertFatal
(
setsockopt
(
result
->
sockHandler
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
enable
,
sizeof
(
enable
))
==
0
,
""
);
struct
timeval
tv
=
{
0
,
UDP_TIMEOUT
};
//struct timeval tv= {0,UDP_TIMEOUT};
struct
timeval
tv
=
{
2
,
UDP_TIMEOUT
};
//debug: wait 2 seconds for human understanding
AssertFatal
(
setsockopt
(
result
->
sockHandler
,
SOL_SOCKET
,
SO_RCVTIMEO
,
&
tv
,
sizeof
(
tv
))
==
0
,
""
);
AssertFatal
(
setsockopt
(
result
->
sockHandler
,
SOL_SOCKET
,
SO_RCVTIMEO
,
&
tv
,
sizeof
(
tv
))
==
0
,
""
);
// Make a send/recv buffer larger than a a couple of subframe
// Make a send/recv buffer larger than a a couple of subframe
// so the kernel will store for us in and out paquets
// so the kernel will store for us in and out paquets
...
@@ -69,9 +70,9 @@ bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPo
...
@@ -69,9 +70,9 @@ bool createUDPsock (char *sourceIP, char *sourcePort, char *destIP, char *destPo
// sock: udp socket
// sock: udp socket
// expectedTS: the expected timestamp, 0 if unknown
// expectedTS: the expected timestamp, 0 if unknown
// bufferZone: a reception area of bufferSize
// bufferZone: a reception area of bufferSize
int
receiveSubFrame
(
UDPsock_t
*
sock
,
uint64_t
expectedTS
,
void
*
bufferZone
,
int
bufferSize
)
{
int
receiveSubFrame
(
UDPsock_t
*
sock
,
uint64_t
expectedTS
,
void
*
bufferZone
,
int
bufferSize
,
uint16_t
contentType
)
{
int
rcved
=
0
;
int
rcved
=
0
;
commonUDP_t
*
tmp
=
NULL
;
commonUDP_t
*
bufOrigin
=
(
commonUDP_t
*
)
bufferZone
;
do
{
do
{
//read all subframe data from the control unit
//read all subframe data from the control unit
...
@@ -85,22 +86,37 @@ int receiveSubFrame(UDPsock_t *sock, uint64_t expectedTS, void *bufferZone, int
...
@@ -85,22 +86,37 @@ int receiveSubFrame(UDPsock_t *sock, uint64_t expectedTS, void *bufferZone, int
return
-
1
;
return
-
1
;
}
}
}
else
{
}
else
{
tmp
=
(
commonUDP_t
*
)
bufferZone
;
if
(
hUDP
(
bufferZone
)
->
contentType
!=
contentType
)
abort
();
if
(
expectedTS
&&
tmp
->
timestamp
!=
expectedTS
)
{
LOG_W
(
HW
,
"Received a paquet in mixed subframes, dropping it
\n
"
);
if
(
hUDP
(
bufferZone
)
->
timestamp
!=
expectedTS
)
{
if
(
hUDP
(
bufferZone
)
->
timestamp
<
expectedTS
)
{
LOG_W
(
HW
,
"Received a paquet from past subframes, dropping it
\n
"
);
}
else
{
LOG_W
(
HW
,
"Received a paquet in future subframes
\n
"
);
if
(
rcved
==
0
)
{
LOG_W
(
HW
,
"First paquet in the sub-frame, keeping it
\n
"
);
rcved
++
;
bufferZone
+=
ret
;
expectedTS
=
hUDP
(
bufferZone
)
->
timestamp
;
}
}
}
else
{
}
else
{
rcved
++
;
rcved
++
;
bufferZone
+=
ret
;
bufferZone
+=
ret
;
}
}
}
}
}
while
(
!
rcved
||
rcved
<
tmp
->
nbBlocks
);
}
while
(
!
rcved
||
rcved
<
hUDP
(
bufferZone
)
->
nbBlocks
);
LOG_D
(
HW
,
"Received: nb_blocks: %d, TS: %lu, frame: %d, subframe: %d
\n
"
,
rcved
,
bufOrigin
->
timestamp
,
*
(((
int
*
)
bufOrigin
)
+
1
),
*
(((
int
*
)
bufOrigin
)
+
2
));
return
rcved
;
return
rcved
;
}
}
int
sendSubFrame
(
UDPsock_t
*
sock
,
void
*
bufferZone
,
ssize_t
secondHeaderSize
)
{
int
sendSubFrame
(
UDPsock_t
*
sock
,
void
*
bufferZone
,
ssize_t
secondHeaderSize
,
uint16_t
contentType
)
{
commonUDP_t
*
UDPheader
=
(
commonUDP_t
*
)
bufferZone
;
commonUDP_t
*
UDPheader
=
(
commonUDP_t
*
)
bufferZone
;
UDPheader
->
contentType
=
contentType
;
int
nbBlocks
=
UDPheader
->
nbBlocks
;
int
nbBlocks
=
UDPheader
->
nbBlocks
;
int
blockId
=
0
;
int
blockId
=
0
;
...
@@ -131,5 +147,7 @@ int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize) {
...
@@ -131,5 +147,7 @@ int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize) {
nbBlocks
--
;
nbBlocks
--
;
}
while
(
nbBlocks
);
}
while
(
nbBlocks
);
LOG_D
(
HW
,
"Sent: TS: %lu, frame: %d, subframe: %d
\n
"
,
UDPheader
->
timestamp
,
*
(((
int
*
)
UDPheader
)
+
1
),
*
(((
int
*
)
UDPheader
)
+
2
));
return
0
;
return
0
;
}
}
openair1/SCHED/phy_procedures_lte_eNb.c
View file @
88d57390
...
@@ -409,10 +409,10 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
...
@@ -409,10 +409,10 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
ul_frame
=
pdcch_alloc2ul_frame
(
fp
,
frame
,
subframe
);
ul_frame
=
pdcch_alloc2ul_frame
(
fp
,
frame
,
subframe
);
// clear previous allocation information for all UEs
// clear previous allocation information for all UEs
for
(
i
=
0
;
i
<
NUMBER_OF_UE_MAX
;
i
++
)
{
//
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
//if (eNB->dlsch[i][0])
//if (eNB->dlsch[i][0])
//eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
//eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
}
//
}
/* TODO: check the following test - in the meantime it is put back as it was before */
/* TODO: check the following test - in the meantime it is put back as it was before */
//if ((ul_subframe < 10)&&
//if ((ul_subframe < 10)&&
...
...
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