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
spbro
OpenXG-RAN
Commits
1f841336
Commit
1f841336
authored
Apr 10, 2022
by
Robert Schmidt
Committed by
Sakthivel Velumani
Sep 13, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add E1AP lib
parent
7465cea4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
449 additions
and
0 deletions
+449
-0
common/utils/LOG/log.h
common/utils/LOG/log.h
+1
-0
common/utils/T/T_messages.txt
common/utils/T/T_messages.txt
+21
-0
common/utils/ocp_itti/intertask_interface.h
common/utils/ocp_itti/intertask_interface.h
+2
-0
openair2/E1AP/CMakeLists.txt
openair2/E1AP/CMakeLists.txt
+6
-0
openair2/E1AP/e1ap.c
openair2/E1AP/e1ap.c
+385
-0
openair2/E1AP/e1ap.h
openair2/E1AP/e1ap.h
+34
-0
No files found.
common/utils/LOG/log.h
View file @
1f841336
...
@@ -219,6 +219,7 @@ typedef enum {
...
@@ -219,6 +219,7 @@ typedef enum {
SPGW
,
SPGW
,
S1AP
,
S1AP
,
F1AP
,
F1AP
,
E1AP
,
SCTP
,
SCTP
,
HW
,
HW
,
OSA
,
OSA
,
...
...
common/utils/T/T_messages.txt
View file @
1f841336
...
@@ -1235,6 +1235,27 @@ ID = LEGACY_F1AP_ERROR
...
@@ -1235,6 +1235,27 @@ ID = LEGACY_F1AP_ERROR
GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY
GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
FORMAT = string,log
ID = LEGACY_E1AP_TRACE
DESC = E1AP TRACE LEVEL
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_E1AP_DEBUG
DESC = E1AP DEBUG LEVEL
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_E1AP_INFO
DESC = E1AP INFO LEVEL
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_E1AP_WARNING
DESC = E1AP WARNING LEVEL
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_E1AP_ERROR
DESC = E1AP ERROR LEVEL
GROUP = ALL:LEGACY_E1AP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
#################
#################
#### UE LOGS ####
#### UE LOGS ####
#################
#################
...
...
common/utils/ocp_itti/intertask_interface.h
View file @
1f841336
...
@@ -339,6 +339,8 @@ void *rrc_enb_process_msg(void *);
...
@@ -339,6 +339,8 @@ void *rrc_enb_process_msg(void *);
TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\
TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\
TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_CUCP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_CUUP_E1, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_NSA_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_NSA_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
...
...
openair2/E1AP/CMakeLists.txt
View file @
1f841336
add_subdirectory
(
MESSAGES
)
add_subdirectory
(
MESSAGES
)
add_library
(
E1AP e1ap.c
)
target_link_libraries
(
E1AP
PUBLIC ASN1_E1AP_LIB
PRIVATE UTIL
)
target_include_directories
(
E1AP PUBLIC
${
CMAKE_CURRENT_DIR
}
)
openair2/E1AP/e1ap.c
0 → 100644
View file @
1f841336
/*
* 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
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* 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
*/
#include "e1ap.h"
int
asn1_encoder_xer_print
=
1
;
int
e1ap_assoc_id
(
bool
isCu
,
instance_t
instance
)
{
return
0
;
}
int
e1ap_encode_send
(
bool
isCu
,
instance_t
instance
,
E1AP_E1AP_PDU_t
*
pdu
,
uint16_t
stream
,
const
char
*
func
)
{
DevAssert
(
pdu
!=
NULL
);
if
(
asn1_encoder_xer_print
)
{
LOG_E
(
E1AP
,
"----------------- ASN1 ENCODER PRINT START -----------------
\n
"
);
xer_fprint
(
stdout
,
&
asn_DEF_E1AP_E1AP_PDU
,
pdu
);
LOG_E
(
E1AP
,
"----------------- ASN1 ENCODER PRINT END-----------------
\n
"
);
}
char
errbuf
[
2048
];
/* Buffer for error message */
size_t
errlen
=
sizeof
(
errbuf
);
/* Size of the buffer */
int
ret
=
asn_check_constraints
(
&
asn_DEF_E1AP_E1AP_PDU
,
pdu
,
errbuf
,
&
errlen
);
if
(
ret
)
{
fprintf
(
stderr
,
"%s: Constraint validation failed: %s
\n
"
,
func
,
errbuf
);
}
void
*
buffer
=
NULL
;
ssize_t
encoded
=
aper_encode_to_new_buffer
(
&
asn_DEF_E1AP_E1AP_PDU
,
0
,
pdu
,
buffer
);
if
(
encoded
<
0
)
{
LOG_E
(
E1AP
,
"%s: Failed to encode E1AP message
\n
"
,
func
);
return
-
1
;
}
else
{
MessageDef
*
message
=
itti_alloc_new_message
(
isCu
?
TASK_CUCP_E1
:
TASK_CUUP_E1
,
0
,
SCTP_DATA_REQ
);
sctp_data_req_t
*
s
=
&
message
->
ittiMsg
.
sctp_data_req
;
s
->
assoc_id
=
e1ap_assoc_id
(
isCu
,
instance
);
s
->
buffer
=
buffer
;
s
->
buffer_length
=
encoded
;
s
->
stream
=
stream
;
LOG_I
(
E1AP
,
"%s: Sending ITTI message to SCTP Task
\n
"
,
func
);
itti_send_msg_to_task
(
TASK_SCTP
,
instance
,
message
);
}
return
encoded
;
}
void
e1ap_itti_send_sctp_close_association
(
bool
isCu
,
instance_t
instance
)
{
MessageDef
*
message
=
itti_alloc_new_message
(
TASK_S1AP
,
0
,
SCTP_CLOSE_ASSOCIATION
);
sctp_close_association_t
*
sctp_close_association
=
&
message
->
ittiMsg
.
sctp_close_association
;
sctp_close_association
->
assoc_id
=
e1ap_assoc_id
(
isCu
,
instance
);
itti_send_msg_to_task
(
TASK_SCTP
,
instance
,
message
);
}
int
e1ap_send_RESET
(
bool
isCu
,
instance_t
instance
,
E1AP_Reset_t
*
Reset
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
E1AP_E1AP_PDU_t
pdu
=
{
0
};
return
e1ap_encode_send
(
isCu
,
instance
,
&
pdu
,
0
,
__func__
);
}
int
e1ap_send_RESET_ACKNOWLEDGE
(
instance_t
instance
,
E1AP_Reset_t
*
Reset
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1ap_handle_RESET
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1ap_handle_RESET_ACKNOWLEDGE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
Error Indication
*/
int
e1ap_handle_ERROR_INDICATION
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1ap_send_ERROR_INDICATION
(
instance_t
instance
,
E1AP_ErrorIndication_t
*
ErrorIndication
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
E1 Setup: can be sent on both ways, to be refined
*/
int
e1apCUUP_send_SETUP_REQUEST
(
instance_t
instance
,
E1AP_Reset_t
*
Reset
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_send_SETUP_RESPONSE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_send_SETUP_FAILURE
()
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_SETUP_REQUEST
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_SETUP_RESPONSE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_SETUP_FAILURE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
E1 configuration update: can be sent in both ways, to be refined
*/
int
e1apCUUP_send_gNB_DU_CONFIGURATION_UPDATE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_gNB_DU_CONFIGURATION_UPDATE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_gNB_DU_CONFIGURATION_FAILURE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
E1 release
*/
int
e1ap_send_RELEASE_REQUEST
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1ap_send_RELEASE_ACKNOWLEDGE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1ap_handle_RELEASE_REQUEST
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1ap_handle_RELEASE_ACKNOWLEDGE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
BEARER CONTEXT SETUP REQUEST
*/
int
e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
BEARER CONTEXT MODIFICATION REQUEST
*/
int
e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_FAILURE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_REQUIRED
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_CONFIRM
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_REQUIRED
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_CONFIRM
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
BEARER CONTEXT RELEASE
*/
int
e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_RELEASE_COMPLETE
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_BEARER_CONTEXT_RELEASE_REQUEST
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_handle_BEARER_CONTEXT_RELEASE_COMMAND
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_RELEASE_COMPLETE
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_RELEASE_REQUEST
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
BEARER CONTEXT INACTIVITY NOTIFICATION
*/
int
e1apCUUP_send_BEARER_CONTEXT_INACTIVITY_NOTIFICATION
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_BEARER_CONTEXT_INACTIVITY_NOTIFICATION
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
/*
DL DATA
*/
int
e1apCUUP_send_DL_DATA_NOTIFICATION
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUUP_send_DATA_USAGE_REPORT
(
instance_t
instance
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_DL_DATA_NOTIFICATION
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
int
e1apCUCP_handle_send_DATA_USAGE_REPORT
(
instance_t
instance
,
uint32_t
assoc_id
,
uint32_t
stream
,
E1AP_E1AP_PDU_t
*
pdu
)
{
AssertFatal
(
false
,
"Not implemented yet
\n
"
);
}
openair2/E1AP/e1ap.h
0 → 100644
View file @
1f841336
/*
* 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
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* 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
*/
#ifndef __E1AP_H_
#define __E1AP_H_
#include <common/utils/LOG/log.h>
#include "openairinterface5g_limits.h"
#include <openair2/RRC/NR/MESSAGES/asn1_msg.h>
#include <E1AP_Cause.h>
#include <E1AP_InitiatingMessage.h>
#include <E1AP_E1AP-PDU.h>
#endif
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