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
alex037yang
OpenXG-RAN
Commits
cd35f606
Commit
cd35f606
authored
6 years ago
by
matzakos
Browse files
Options
Browse Files
Download
Plain Diff
L2-emulator running finein -noS1 mode after the merge with LTE-D2D master branch
parents
729a92e3
dad40182
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1638 additions
and
70 deletions
+1638
-70
d2d_emulator_setup.txt
d2d_emulator_setup.txt
+90
-16
openair2/LAYER2/MAC/config.c
openair2/LAYER2/MAC/config.c
+301
-1
openair2/LAYER2/MAC/config_ue.c
openair2/LAYER2/MAC/config_ue.c
+1141
-4
openair2/LAYER2/MAC/defs.h
openair2/LAYER2/MAC/defs.h
+19
-1
openair2/LAYER2/MAC/proto.h
openair2/LAYER2/MAC/proto.h
+1
-0
openair2/LAYER2/MAC/ue_procedures.c
openair2/LAYER2/MAC/ue_procedures.c
+27
-6
openair2/RRC/LITE/MESSAGES/asn1_msg.c
openair2/RRC/LITE/MESSAGES/asn1_msg.c
+2
-2
openair2/RRC/LITE/defs.h
openair2/RRC/LITE/defs.h
+5
-3
openair2/RRC/LITE/rrc_UE.c
openair2/RRC/LITE/rrc_UE.c
+44
-27
targets/RT/USER/lte-ue.c
targets/RT/USER/lte-ue.c
+8
-10
No files found.
d2d_emulator_setup.txt
View file @
cd35f606
...
...
@@ -34,23 +34,30 @@ OAI build/execute
- cp ../../../targets/bin/.usim* .
- sudo insmod ../../../targets/bin/ue_ip.ko
Get and build vencore_app from d2d-l3-stub (branch: l3_stub)
- git clone https://gitlab.eurecom.fr/tien-thinh.nguyen/d2d-l3-stub
- git checkout l3-stub
- gcc -I . vencore_app.c -o vencore_app -lpthread
UE1:
- sudo ifconfig oip0 10.0.0.1
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark
3
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark
4
- (if necessary) sudo route add default gw 10.10.10.1 eth0
UE2:
- sudo ifconfig oip0 10.0.0.2
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark
3
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark
4
- (if necessary) sudo route add default gw 10.10.10.1 eno1
UE1 and UE2: Get and build vencore_app from d2d-l3-stub (branch: l3_stub)
- gcc -I . vencore_app.c -o vencore_app -lpthread
For the moment, we suppose that L2Ids of UE1, UE2 are Ox01, 0x02 respectively. GroupL2Id is set to 0x03.
--------------------------------
TEST ONE-TO-MANY
Run UE1 then UE2, for example:
UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
- UE1 ./vencore_app -g 0x01 0x03 #0x01 - UE1-L2Id, 0x03-groupL2Id
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE2 ./vencore_app -g 0x02 0x03 #0x02 - UE2-L2Id, 0x03-groupL2Id
Test with Ping
- Sender - UE1: ping -I oip0 224.0.0.3
...
...
@@ -61,40 +68,43 @@ Test with Iperf
- Receiver - UE2: sudo ./mcreceive 224.0.0.3 5001
Filter the incomming packets according to GroupL2Id: receiver (one-to-many) can discard the packets if it doesn't belong to this group.
For the moment, both sender and receiver use the same set of Ids (hardcoded)
UE1 (sender)
- sudo ./lte-softmodem-stub -U --emul-iface eth0
- ./vencore_app #send the sourceL2Id, groupL2Id to OAI
- ./vencore_app -g 0x01 0x03 #0x01 - UE1's L2Id, 0x03-groupL2Id
- ping -I oip0 224.0.0.3
UE2(receiver)
- sudo ./lte-softmodem-stub -U --emul-iface eno1
#we can see the incomming packets from OAI log, however, cannot see from Wireshark -> they are discarded at MAC layer
-
./vencore_app
#we can see the packets appearing in Wireshark
-
./vencore_app -g 0x02 0x03 #0x02 - UE2-L2Id, 0x03-groupL2Id
#we can see the packets appearing in Wireshark
--------------------------------------
TEST PC5-S (UE1 -
sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario
TEST PC5-S (UE1 -
sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario (and PC5-U for ONE-TO-MANY scenario)
Configure UE1/UE2
UE1:
- sudo ifconfig oip0 10.0.0.1
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 4
- sudo route add default gw 10.10.10.1 eth0
UE2:
- sudo ifconfig oip0 10.0.0.2
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 4
- sudo route add default gw 10.10.10.1 eno1
step 1:
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
step 2:
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE2: ./vencore_app -r
#listen to incomming message from PC5-S
- UE2: ./vencore_app -r
0x02 0x01 #listen to incomming PC5-S message and incomming PC5-U packet from UE1, 0x02 - UE2-L2Id, 0x01 - UE1-L2Id
step 3:
- UE1: ./vencore_app -s
#send a message via PC5-S (e.g., DirectCommunicationRequest)
- UE1: ./vencore_app -s
0x01 0x02 #send a message via PC5-S (e.g., DirectCommunicationRequest) and establish 1-1 communication, 0x01 - UE1-L2Id, 0x02 - UE2-L2Id
Generate unicast traffic
UE1: ping -I oip0 10.0.0.2
-
UE1: ping -I oip0 10.0.0.2
Generate multicast traffic
- UE1: ping -I oip0 224.0.0.3
--------------------------------------
TEST PC5-D
...
...
@@ -105,3 +115,67 @@ step 2:
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE2: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
Scenario 2 : Off-network UE2UE link (3 UEs, 2 communication flows: 1 unicast + 1 multicast)
SynchREF UE (UE1)
UE1(eth0 - 10.10.10.1)-----Hub------UE2(eno1 - 10.10.10.2)
|
|
UE3 (eno1 - 10.0.0.4)
UE1-L2ID: 0x01
UE2-L2ID: 0x02
UE3-L2ID: 0x04
--------------------------------------
TEST PC5-U for ONE-TO-ONE scenario (UE1 - sender, UE2 - receiver) and PC5-U for ONE-TO-MANY scenario (UE1 - sender, UE2/3 - receiver)
- configure UE1, UE2 as mentioned in the previous section
UE1:
- sudo ifconfig oip0 10.0.0.1
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 4
- sudo route add default gw 10.10.10.1 eth0
UE2:
- sudo ifconfig oip0 10.0.0.2
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 4
- sudo route add default gw 10.10.10.1 eno1
- configure UE3
UE3:
- sudo ifconfig oip0 10.0.0.4
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 4
- sudo route add default gw 10.10.10.1 eno1
step 1:
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
step 2:
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE2: ./vencore_app -r 0x02 0x01 # listen to incomming PC5-S message and incomming PC5-U packet from UE1, 0x02 - UE2-L2Id, 0x01 - UE1-L2Id
# groupL2Id is hardcoded for the moment (0x03)
- UE3: sudo ./lte-softmodem-stub -U --emul-iface eno1
- UE3: ./vencore_app -g 0x04 0x03 # listen to incomming PC5-S message and incomming PC5-U packet from UE1, 0x02 - UE2-L2Id, 0x01 - UE1-L2Id
# groupL2Id is hardcoded for the moment
step 3:
- UE1: ./vencore_app -s 0x01 0x02 # 0x01 - UE1-L2Id, 0x02 - UE2-L2Id
# groupL2Id is hardcoded for the moment (0x03)
Generate unicast traffic
- UE1: ping -I oip0 10.0.0.2
Generate multicast traffic
- UE1: ping -I oip0 224.0.0.3
Expected results:
- UE2 can receive both unicast and multicast traffic
- UE3 can only receive multicast traffic
Note:
- Use wireshark to observe unicast/multicast traffic from UE2 and multicast traffic from UE3.
This diff is collapsed.
Click to expand it.
openair2/LAYER2/MAC/config.c
View file @
cd35f606
This diff is collapsed.
Click to expand it.
openair2/LAYER2/MAC/config_ue.c
View file @
cd35f606
This diff is collapsed.
Click to expand it.
openair2/LAYER2/MAC/defs.h
View file @
cd35f606
...
...
@@ -119,6 +119,7 @@
#define LCGID3 3
/*!\brief Maximum number of logical chanels */
#define MAX_NUM_LCID 11
#define MAX_NUM_LCID_DATA 8
/*!\brief Maximum number od control elemenets */
#define MAX_NUM_CE 5
/*!\brief Maximum number of random access process */
...
...
@@ -1324,6 +1325,19 @@ typedef struct {
int16_t
bucket_size
[
MAX_NUM_LCID
];
}
UE_SCHEDULING_INFO
;
/*!\brief Top level UE MAC structure */
typedef
struct
{
//SL source L2Id
uint32_t
sourceL2Id
;
//SL groupL2Id
uint32_t
groupL2Id
;
//SL destinationL2Id
uint32_t
destinationL2Id
;
//LCID
uint32_t
LCID
;
}
SL_INFO
;
typedef
struct
{
uint16_t
Node_id
;
/// RX frame counter
...
...
@@ -1371,11 +1385,15 @@ typedef struct {
uint32_t
groupL2Id
;
//SL destinationL2Id
uint32_t
destinationL2Id
;
//List of destinations
//List of destinations
(unicast)
uint32_t
destinationList
[
MAX_NUM_DEST
];
//List of group (multicast)
uint32_t
groupList
[
MAX_NUM_DEST
];
uint8_t
numCommFlows
;
uint32_t
SL_LCID
[
MAX_NUM_LCID
];
SL_INFO
sl_info
[
MAX_NUM_LCID
];
#endif
/// pointer to TDD Configuration (NULL for FDD)
TDD_Config_t
*
tdd_Config
;
...
...
This diff is collapsed.
Click to expand it.
openair2/LAYER2/MAC/proto.h
View file @
cd35f606
...
...
@@ -1032,6 +1032,7 @@ int rrc_mac_config_req_ue(module_id_t module_idP,
,
config_action_t
config_action
,
const
uint32_t
*
const
sourceL2Id
,
const
uint32_t
*
const
destinationL2Id
,
const
uint32_t
*
const
groupL2Id
#endif
);
...
...
This diff is collapsed.
Click to expand it.
openair2/LAYER2/MAC/ue_procedures.c
View file @
cd35f606
...
...
@@ -839,6 +839,7 @@ void ue_send_sl_sdu(module_id_t module_idP,
int
rlc_sdu_len
;
char
*
rlc_sdu
;
uint32_t
destinationL2Id
=
0x00000000
;
uint32_t
sourceL2Id
=
0x00000000
;
if
(
sl_discovery_flag
==
SL_DISCOVERY_FLAG_NO
)
{
...
...
@@ -848,17 +849,22 @@ void ue_send_sl_sdu(module_id_t module_idP,
// extract header
SLSCH_SUBHEADER_24_Bit_DST_LONG
*
longh
=
(
SLSCH_SUBHEADER_24_Bit_DST_LONG
*
)
sdu
;
AssertFatal
(
longh
->
E
==
0
,
"E is non-zero
\n
"
);
AssertFatal
(((
longh
->
LCID
==
3
)
|
(
longh
->
LCID
==
10
)
),
"LCID is %d (not 3
or 10)
\n
"
,
longh
->
LCID
);
AssertFatal
(((
longh
->
LCID
==
3
)
|
(
longh
->
LCID
==
10
)
|
(
longh
->
LCID
==
4
)),
"LCID is %d (not 3, 4
or 10)
\n
"
,
longh
->
LCID
);
//filter incoming packet based on destination address
destinationL2Id
=
(
longh
->
DST07
<<
16
)
|
(
longh
->
DST815
<<
8
)
|
(
longh
->
DST1623
);
LOG_I
(
MAC
,
"[DestinationL2Id: 0x%08x]
\n
"
,
destinationL2Id
);
sourceL2Id
=
(
longh
->
SRC07
<<
16
)
|
(
longh
->
SRC815
<<
8
)
|
(
longh
->
SRC1623
);
LOG_D
(
MAC
,
"[DestinationL2Id: 0x%08x]
\n
"
,
destinationL2Id
);
//in case of 1-n communication, verify that UE belongs to that group
int
i
=
0
;
int
i
=
0
;
for
(
i
=
0
;
i
<
MAX_NUM_DEST
;
i
++
)
if
(
UE_mac_inst
[
module_idP
].
destinationList
[
i
]
==
destinationL2Id
)
break
;
if
(
UE_mac_inst
[
module_idP
].
groupList
[
i
]
==
destinationL2Id
)
break
;
int
j
=
0
;
for
(
j
=
0
;
j
<
MAX_NUM_DEST
;
j
++
)
if
(
UE_mac_inst
[
module_idP
].
destinationList
[
j
]
==
sourceL2Id
)
break
;
//match the destinationL2Id with UE L2Id or groupL2ID
if
(
!
((
destinationL2Id
==
UE_mac_inst
[
module_idP
].
sourceL2Id
)
|
(
i
<
MAX_NUM_DEST
))){
LOG_
I
(
MAC
,
"[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!!
\n
"
);
if
(
!
((
(
destinationL2Id
==
UE_mac_inst
[
module_idP
].
sourceL2Id
)
&&
(
j
<
MAX_NUM_DEST
))
|
((
destinationL2Id
==
UE_mac_inst
[
module_idP
].
sourceL2Id
)
&&
(
longh
->
LCID
==
10
)
)
|
(
i
<
MAX_NUM_DEST
))){
LOG_
D
(
MAC
,
"[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!!
\n
"
);
return
;
}
...
...
@@ -3271,6 +3277,21 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_
break
;
}
}
if
((
ue
->
sourceL2Id
>
0
)
&&
(
ue
->
groupList
[
j
]
>
0
)
){
rlc_status
=
mac_rlc_status_ind
(
module_idP
,
0x1234
,
0
,
frameP
,
subframeP
,
ENB_FLAG_NO
,
MBMS_FLAG_NO
,
ue
->
SL_LCID
[
i
],
0xFFFF
,
ue
->
sourceL2Id
,
ue
->
groupList
[
j
]);
if
(
rlc_status
.
bytes_in_buffer
>
2
){
LOG_I
(
MAC
,
"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer
\n
"
,
frameP
,
subframeP
,
rlc_status
.
bytes_in_buffer
);
// Fill in group id for off-network communications
ue
->
sltx_active
=
1
;
//store LCID, destinationL2Id
ue
->
slsch_lcid
=
ue
->
SL_LCID
[
i
];
ue
->
destinationL2Id
=
ue
->
groupList
[
j
];
break
;
}
}
}
}
if
(
ue
->
sltx_active
==
1
)
break
;
...
...
This diff is collapsed.
Click to expand it.
openair2/RRC/LITE/MESSAGES/asn1_msg.c
View file @
cd35f606
...
...
@@ -648,6 +648,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
sib18_part
=
CALLOC
(
1
,
sizeof
(
struct
SystemInformation_r8_IEs__sib_TypeAndInfo__Member
));
sib19_part
=
CALLOC
(
1
,
sizeof
(
struct
SystemInformation_r8_IEs__sib_TypeAndInfo__Member
));
sib21_part
=
CALLOC
(
1
,
sizeof
(
struct
SystemInformation_r8_IEs__sib_TypeAndInfo__Member
));
memset
(
sib18_part
,
0
,
sizeof
(
struct
SystemInformation_r8_IEs__sib_TypeAndInfo__Member
));
memset
(
sib19_part
,
0
,
sizeof
(
struct
SystemInformation_r8_IEs__sib_TypeAndInfo__Member
));
memset
(
sib21_part
,
0
,
sizeof
(
struct
SystemInformation_r8_IEs__sib_TypeAndInfo__Member
));
...
...
@@ -659,7 +660,6 @@ uint8_t do_SIB23(uint8_t Mod_id,
*
sib18
=
&
sib18_part
->
choice
.
sib18_v1250
;
*
sib19
=
&
sib19_part
->
choice
.
sib19_v1250
;
*
sib21
=
&
sib21_part
->
choice
.
sib21_v1430
;
#endif
...
...
@@ -1347,7 +1347,6 @@ uint8_t do_SIB23(uint8_t Mod_id,
//end SIB21
#endif
bcch_message
->
message
.
present
=
BCCH_DL_SCH_MessageType_PR_c1
;
bcch_message
->
message
.
choice
.
c1
.
present
=
BCCH_DL_SCH_MessageType__c1_PR_systemInformation
;
...
...
@@ -1377,6 +1376,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
#endif
#ifdef XER_PRINT
xer_fprint
(
stdout
,
&
asn_DEF_BCCH_DL_SCH_Message
,
(
void
*
)
bcch_message
);
#endif
...
...
This diff is collapsed.
Click to expand it.
openair2/RRC/LITE/defs.h
View file @
cd35f606
...
...
@@ -665,7 +665,7 @@ typedef struct {
SystemInformationBlockType18_r12_t
*
sib18
;
SystemInformationBlockType19_r12_t
*
sib19
;
SystemInformationBlockType21_r14_t
*
sib21
;
// End - TTN
SRB_INFO
SI
;
SRB_INFO
Srb0
;
uint8_t
*
paging
[
NUMBER_OF_UE_MAX
];
...
...
@@ -773,8 +773,10 @@ typedef struct UE_RRC_INST_s {
uint32_t
groupL2Id
;
//current destination
uint32_t
destinationL2Id
;
//List of destinations
//List of destinations
(unicast)
uint32_t
destinationList
[
MAX_NUM_DEST
];
//List of groups (multicast)
uint32_t
groupList
[
MAX_NUM_DEST
];
//sl_discovery..
SRB_INFO
SL_Discovery
[
NB_CNX_UE
];
#endif
...
...
This diff is collapsed.
Click to expand it.
openair2/RRC/LITE/rrc_UE.c
View file @
cd35f606
This diff is collapsed.
Click to expand it.
targets/RT/USER/lte-ue.c
View file @
cd35f606
...
...
@@ -825,16 +825,15 @@ void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) {
wakeup_thread
(
&
UE
->
timer_mutex
,
&
UE
->
timer_cond
,
&
UE
->
instance_cnt_timer
,
"timer_thread"
);
break
;
case
SLSCH
:
LOG_I
(
PHY
,
"Emulator SFN.SF %d.%d, Got SLSCH packet
\n
"
,
emulator_absSF
/
10
,
emulator_absSF
%
10
);
LOG_I
(
PHY
,
"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC
\n
"
,
num_bytes
,
LOG_D
(
PHY
,
"Emulator SFN.SF %d.%d, Got SLSCH packet
\n
"
,
emulator_absSF
/
10
,
emulator_absSF
%
10
);
LOG_D
(
PHY
,
"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC
\n
"
,
num_bytes
,
pdu
->
header
.
absSF
/
10
,
pdu
->
header
.
absSF
%
10
,
slsch
->
payload_length
);
#ifdef DEBUG_UE_RX
printf
(
"SLSCH:"
);
for
(
int
i
=
0
;
i
<
sizeof
(
SLSCH_t
);
i
++
)
printf
(
"%x "
,((
uint8_t
*
)
slsch
)[
i
]);
printf
(
"
\n
"
);
#endif
ue_send_sl_sdu
(
0
,
0
,
pdu
->
header
.
absSF
/
10
,
...
...
@@ -846,16 +845,15 @@ void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) {
break
;
case
SLDCH
:
LOG_I
(
PHY
,
"Emulator SFN.SF %d.%d, Got SLDCH packet
\n
"
,
emulator_absSF
/
10
,
emulator_absSF
%
10
);
LOG_I
(
PHY
,
"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC
\n
"
,
num_bytes
,
LOG_D
(
PHY
,
"Emulator SFN.SF %d.%d, Got SLDCH packet
\n
"
,
emulator_absSF
/
10
,
emulator_absSF
%
10
);
LOG_D
(
PHY
,
"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC
\n
"
,
num_bytes
,
pdu
->
header
.
absSF
/
10
,
pdu
->
header
.
absSF
%
10
,
sldch
->
payload_length
);
#ifdef DEBUG_UE_RX
printf
(
"SLDCH:"
);
for
(
int
i
=
0
;
i
<
sizeof
(
SLDCH_t
);
i
++
)
printf
(
"%x "
,((
uint8_t
*
)
sldch
)[
i
]);
printf
(
"
\n
"
);
#endif
ue_send_sl_sdu
(
0
,
0
,
pdu
->
header
.
absSF
/
10
,
...
...
This diff is collapsed.
Click to expand it.
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