Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-UDR
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
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-UDR
Commits
96df5bca
Commit
96df5bca
authored
Jan 15, 2021
by
yangjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update Amf3GppAccessRegistration: add database
parent
fc26b322
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
252 additions
and
16 deletions
+252
-16
impl/AMF3GPPAccessRegistrationDocumentApiImpl.cpp
impl/AMF3GPPAccessRegistrationDocumentApiImpl.cpp
+243
-11
impl/AMF3GPPAccessRegistrationDocumentApiImpl.h
impl/AMF3GPPAccessRegistrationDocumentApiImpl.h
+8
-4
main-api-server.cpp
main-api-server.cpp
+1
-1
No files found.
impl/AMF3GPPAccessRegistrationDocumentApiImpl.cpp
View file @
96df5bca
/**
* Nudr_DataRepository API OpenAPI file
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.2
*
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
...
...
@@ -19,12 +19,14 @@ namespace api {
using
namespace
org
::
openapitools
::
server
::
model
;
AMF3GPPAccessRegistrationDocumentApiImpl
::
AMF3GPPAccessRegistrationDocumentApiImpl
(
std
::
shared_ptr
<
Pistache
::
Rest
::
Router
>
rtr
)
AMF3GPPAccessRegistrationDocumentApiImpl
::
AMF3GPPAccessRegistrationDocumentApiImpl
(
std
::
shared_ptr
<
Pistache
::
Rest
::
Router
>
rtr
,
MYSQL
*
mysql
)
:
AMF3GPPAccessRegistrationDocumentApi
(
rtr
)
{
}
{
mysql_WitcommUDRDB
=
mysql
;
}
void
AMF3GPPAccessRegistrationDocumentApiImpl
::
amf_context3gpp
(
const
std
::
string
&
ueId
,
const
std
::
vector
<
PatchItem
>
&
patchItem
,
const
Pistache
::
Optional
<
std
::
string
>
&
supportedFeatures
,
Pistache
::
Http
::
ResponseWriter
&
response
)
{
/************************ test ************************/
nlohmann
::
json
j
,
j1
;
for
(
int
i
=
0
;
i
<
patchItem
.
size
();
i
++
)
...
...
@@ -41,18 +43,248 @@ void AMF3GPPAccessRegistrationDocumentApiImpl::amf_context3gpp(const std::string
//response.send(Pistache::Http::Code::Ok, j.dump());
}
void
AMF3GPPAccessRegistrationDocumentApiImpl
::
create_amf_context3gpp
(
const
std
::
string
&
ueId
,
const
Amf3GppAccessRegistration
&
amf3GppAccessRegistration
,
Pistache
::
Http
::
ResponseWriter
&
response
)
{
//response.send(Pistache::Http::Code::Ok, "Do some magic\n");
MYSQL_RES
*
res
=
NULL
;
MYSQL_ROW
row
;
const
std
::
string
select_AMF3GPPAccessRegistration
=
"select * from Amf3GppAccessRegistration WHERE ueid="
+
ueId
;
std
::
string
query
;
nlohmann
::
json
j
;
if
(
mysql_real_query
(
mysql_WitcommUDRDB
,
select_AMF3GPPAccessRegistration
.
c_str
(),
(
unsigned
long
)
select_AMF3GPPAccessRegistration
.
size
()))
{
std
::
cout
<<
"mysql_real_query failure!"
<<
std
::
endl
;
return
;
}
res
=
mysql_store_result
(
mysql_WitcommUDRDB
);
if
(
res
==
NULL
)
{
std
::
cout
<<
"mysql_store_result failure!"
<<
std
::
endl
;
return
;
}
if
(
mysql_num_rows
(
res
))
{
query
=
"update Amf3GppAccessRegistration set amfInstanceId='"
+
amf3GppAccessRegistration
.
getAmfInstanceId
()
+
"',"
+
\
(
amf3GppAccessRegistration
.
supportedFeaturesIsSet
()
?
"supportedFeatures='"
+
amf3GppAccessRegistration
.
getSupportedFeatures
()
+
"',"
:
""
)
+
\
(
amf3GppAccessRegistration
.
purgeFlagIsSet
()
?
(
amf3GppAccessRegistration
.
isPurgeFlag
()
?
"purgeFlag=1,"
:
"purgeFlag=0,"
)
:
""
)
+
\
(
amf3GppAccessRegistration
.
peiIsSet
()
?
"pei='"
+
amf3GppAccessRegistration
.
getPei
()
+
"',"
:
""
)
+
\
// (amf3GppAccessRegistration.imsVoPsIsSet()?",imsVoPs="+amf3GppAccessRegistration.getImsVoPs():"")+
"deregCallbackUri='"
+
amf3GppAccessRegistration
.
getDeregCallbackUri
()
+
"',"
+
\
// (amf3GppAccessRegistration.amfServiceNameDeregIsSet()?",amfServiceNameDereg="+amf3GppAccessRegistration.getAmfServiceNameDereg():"")+
(
amf3GppAccessRegistration
.
pcscfRestorationCallbackUriIsSet
()
?
"pcscfRestorationCallbackUri='"
+
amf3GppAccessRegistration
.
getPcscfRestorationCallbackUri
()
+
"',"
:
""
)
+
\
// (amf3GppAccessRegistration.amfServiceNamePcscfRestIsSet()?",amfServiceNamePcscfRest="+amf3GppAccessRegistration.getAmfServiceNamePcscfRest():"")+
(
amf3GppAccessRegistration
.
initialRegistrationIndIsSet
()
?
(
amf3GppAccessRegistration
.
isInitialRegistrationInd
()
?
"initialRegistrationInd=1,"
:
"initialRegistrationInd=0,"
)
:
""
)
+
\
// ",guami="+to_json(j,amf3GppAccessRegistration.getGuami())+ **M
// backupAmfInfo
(
amf3GppAccessRegistration
.
drFlagIsSet
()
?
(
amf3GppAccessRegistration
.
isDrFlag
()
?
"drFlag=1,"
:
"drFlag=0,"
)
:
""
)
+
\
// ratType **M
(
amf3GppAccessRegistration
.
urrpIndicatorIsSet
()
?
(
amf3GppAccessRegistration
.
isUrrpIndicator
()
?
"urrpIndicator=1,"
:
"urrpIndicator=0,"
)
:
""
)
+
\
(
amf3GppAccessRegistration
.
amfEeSubscriptionIdIsSet
()
?
"amfEeSubscriptionId='"
+
amf3GppAccessRegistration
.
getAmfEeSubscriptionId
()
+
"',"
:
""
)
+
\
// epsInterworkingInfo
(
amf3GppAccessRegistration
.
ueSrvccCapabilityIsSet
()
?
(
amf3GppAccessRegistration
.
isUeSrvccCapability
()
?
"ueSrvccCapability=1,"
:
"ueSrvccCapability=0,"
)
:
""
)
+
\
(
amf3GppAccessRegistration
.
registrationTimeIsSet
()
?
"registrationTime='"
+
amf3GppAccessRegistration
.
getRegistrationTime
()
+
"',"
:
""
)
+
\
// vgmlcAddress
// contextInfo
(
amf3GppAccessRegistration
.
noEeSubscriptionIndIsSet
()
?
(
amf3GppAccessRegistration
.
isNoEeSubscriptionInd
()
?
"noEeSubscriptionInd=1,"
:
"noEeSubscriptionInd=0,"
)
:
""
);
to_json
(
j
,
amf3GppAccessRegistration
.
getGuami
());
query
+=
"guami='"
+
j
.
dump
()
+
"',"
;
// to_json(j,amf3GppAccessRegistration.getRatType());
// query += ",ratType="+j.dump();
query
+=
"ratType='{}'"
;
query
+=
" where ueid="
+
ueId
;
}
else
{
query
=
"insert into Amf3GppAccessRegistration set ueid="
+
ueId
+
","
+
\
"amfInstanceId='"
+
amf3GppAccessRegistration
.
getAmfInstanceId
()
+
"',"
+
\
(
amf3GppAccessRegistration
.
supportedFeaturesIsSet
()
?
"supportedFeatures='"
+
amf3GppAccessRegistration
.
getSupportedFeatures
()
+
"',"
:
""
)
+
\
(
amf3GppAccessRegistration
.
purgeFlagIsSet
()
?
(
amf3GppAccessRegistration
.
isPurgeFlag
()
?
"purgeFlag=1,"
:
"purgeFlag=0,"
)
:
""
)
+
\
(
amf3GppAccessRegistration
.
peiIsSet
()
?
"pei='"
+
amf3GppAccessRegistration
.
getPei
()
+
"',"
:
""
)
+
\
// (amf3GppAccessRegistration.imsVoPsIsSet()?",imsVoPs="+amf3GppAccessRegistration.getImsVoPs():"")+
"deregCallbackUri='"
+
amf3GppAccessRegistration
.
getDeregCallbackUri
()
+
"',"
+
\
// (amf3GppAccessRegistration.amfServiceNameDeregIsSet()?",amfServiceNameDereg="+amf3GppAccessRegistration.getAmfServiceNameDereg():"")+
(
amf3GppAccessRegistration
.
pcscfRestorationCallbackUriIsSet
()
?
"pcscfRestorationCallbackUri='"
+
amf3GppAccessRegistration
.
getPcscfRestorationCallbackUri
()
+
"',"
:
""
)
+
\
// (amf3GppAccessRegistration.amfServiceNamePcscfRestIsSet()?",amfServiceNamePcscfRest="+amf3GppAccessRegistration.getAmfServiceNamePcscfRest():"")+
(
amf3GppAccessRegistration
.
initialRegistrationIndIsSet
()
?
(
amf3GppAccessRegistration
.
isInitialRegistrationInd
()
?
"initialRegistrationInd=1,"
:
"initialRegistrationInd=0,"
)
:
""
)
+
\
// ",guami="+to_json(j,amf3GppAccessRegistration.getGuami())+ **M
// backupAmfInfo
(
amf3GppAccessRegistration
.
drFlagIsSet
()
?
(
amf3GppAccessRegistration
.
isDrFlag
()
?
"drFlag=1,"
:
"drFlag=0,"
)
:
""
)
+
\
// ratType **M
(
amf3GppAccessRegistration
.
urrpIndicatorIsSet
()
?
(
amf3GppAccessRegistration
.
isUrrpIndicator
()
?
"urrpIndicator=1,"
:
"urrpIndicator=0,"
)
:
""
)
+
\
(
amf3GppAccessRegistration
.
amfEeSubscriptionIdIsSet
()
?
"amfEeSubscriptionId='"
+
amf3GppAccessRegistration
.
getAmfEeSubscriptionId
()
+
"',"
:
""
)
+
\
// epsInterworkingInfo
(
amf3GppAccessRegistration
.
ueSrvccCapabilityIsSet
()
?
(
amf3GppAccessRegistration
.
isUeSrvccCapability
()
?
"ueSrvccCapability=1,"
:
"ueSrvccCapability=0,"
)
:
""
)
+
\
(
amf3GppAccessRegistration
.
registrationTimeIsSet
()
?
"registrationTime='"
+
amf3GppAccessRegistration
.
getRegistrationTime
()
+
"',"
:
""
)
+
\
// vgmlcAddress
// contextInfo
(
amf3GppAccessRegistration
.
noEeSubscriptionIndIsSet
()
?
(
amf3GppAccessRegistration
.
isNoEeSubscriptionInd
()
?
"noEeSubscriptionInd=1,"
:
"noEeSubscriptionInd=0,"
)
:
""
);
to_json
(
j
,
amf3GppAccessRegistration
.
getGuami
());
query
+=
"guami='"
+
j
.
dump
()
+
"',"
;
// to_json(j,amf3GppAccessRegistration.getRatType());
// query += ",ratType="+j.dump();
query
+=
"ratType='{}'"
;
}
mysql_free_result
(
res
);
// std::cout << query << std::endl;
if
(
mysql_real_query
(
mysql_WitcommUDRDB
,
query
.
c_str
(),
(
unsigned
long
)
query
.
size
()))
{
std
::
cout
<<
"mysql_real_query failure!"
<<
std
::
endl
;
return
;
}
/************************ test ************************/
nlohmann
::
json
j
;
to_json
(
j
,
amf3GppAccessRegistration
);
response
.
send
(
Pistache
::
Http
::
Code
::
Created
,
j
.
dump
());
//response.send(Pistache::Http::Code::Ok, "Do some magic hello\n");
/******************************************************/
}
void
AMF3GPPAccessRegistrationDocumentApiImpl
::
query_amf_context3gpp
(
const
std
::
string
&
ueId
,
const
Pistache
::
Optional
<
std
::
vector
<
std
::
string
>>
&
fields
,
const
Pistache
::
Optional
<
std
::
string
>
&
supportedFeatures
,
Pistache
::
Http
::
ResponseWriter
&
response
)
{
response
.
send
(
Pistache
::
Http
::
Code
::
Ok
,
"query_amf_context3gpp
\n
"
);
MYSQL_RES
*
res
=
NULL
;
MYSQL_ROW
row
;
MYSQL_FIELD
*
field
=
nullptr
;
nlohmann
::
json
j
;
Amf3GppAccessRegistration
amf3gppaccessregistration
;
const
std
::
string
query
=
"select * from Amf3GppAccessRegistration WHERE ueid="
+
ueId
;
if
(
mysql_real_query
(
mysql_WitcommUDRDB
,
query
.
c_str
(),
(
unsigned
long
)
query
.
size
()))
{
std
::
cout
<<
"mysql_real_query failure!"
<<
std
::
endl
;
return
;
}
res
=
mysql_store_result
(
mysql_WitcommUDRDB
);
if
(
res
==
NULL
)
{
std
::
cout
<<
"mysql_store_result failure!"
<<
std
::
endl
;
return
;
}
row
=
mysql_fetch_row
(
res
);
if
(
row
!=
NULL
)
{
for
(
int
i
=
0
;
field
=
mysql_fetch_field
(
res
);
i
++
)
{
if
(
!
strcmp
(
"amfInstanceId"
,
field
->
name
))
{
amf3gppaccessregistration
.
setAmfInstanceId
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"supportedFeatures"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
amf3gppaccessregistration
.
setSupportedFeatures
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"purgeFlag"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
if
(
strcmp
(
row
[
i
],
"0"
))
amf3gppaccessregistration
.
setPurgeFlag
(
true
);
else
amf3gppaccessregistration
.
setPurgeFlag
(
false
);
}
else
if
(
!
strcmp
(
"pei"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
amf3gppaccessregistration
.
setPei
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"imsVoPs"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setImsVoPs(ImsVoPs const & value);
}
else
if
(
!
strcmp
(
"deregCallbackUri"
,
field
->
name
))
{
amf3gppaccessregistration
.
setDeregCallbackUri
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"amfServiceNameDereg"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setAmfServiceNameDereg(ServiceName const & value);
}
else
if
(
!
strcmp
(
"pcscfRestorationCallbackUri"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
amf3gppaccessregistration
.
setPcscfRestorationCallbackUri
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"amfServiceNamePcscfRest"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setAmfServiceNamePcscfRest(ServiceName const & value);
}
else
if
(
!
strcmp
(
"initialRegistrationInd"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
if
(
strcmp
(
row
[
i
],
"0"
))
amf3gppaccessregistration
.
setInitialRegistrationInd
(
true
);
else
amf3gppaccessregistration
.
setInitialRegistrationInd
(
false
);
}
else
if
(
!
strcmp
(
"guami"
,
field
->
name
))
{
// amf3gppaccessregistration.setGuami(Guami const & value);
}
else
if
(
!
strcmp
(
"backupAmfInfo"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setBackupAmfInfo(std :: vector < BackupAmfInfo > const & value);
}
else
if
(
!
strcmp
(
"drFlag"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
if
(
strcmp
(
row
[
i
],
"0"
))
amf3gppaccessregistration
.
setDrFlag
(
true
);
else
amf3gppaccessregistration
.
setDrFlag
(
false
);
}
else
if
(
!
strcmp
(
"ratType"
,
field
->
name
))
{
// amf3gppaccessregistration.setRatType(RatType const & value);
}
else
if
(
!
strcmp
(
"urrpIndicator"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
if
(
strcmp
(
row
[
i
],
"0"
))
amf3gppaccessregistration
.
setUrrpIndicator
(
true
);
else
amf3gppaccessregistration
.
setUrrpIndicator
(
false
);
}
else
if
(
!
strcmp
(
"amfEeSubscriptionId"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
amf3gppaccessregistration
.
setAmfEeSubscriptionId
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"epsInterworkingInfo"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setEpsInterworkingInfo(EpsInterworkingInfo const & value);
}
else
if
(
!
strcmp
(
"ueSrvccCapability"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
if
(
strcmp
(
row
[
i
],
"0"
))
amf3gppaccessregistration
.
setUeSrvccCapability
(
true
);
else
amf3gppaccessregistration
.
setUeSrvccCapability
(
false
);
}
else
if
(
!
strcmp
(
"registrationTime"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
amf3gppaccessregistration
.
setRegistrationTime
(
row
[
i
]);
}
else
if
(
!
strcmp
(
"vgmlcAddress"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setVgmlcAddress(VgmlcAddress const & value);
}
else
if
(
!
strcmp
(
"contextInfo"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
// amf3gppaccessregistration.setContextInfo(ContextInfo const & value);
}
else
if
(
!
strcmp
(
"noEeSubscriptionInd"
,
field
->
name
)
&&
row
[
i
]
!=
NULL
)
{
if
(
strcmp
(
row
[
i
],
"0"
))
amf3gppaccessregistration
.
setNoEeSubscriptionInd
(
true
);
else
amf3gppaccessregistration
.
setNoEeSubscriptionInd
(
false
);
}
}
to_json
(
j
,
amf3gppaccessregistration
);
response
.
send
(
Pistache
::
Http
::
Code
::
Ok
,
j
.
dump
());
}
else
{
std
::
cout
<<
"Amf3GppAccessRegistration no data!"
<<
std
::
endl
;
}
mysql_free_result
(
res
);
}
}
...
...
impl/AMF3GPPAccessRegistrationDocumentApiImpl.h
View file @
96df5bca
/**
* Nudr_DataRepository API OpenAPI file
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
* Unified Data Repository Service. © 2020, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 2.1.2
*
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
...
...
@@ -13,7 +13,7 @@
/*
* AMF3GPPAccessRegistrationDocumentApiImpl.h
*
*
*
*/
#ifndef AMF3_GPP_ACCESS_REGISTRATION_DOCUMENT_API_IMPL_H_
...
...
@@ -36,6 +36,8 @@
#include <string>
#include <vector>
#include <mysql/mysql.h>
namespace
org
{
namespace
openapitools
{
namespace
server
{
...
...
@@ -45,13 +47,15 @@ using namespace org::openapitools::server::model;
class
AMF3GPPAccessRegistrationDocumentApiImpl
:
public
org
::
openapitools
::
server
::
api
::
AMF3GPPAccessRegistrationDocumentApi
{
public:
AMF3GPPAccessRegistrationDocumentApiImpl
(
std
::
shared_ptr
<
Pistache
::
Rest
::
Router
>
);
AMF3GPPAccessRegistrationDocumentApiImpl
(
std
::
shared_ptr
<
Pistache
::
Rest
::
Router
>
,
MYSQL
*
mysql
);
~
AMF3GPPAccessRegistrationDocumentApiImpl
()
{}
void
amf_context3gpp
(
const
std
::
string
&
ueId
,
const
std
::
vector
<
PatchItem
>
&
patchItem
,
const
Pistache
::
Optional
<
std
::
string
>
&
supportedFeatures
,
Pistache
::
Http
::
ResponseWriter
&
response
);
void
create_amf_context3gpp
(
const
std
::
string
&
ueId
,
const
Amf3GppAccessRegistration
&
amf3GppAccessRegistration
,
Pistache
::
Http
::
ResponseWriter
&
response
);
void
query_amf_context3gpp
(
const
std
::
string
&
ueId
,
const
Pistache
::
Optional
<
std
::
vector
<
std
::
string
>>
&
fields
,
const
Pistache
::
Optional
<
std
::
string
>
&
supportedFeatures
,
Pistache
::
Http
::
ResponseWriter
&
response
);
private:
MYSQL
*
mysql_WitcommUDRDB
;
};
}
...
...
main-api-server.cpp
View file @
96df5bca
...
...
@@ -171,7 +171,7 @@ int main() {
}
AMF3GPPAccessRegistrationDocumentApiImpl
AMF3GPPAccessRegistrationDocumentApiserver
(
router
);
AMF3GPPAccessRegistrationDocumentApiImpl
AMF3GPPAccessRegistrationDocumentApiserver
(
router
,
&
mysql
);
AMF3GPPAccessRegistrationDocumentApiserver
.
init
();
AMFNon3GPPAccessRegistrationDocumentApiImpl
AMFNon3GPPAccessRegistrationDocumentApiserver
(
router
);
AMFNon3GPPAccessRegistrationDocumentApiserver
.
init
();
...
...
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