Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
MEC - Multi-access Edge Computing
MEC TTCN-3 Test Suite
Commits
8949f887
Commit
8949f887
authored
Aug 09, 2019
by
YannGarcia
Browse files
Add RnisQuery_BV tests
parent
145a034c
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
TODO.md
View file @
8949f887
...
...
@@ -27,6 +27,7 @@ https://forge.etsi.org/gitlab/mec/gs032p2-test-purposes/blob/master/Test%20Purpo
https://forge.etsi.org/gitlab/mec/gs032p2-test-purposes/blob/master/Test%20Purposes/SRV/RNIS/RnisSpecificSubscription_BV.tplan2
-
TC_MEC_SRV_RNIS_011_OK
<font
color=
"color:green"
>
To be tested
</font>
-
TC_MEC_SRV_RNIS_012_OK
<font
color=
"color:green"
>
To be tested
</font>
### SAQ
...
...
ccsrc/Protocols/Json/json_codec.cc
View file @
8949f887
...
...
@@ -24,6 +24,10 @@ int json_codec::encode (const LibItsHttp__JsonMessageBodyTypes::JsonBody& msg, O
const
LocationAPI__TypesAndValues
::
UserTrackingSubscription
&
user_tracking_subscription
=
msg
.
userTrackingSubscription
();
user_tracking_subscription
.
encode
(
LocationAPI__TypesAndValues
::
UserTrackingSubscription_descr_
,
encoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
data
=
char2oct
(
CHARSTRING
(
"{
\"
userTrackingSubscription
\"
: "
))
+
OCTETSTRING
(
encoding_buffer
.
get_len
(),
encoding_buffer
.
get_data
())
+
char2oct
(
CHARSTRING
(
"}"
));
}
else
if
(
msg
.
ischosen
(
LibItsHttp__JsonMessageBodyTypes
::
JsonBody
::
ALT_cellChangeSubscription
))
{
const
RnisAPI__TypesAndValues
::
CellChangeSubscription
&
cell_change_subscription
=
msg
.
cellChangeSubscription
();
cell_change_subscription
.
encode
(
RnisAPI__TypesAndValues
::
CellChangeSubscription_descr_
,
encoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
data
=
char2oct
(
CHARSTRING
(
"{
\"
CellChangeSubscription
\"
: "
))
+
OCTETSTRING
(
encoding_buffer
.
get_len
(),
encoding_buffer
.
get_data
())
+
char2oct
(
CHARSTRING
(
"}"
));
}
else
{
loggers
::
get_instance
().
error
(
"json_codec::encode: Not supported"
);
}
...
...
@@ -94,6 +98,19 @@ int json_codec::decode (const OCTETSTRING& p_data, LibItsHttp__JsonMessageBodyTy
AppEnablementAPI__TypesAndValues
::
TrafficRule
traffic_rule
;
traffic_rule
.
decode
(
AppEnablementAPI__TypesAndValues
::
TrafficRule_descr_
,
decoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
msg
.
trafficRule
()
=
traffic_rule
;
}
else
if
(
it
->
second
.
find
(
"
\"
CellChangeSubscription
\"
"
)
!=
std
::
string
::
npos
)
{
RnisAPI__TypesAndValues
::
CellChangeSubscription
cell_change_subscription
;
cell_change_subscription
.
decode
(
RnisAPI__TypesAndValues
::
CellChangeSubscription_descr_
,
decoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
msg
.
cellChangeSubscription
()
=
cell_change_subscription
;
//TODO Continue with other ChangeSubscription
}
else
if
(
it
->
second
.
find
(
"
\"
RabInfo
\"
"
)
!=
std
::
string
::
npos
)
{
RnisAPI__TypesAndValues
::
RabInfo
rab_info
;
rab_info
.
decode
(
RnisAPI__TypesAndValues
::
RabInfo_descr_
,
decoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
msg
.
rabInfo
()
=
rab_info
;
}
else
if
(
it
->
second
.
find
(
"
\"
PlmnInfo
\"
"
)
!=
std
::
string
::
npos
)
{
RnisAPI__TypesAndValues
::
PlmnInfo
plmn_info
;
plmn_info
.
decode
(
RnisAPI__TypesAndValues
::
PlmnInfo_descr_
,
decoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
msg
.
plmnInfo
()
=
plmn_info
;
}
else
if
(
it
->
second
.
find
(
"
\"
bwInfo
\"
"
)
!=
std
::
string
::
npos
)
{
BwManagementAPI__TypesAndValues
::
BwInfo
bw_info
;
...
...
@@ -114,9 +131,17 @@ int json_codec::decode (const OCTETSTRING& p_data, LibItsHttp__JsonMessageBodyTy
bw_info
.
decode
(
BwManagementAPI__TypesAndValues
::
BwInfo_descr_
,
decoding_buffer_
,
TTCN_EncDec
::
CT_JSON
);
msg
.
bwInfo
()
=
bw_info
;
}
else
if
(
it
->
second
.
find
(
"
\"
problemDetails
\"
"
)
!=
std
::
string
::
npos
)
{
// TODO To be refined, problemDetails in different modules
UEidentityAPI__TypesAndValues
::
ProblemDetails
problem_details
;
problem_details
.
decode
(
UEidentityAPI__TypesAndValues
::
ProblemDetails_descr_
,
decoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
msg
.
problemDetails__ue__identity
()
=
problem_details
;
// UEidentityAPI__TypesAndValues::ProblemDetails problem_details;
// problem_details.decode(UEidentityAPI__TypesAndValues::ProblemDetails_descr_, decoding_buffer, TTCN_EncDec::CT_JSON);
// msg.problemDetails__ue__identity() = problem_details;
RnisAPI__TypesAndValues
::
ProblemDetails
problem_details
;
problem_details
.
decode
(
RnisAPI__TypesAndValues
::
ProblemDetails_descr_
,
decoding_buffer
,
TTCN_EncDec
::
CT_JSON
);
msg
.
problemDetails__rni
()
=
problem_details
;
}
else
{
loggers
::
get_instance
().
warning
(
"json_codec::decode: Unsupported variant"
);
return
-
1
;
...
...
etc/AtsMec/AtsMec.cfg
View file @
8949f887
...
...
@@ -16,6 +16,7 @@ LibItsHttp_Pics.PICS_HEADER_CONTENT_TYPE := "application/json"
LibMec_Pics.PICS_MEC_PLAT := true
LibMec_Pics.PICS_SERVICES := true
LibMec_Pics.PICS_RNIS := true
LibMec_Pics.PICS_RNIS_QUERY := true
LibMec_Pics.PICS_RNIS_ALL_SUBSCRIPTIONS := true
LocationAPI_Pics.PICS_LOCATION_API_SUPPORTED := false
...
...
@@ -99,7 +100,11 @@ system.httpPort.params := "HTTP(codecs=json:json_codec)/TCP(debug=1,server=192.1
#AtsMec_LocationAPI_TestCases.TC_MEC_SRV_UEINFSUB_002_OK
#AtsMec_LocationAPI_TestCases.TC_MEC_SRV_UEINFSUB_002_NF
AtsMec_RnisAPI_TestCases.TC_MEC_SRV_RNIS_011_OK
#AtsMec_RnisAPI_TestCases.TC_MEC_SRV_RNIS_011_OK
#AtsMec_RnisAPI_TestCases.TC_MEC_SRV_RNIS_012_OK
#AtsMec_RnisAPI_TestCases.TC_MEC_SRV_RNIS_011_BR
#AtsMec_RnisAPI_TestCases.TC_MEC_SRV_RNIS_012_BR
AtsMec_RnisAPI_TestCases.TC_MEC_SRV_RNIS_016_OK
#AtsMec_AppEnablementAPI_TestCases.TC_MEC_SRV_TRANS_001_OK
#AtsMec_AppEnablementAPI_TestCases.TC_MEC_SRV_TRAF_001_OK
...
...
ttcn/AtsMec/AtsMec_RnisAPI_TestCases.ttcn
View file @
8949f887
This diff is collapsed.
Click to expand it.
ttcn/AtsMec/AtsMec_TestControl.ttcn
View file @
8949f887
...
...
@@ -72,6 +72,13 @@ module AtsMec_TestControl {
if
(
PICS_RNIS
)
{
if
(
PICS_RNIS_ALL_SUBSCRIPTIONS
)
{
execute
(
TC_MEC_SRV_RNIS_011_OK
());
execute
(
TC_MEC_SRV_RNIS_012_OK
());
execute
(
TC_MEC_SRV_RNIS_011_BR
());
execute
(
TC_MEC_SRV_RNIS_012_BR
());
}
if
(
PICS_RNIS_QUERY
)
{
execute
(
TC_MEC_SRV_RNIS_016_OK
());
}
}
...
...
ttcn/LibMec/RnisAPI/ttcn/RnisAPI_Pixits.ttcn
View file @
8949f887
...
...
@@ -3,13 +3,25 @@ module RnisAPI_Pixits {
// JSON
import
from
JSON
all
;
// LibCommon
import
from
LibCommon_BasicTypesAndValues
all
;
// LibMec/Rnis
import
from
RnisAPI_TypesAndValues
all
;
modulepar
JSON
.
String
PX_SUBSCRIPTION_TYPE
:=
"cell_change"
;
modulepar
JSON
.
String
PX_SUBSCRIPTION_HREF_VALUE
:=
"cell_change"
;
modulepar
SubscriptionType
PX_SUBSCRIPTION_TYPE
:=
CELL_CHANGE
;
modulepar
JSON
.
String
PX_SUBSCRIPTION_ID
:=
"7777"
;
modulepar
Link
PX_LINKS_SELF
:=
{
self_
:=
"http://example.com/exampleAPI/rni/v2/subscriptions"
};
modulepar
CallbackReference
PX_CALLBACK_REFERENCE
:=
"http://meAppClient.example.com/rni/v2/notifications/cell_change/77777"
;
modulepar
UInt32
PX_ASSOCIATE_ID_VALUE
:=
1
;
modulepar
CellId
PX_CELL_ID
:=
"0x0800000A"
;
modulepar
AppInsId
PX_APP_INS_ID
:=
"01"
;
}
// End of module RnisAPI_Pixits
ttcn/LibMec/RnisAPI/ttcn/RnisAPI_Templates.ttcn
View file @
8949f887
...
...
@@ -9,6 +9,34 @@ module RnisAPI_Templates {
// LibMec/RnisAPI
import
from
RnisAPI_TypesAndValues
all
;
template
(
value
)
ProblemDetails
m_problem_details
(
in
JSON
.
String
p_type
,
in
JSON
.
String
p_title
,
in
UInt32
p_status
,
in
JSON
.
String
p_detail
,
in
JSON
.
String
p_instance
)
:=
{
type_
:=
p_type
,
title
:=
p_title
,
status
:=
p_status
,
detail
:=
p_detail
,
instance
:=
p_instance
}
// End of template m_problem_details
template
(
present
)
ProblemDetails
mw_problem_details
(
template
(
present
)
JSON
.
String
p_type
:=
?
,
template
(
present
)
JSON
.
String
p_title
:=
?
,
template
(
present
)
UInt32
p_status
:=
?
,
template
(
present
)
JSON
.
String
p_detail
:=
?
,
template
(
present
)
JSON
.
String
p_instance
:=
?
)
:=
{
type_
:=
p_type
,
title
:=
p_title
,
status
:=
p_status
,
detail
:=
p_detail
,
instance
:=
p_instance
}
// End of template mw_problem_details
group
subscriptions
{
template
(
omit
)
SubscriptionLinkList
m_subscriptions_list
(
...
...
@@ -44,6 +72,66 @@ module RnisAPI_Templates {
subscriptionType
:=
p_subscriptionType
}
// End of temlate mw_subscription
template
(
value
)
RabInfo
m_rab_info
(
in
template
(
value
)
TimeStamp
p_timeStamp
,
in
AppInsId
p_appInsId
,
in
RequestId
p_requestId
,
in
template
(
value
)
CellUserInfo
p_cellUserInfo
)
:=
{
timeStamp
:=
p_timeStamp
,
appInsId
:=
p_appInsId
,
requestId
:=
p_requestId
,
cellUserInfo
:=
p_cellUserInfo
}
// End of temlate m_rab_info
template
(
present
)
RabInfo
mw_rab_info
(
template
(
present
)
TimeStamp
p_timeStamp
:=
?
,
template
(
present
)
AppInsId
p_appInsId
:=
?
,
template
(
present
)
RequestId
p_requestId
:=
?
,
template
(
present
)
CellUserInfo
p_cellUserInfo
:=
?
)
:=
{
timeStamp
:=
p_timeStamp
,
appInsId
:=
p_appInsId
,
requestId
:=
p_requestId
,
cellUserInfo
:=
p_cellUserInfo
}
// End of temlate mw_rab_info
template
(
value
)
PlmnInfo
m_plmn_info
(
in
template
(
value
)
TimeStamp
p_timeStamp
,
in
AppInsId
p_appInsId
,
in
template
(
value
)
Ecgi
p_ecgi
)
:=
{
timeStamp
:=
p_timeStamp
,
appInsId
:=
p_appInsId
,
ecgi
:=
p_ecgi
}
// End of temlate m_plmn_info
template
(
present
)
PlmnInfo
mw_plmn_info
(
template
(
present
)
TimeStamp
p_timeStamp
:=
?
,
template
(
present
)
AppInsId
p_appInsId
:=
?
,
template
(
present
)
Ecgi
p_ecgi
:=
?
)
:=
{
timeStamp
:=
p_timeStamp
,
appInsId
:=
p_appInsId
,
ecgi
:=
p_ecgi
}
// End of temlate mw_plmn_info
template
(
value
)
TimeStamp
m_time_stamp
(
in
UInt32
p_seconds
,
in
UInt32
p_nanoSeconds
:=
0
)
:=
{
seconds
:=
p_seconds
,
nanoSeconds
:=
p_nanoSeconds
}
// End of temlate m_time_stamp
template
(
present
)
TimeStamp
mw_time_stamp
(
template
(
present
)
UInt32
p_seconds
:=
?
,
template
(
present
)
UInt32
p_nanoSeconds
:=
?
)
:=
{
seconds
:=
p_seconds
,
nanoSeconds
:=
p_nanoSeconds
}
// End of temlate mw_time_stamp
group
cell
{
template
(
omit
)
CellChangeSubscription
m_cell_change_subscription
(
...
...
@@ -52,26 +140,130 @@ module RnisAPI_Templates {
in
template
(
value
)
FilterCriteriaAssocHo
p_filterCriteria
,
in
template
(
omit
)
TimeStamp
p_expiryDeadline
:=
omit
)
:=
{
subscriptionType
:=
CELL_CHANGE
,
callbackReference
:=
p_callbackReference
,
links
:=
p_links
,
filterCriteria
:=
p_filterCriteria
,
expiryDeadline
:=
p_expiryDeadline
}
// End of template m_cell_change_subscription
template
(
omit
)
CellChangeSubscription
m_cell_change_subscription_wrong_subscription_type
(
in
template
(
value
)
CallbackReference
p_callbackReference
,
in
template
(
value
)
Link
p_links
,
in
template
(
value
)
FilterCriteriaAssocHo
p_filterCriteria
,
in
template
(
omit
)
TimeStamp
p_expiryDeadline
:=
omit
)
modifies
m_cell_change_subscription
:=
{
subscriptionType
:=
WRONG_PARAMETER
}
// End of template m_cell_change_subscription_wrong_subscription_type
template
CellChangeSubscription
mw_cell_change_subscription
(
template
(
present
)
CallbackReference
p_callbackReference
:=
?
,
template
(
present
)
Link
p_links
:=
?
,
template
(
present
)
FilterCriteriaAssocHo
p_filterCriteria
:=
?
,
template
TimeStamp
p_expiryDeadline
:=
*
)
:=
{
subscriptionType
:=
CELL_CHANGE
,
callbackReference
:=
p_callbackReference
,
links
:=
p_links
,
filterCriteria
:=
p_filterCriteria
,
expiryDeadline
:=
p_expiryDeadline
}
// End of template mw_cell_change_subscription
template
(
value
)
FilterCriteriaAssocHo
m_filter_criteria
(
in
AppInsId
p_appInsId
,
in
template
(
value
)
AssociateId
p_associateId
,
in
template
(
value
)
Plmn
p_plmn
,
in
template
(
value
)
CellId
p_cellId
,
in
HoStatus
p_hoStatus
)
:=
{
appInsId
:=
p_appInsId
,
associateId
:=
p_associateId
,
plmn
:=
p_plmn
,
cellId
:=
p_cellId
,
hoStatus
:=
p_hoStatus
}
// End of template m_filter_criteria
template
(
present
)
FilterCriteriaAssocHo
mw_filter_criteria
(
template
(
present
)
AppInsId
p_appInsId
:=
?
,
template
(
present
)
AssociateId
p_associateId
:=
?
,
template
(
present
)
Plmn
p_plmn
:=
?
,
template
(
present
)
CellId
p_cellId
:=
?
,
template
(
present
)
HoStatus
p_hoStatus
:=
?
)
:=
{
appInsId
:=
p_appInsId
,
associateId
:=
p_associateId
,
plmn
:=
p_plmn
,
cellId
:=
p_cellId
,
hoStatus
:=
p_hoStatus
}
// End of template mw_filter_criteria
template
(
value
)
CellUserInfo
m_cell_user_info
(
in
template
(
value
)
Ecgi
p_ecgi
,
in
template
(
value
)
UeInfo
p_ueInfo
)
:=
{
ecgi
:=
p_ecgi
,
ueInfo
:=
p_ueInfo
}
// End of template m_cell_user_info
template
(
present
)
CellUserInfo
mw_cell_user_info
(
template
(
present
)
Ecgi
p_ecgi
:=
?
,
template
(
present
)
UeInfo
p_ueInfo
:=
?
)
:=
{
ecgi
:=
p_ecgi
,
ueInfo
:=
p_ueInfo
}
// End of template mw_cell_user_info
template
(
value
)
AssociateId_
m_associate_id
(
in
AssociateId_type
p_type_
,
in
UInt32
p_value_
)
:=
{
type_
:=
p_type_
,
value_
:=
p_value_
}
// End of template m_associate_id
template
(
present
)
AssociateId_
mw_associate_id
(
template
(
present
)
AssociateId_type
p_type_
:=
?
,
template
(
present
)
UInt32
p_value_
:=
?
)
:=
{
type_
:=
p_type_
,
value_
:=
p_value_
}
// End of template mw_associate_id
template
(
value
)
Ecgi
m_ecgi
(
in
template
(
value
)
Plmn
p_plmn
,
in
template
(
value
)
CellId
p_cellId
)
:=
{
plmn
:=
p_plmn
,
cellId
:=
p_cellId
}
// End of template m_ecgi
template
(
present
)
Ecgi
mw_ecgi
(
in
template
(
present
)
Plmn
p_plmn
:=
?
,
in
template
(
present
)
CellId
p_cellId
:=
?
)
:=
{
plmn
:=
p_plmn
,
cellId
:=
p_cellId
}
// End of template mw_ecgi
template
(
value
)
Plmn
m_plmn
(
in
JSON
.
String
p_mcc
,
in
JSON
.
String
p_mnc
)
:=
{
mcc
:=
p_mcc
,
mnc
:=
p_mnc
}
// End of template m_plmn
template
(
present
)
Plmn
mw_plmn
(
template
(
present
)
JSON
.
String
p_mcc
:=
?
,
template
(
present
)
JSON
.
String
p_mnc
:=
?
)
:=
{
mcc
:=
p_mcc
,
mnc
:=
p_mnc
}
// End of template mw_plmn
}
// End of group cell
}
// End of group subscriptions
}
// End of module RnisAPI_Templates
ttcn/LibMec/RnisAPI/ttcn/RnisAPI_TypesAndValues.ttcn
View file @
8949f887
...
...
@@ -183,7 +183,7 @@ module RnisAPI_TypesAndValues {
/**
* @desc The E-UTRAN Cell Identity as a bit string (size (28)), as defined in 3GPP TS 36.413
*/
type
record
of
octets
tring
CellId
;
type
JSON
.
S
tring
CellId
;
/**
* @desc Information on UEs in the specific cell
...
...
@@ -455,6 +455,7 @@ module RnisAPI_TypesAndValues {
* @member expiryDeadline
*/
type
record
CellChangeSubscription
{
SubscriptionType
subscriptionType
,
CallbackReference
callbackReference
,
Link
links
,
FilterCriteriaAssocHo
filterCriteria
,
...
...
@@ -540,7 +541,8 @@ module RnisAPI_TypesAndValues {
MEAS_REPORT_UE
,
MEAS_TIMING_ADVANCE
,
CA_RECONF
,
S1_BEARE
S1_BEARE
,
WRONG_PARAMETER
}
/**
...
...
ttcn/LibMec/ttcn/LibMec_Pixits.ttcn
View file @
8949f887
...
...
@@ -20,6 +20,8 @@ module LibMec_Pixits {
modulepar
charstring
PX_RNIS_SUBSCRITIONS_URI
:=
"/rni/v2/subscriptions"
;
modulepar
charstring
PX_RNIS_QUERIES_URI
:=
"/rni/v2/queries"
;
modulepar
charstring
PX_ME_BWM_URI
:=
"/bwm/v2/bw_allocations"
;
}
// End of module LibMec_Pixits
ttcn/patch_lib_http/LibItsHttp_JsonMessageBodyTypes.ttcn
View file @
8949f887
...
...
@@ -29,7 +29,9 @@ module LibItsHttp_JsonMessageBodyTypes {
UeIdentityTagInfo
ueIdentityTagInfo
,
SubscriptionLinkList
subscriptionLinkList
,
CellChangeSubscription
cellChangeSubscription
,
RnisAPI_TypesAndValues
.
ProblemDetails
problemDetails_rnis
,
RabInfo
rabInfo
,
PlmnInfo
plmnInfo
,
RnisAPI_TypesAndValues
.
ProblemDetails
problemDetails_rni
,
BwInfo
bwInfo
,
BwManagementAPI_TypesAndValues
.
ProblemDetails
problemDetails_bw_management
,
TransportInfoList
transportInfoList
,
...
...
ttcn/patch_lib_http/LibItsHttp_JsonTemplates.ttcn
View file @
8949f887
...
...
@@ -174,6 +174,42 @@ module LibItsHttp_JsonTemplates {
cellChangeSubscription
:=
p_cellChangeSubscription
}
// End of template mw_body_json_cell_change_subscription
template
(
value
)
JsonBody
m_body_json_rab_info
(
in
template
(
value
)
RabInfo
p_rabInfo
)
:=
{
rabInfo
:=
p_rabInfo
}
// End of template m_body_json_rab_info
template
(
present
)
JsonBody
mw_body_json_rab_info
(
template
(
present
)
RabInfo
p_rabInfo
:=
?
)
:=
{
rabInfo
:=
p_rabInfo
}
// End of template mw_body_json_rab_info
template
(
value
)
JsonBody
m_body_json_plmn_info
(
in
template
(
value
)
PlmnInfo
p_plmnInfo
)
:=
{
plmnInfo
:=
p_plmnInfo
}
// End of template m_body_json_plmn_info
template
(
present
)
JsonBody
mw_body_json_plmn_info
(
template
(
present
)
PlmnInfo
p_plmnInfo
:=
?
)
:=
{
plmnInfo
:=
p_plmnInfo
}
// End of template mw_body_json_plmn_info
template
(
value
)
JsonBody
m_body_json_rni_problem_details
(
in
template
(
value
)
RnisAPI_TypesAndValues
.
ProblemDetails
p_problemDetails
)
:=
{
problemDetails_rni
:=
p_problemDetails
}
// End of template m_body_json_rni_problem_details
template
(
present
)
JsonBody
mw_body_json_rni_problem_details
(
template
(
present
)
RnisAPI_TypesAndValues
.
ProblemDetails
p_problemDetails
:=
?
)
:=
{
problemDetails_rni
:=
p_problemDetails
}
// End of template mw_body_json_rni_problem_details
}
// End of group rnis_subscriptions
group
bw_management_api
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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