Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EV side Se/Deserialization for session_setup and unit tests #81

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/iso15118/message/session_setup.cpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove your comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the comments in the code file?
src/iso15118/message/session_setup.cpp

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,19 @@ namespace iso15118::message_20 {

//
// conversions
// RBL Added conversions for both directions, since EV side is the mirror of the EVSE side
//
template <> void convert(const struct iso20_SessionSetupReqType& in, SessionSetupRequest& out) {
convert(in.Header, out.header);
out.evccid = CB2CPP_STRING(in.EVCCID);
}

//Add the conversion for the response from the EVCC
template <> void convert(const struct iso20_SessionSetupResType& in, SessionSetupResponse& out) {
convert(in.Header, out.header);
out.evseid = CB2CPP_STRING(in.EVSEID);
}

template <> void convert(const SessionSetupResponse& in, iso20_SessionSetupResType& out) {
init_iso20_SessionSetupResType(&out);

Expand All @@ -29,10 +36,24 @@ template <> void convert(const SessionSetupResponse& in, iso20_SessionSetupResTy
convert(in.header, out.Header);
}

//Add conversion for the request to convert to exi
template <> void convert(const SessionSetupRequest& in, iso20_SessionSetupReqType& out) {
init_iso20_SessionSetupReqType(&out);

CPP2CB_STRING(in.evccid, out.EVCCID);

convert(in.header, out.Header);
}

template <> void insert_type(VariantAccess& va, const struct iso20_SessionSetupReqType& in) {
va.insert_type<SessionSetupRequest>(in);
};

//add the insert type for the incoming Response
template <> void insert_type(VariantAccess& va, const struct iso20_SessionSetupResType& in) {
va.insert_type<SessionSetupResponse>(in);
};

template <> int serialize_to_exi(const SessionSetupResponse& in, exi_bitstream_t& out) {
iso20_exiDocument doc;
init_iso20_exiDocument(&doc);
Expand All @@ -43,8 +64,24 @@ template <> int serialize_to_exi(const SessionSetupResponse& in, exi_bitstream_t
return encode_iso20_exiDocument(&out, &doc);
}

//request serialize
template <> int serialize_to_exi(const SessionSetupRequest& in, exi_bitstream_t& out) {
iso20_exiDocument doc;
init_iso20_exiDocument(&doc);
CB_SET_USED(doc.SessionSetupReq);

convert(in, doc.SessionSetupReq);

return encode_iso20_exiDocument(&out, &doc);
}

template <> size_t serialize(const SessionSetupResponse& in, const io::StreamOutputView& out) {
return serialize_helper(in, out);
}

//Add the Request serialize
template <> size_t serialize(const SessionSetupRequest& in, const io::StreamOutputView& out) {
return serialize_helper(in, out);
}

} // namespace iso15118::message_20
2 changes: 2 additions & 0 deletions src/iso15118/message/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static void handle_main(VariantAccess& va) {

if (doc.SessionSetupReq_isUsed) {
insert_type(va, doc.SessionSetupReq);
} else if (doc.SessionSetupRes_isUsed) {
insert_type(va, doc.SessionSetupRes);
} else if (doc.AuthorizationSetupReq_isUsed) {
insert_type(va, doc.AuthorizationSetupReq);
} else if (doc.AuthorizationReq_isUsed) {
Expand Down
101 changes: 89 additions & 12 deletions test/exi/cb/iso20/session_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,119 @@

using namespace iso15118;

//Note that the doc-raw as well as the verbose v2g representation come from the dsV2Gwireshark plugin
//monitoring the communication between the EV and the EVSE in a typical EVerest ISO 15118-20 DC SIL session using config-sil-dc-d20
//The verbose v2g representation is not used in the tests, but is included for reference

/* V2G Message
WARNING: Preliminary ISO 15118-20 support!
Metadata
EXI: 808C0400000000000000000C9F9C2BD0620B2BA6A4AB1899199A1A9B1B9C1C9820A121A222AC00
Message: SessionSetupReq
Decoded XML […]: <?xml version="1.0" encoding="UTF-8"?><ns1:SessionSetupReq xmlns:ns1="urn:iso:std:iso:15118:-20:CommonMessages" xmlns:ns2="urn:iso:std:iso:15118:-20:CommonTypes"><ns2:Header><ns2:SessionID>0000000000000000</ns2:SessionID
Message Validation: Successful
Schema: urn:iso:std:iso:15118:-20:CommonMessages
SessionSetupReq
[XML Attributes: xmlns:ns1="urn:iso:std:iso:15118:-20:CommonMessages" xmlns:ns2="urn:iso:std:iso:15118:-20:CommonTypes"]
Header
SessionID: 0000000000000000
TimeStamp: 1739635913
EVCCID: WMIV1234567890ABCDEX */

/* unsigned char bytes[] = {0x80, 0x8c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x9f, 0x9c, 0x2b, 0xd0, 0x62, 0xb,
0x2b, 0xa6, 0xa4, 0xab, 0x18, 0x99, 0x19, 0x9a, 0x1a, 0x9b, 0x1b, 0x9c, 0x1c, 0x98, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xac, 0x0};
*/

/* V2G Message
WARNING: Preliminary ISO 15118-20 support!
Metadata
EXI: 809004177D0C4A6E3DC8088C9F9C2BD062040451114A9413960A914C4C8CCD0D4A8C40
Message: SessionSetupRes
Decoded XML […]: <?xml version="1.0" encoding="UTF-8"?><ns1:SessionSetupRes xmlns:ns1="urn:iso:std:iso:15118:-20:CommonMessages" xmlns:ns2="urn:iso:std:iso:15118:-20:CommonTypes"><ns2:Header><ns2:SessionID>2EFA1894DC7B9011</ns2:SessionID
Message Validation: Successful
Schema: urn:iso:std:iso:15118:-20:CommonMessages
SessionSetupRes
[XML Attributes: xmlns:ns1="urn:iso:std:iso:15118:-20:CommonMessages" xmlns:ns2="urn:iso:std:iso:15118:-20:CommonTypes"]
Header
SessionID: 2EFA1894DC7B9011
TimeStamp: 1739635913
ResponseCode: OK_NewSessionEstablished
EVSEID: DE*PNX*E12345*1
*/

/* unsigned char bytes[] = {0x80, 0x90, 0x4, 0x17, 0x7d, 0xc, 0x4a, 0x6e, 0x3d, 0xc8, 0x8, 0x8c, 0x9f, 0x9c, 0x2b, 0xd0, 0x62,
0x4, 0x4, 0x51, 0x11, 0x4a, 0x94, 0x13, 0x96, 0xa, 0x91, 0x4c, 0x4c, 0x8c, 0xcd, 0xd, 0x4a, 0x8c, 0x40}; */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course I understand why you need a Json/XML representation of the Exi stream for the unit tests. To write the tests, I used the Json message myself.
Nevertheless, I would not commit the Json/XML representation. Due to the individual catch2 assertions, there is a duplication with the Json/XML representation. Theoretically, you can read out how the Json/XML message is structured from the individual test steps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just following the advice of Moritz in Zulip... Personally, I like to have the comments so I can remember what is being tested. I imagine that a more complicated message might have more parameter combinations and more test cases, where these sort of comments could help keep things straight. maybe we can discuss in the car comm meeting?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, then lets have a discussion in the car WG meeting 👍



SCENARIO("Se/Deserialize session setup messages") {

GIVEN("Deserialize session_setup_req") {
uint8_t doc_raw[] = {0x80, 0x8c, 0x00, 0x80, 0x0d, 0x6c, 0xac, 0x3a, 0x60, 0x62, 0x0b,
0x2b, 0xa6, 0xa4, 0xab, 0x18, 0x99, 0x19, 0x9a, 0x1a, 0x9b, 0x1b,
0x9c, 0x1c, 0x98, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xac, 0x00};
uint8_t doc_raw[] = {0x80, 0x8c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x9f, 0x9c, 0x2b, 0xd0, 0x62, 0xb,
0x2b, 0xa6, 0xa4, 0xab, 0x18, 0x99, 0x19, 0x9a, 0x1a, 0x9b, 0x1b, 0x9c, 0x1c, 0x98, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xac, 0x0};

const io::StreamInputView stream_view{doc_raw, sizeof(doc_raw)};

message_20::Variant variant(io::v2gtp::PayloadType::Part20Main, stream_view);

THEN("It should be deserialized succussfully") {
THEN("It should be deserialized successfully") {
REQUIRE(variant.get_type() == message_20::Type::SessionSetupReq);

const auto& msg = variant.get<message_20::SessionSetupRequest>();
const auto& header = msg.header;

REQUIRE(header.session_id == std::array<uint8_t, 8>{0});
REQUIRE(header.timestamp == 1691411798);
REQUIRE(header.timestamp == 1739635913);

REQUIRE(msg.evccid == "WMIV1234567890ABCDEX");
}
}

GIVEN("Serialize session_setup_res") {

const auto header = message_20::Header{{0xF2, 0x19, 0x15, 0xB9, 0xDD, 0xDC, 0x12, 0xD1}, 1691411798};
const auto header = message_20::Header{{0x2E, 0xFA, 0x18, 0x94, 0xDC, 0x7B, 0x90, 0x11}, 1739635913};

const auto res = message_20::SessionSetupResponse{
header, message_20::datatypes::ResponseCode::OK_NewSessionEstablished, "UK123E1234"};
header, message_20::datatypes::ResponseCode::OK_NewSessionEstablished, "DE*PNX*E12345*1"};

std::vector<uint8_t> expected = {0x80, 0x90, 0x4, 0x17, 0x7d, 0xc, 0x4a, 0x6e, 0x3d, 0xc8, 0x8, 0x8c, 0x9f, 0x9c, 0x2b, 0xd0, 0x62,
0x4, 0x4, 0x51, 0x11, 0x4a, 0x94, 0x13, 0x96, 0xa, 0x91, 0x4c, 0x4c, 0x8c, 0xcd, 0xd, 0x4a, 0x8c, 0x40};

THEN("It should be serialized successfully") {
REQUIRE(serialize_helper(res) == expected);
}
}

GIVEN("Deserialize session_setup_res") {
uint8_t doc_raw[] = {0x80, 0x90, 0x4, 0x17, 0x7d, 0xc, 0x4a, 0x6e, 0x3d, 0xc8, 0x8, 0x8c, 0x9f, 0x9c, 0x2b, 0xd0, 0x62,
0x4, 0x4, 0x51, 0x11, 0x4a, 0x94, 0x13, 0x96, 0xa, 0x91, 0x4c, 0x4c, 0x8c, 0xcd, 0xd, 0x4a, 0x8c, 0x40};

const io::StreamInputView stream_view{doc_raw, sizeof(doc_raw)};

message_20::Variant variant(io::v2gtp::PayloadType::Part20Main, stream_view);

THEN("It should be deserialized successfully") {
REQUIRE(variant.get_type() == message_20::Type::SessionSetupRes);

const auto& msg = variant.get<message_20::SessionSetupResponse>();
const auto& header = msg.header;

REQUIRE(header.session_id == std::array<uint8_t, 8>{0x2E, 0xFA, 0x18, 0x94, 0xDC, 0x7B, 0x90, 0x11});
REQUIRE(header.timestamp == 1739635913);

REQUIRE(msg.evseid == "DE*PNX*E12345*1");
}
}

GIVEN("Serialize session_setup_req") {

const auto header = message_20::Header{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 1739635913};

std::vector<uint8_t> expected = {0x80, 0x90, 0x04, 0x79, 0x0c, 0x8a, 0xdc, 0xee, 0xee, 0x09,
0x68, 0x8d, 0x6c, 0xac, 0x3a, 0x60, 0x62, 0x04, 0x03, 0x15,
0x52, 0xcc, 0x4c, 0x8c, 0xd1, 0x4c, 0x4c, 0x8c, 0xcd, 0x00};
const auto res = message_20::SessionSetupRequest{
header, "WMIV1234567890ABCDEX"};

THEN("It should be serialized succussfully") {
std::vector<uint8_t> expected = {0x80, 0x8c, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x9f, 0x9c, 0x2b, 0xd0, 0x62, 0xb,
0x2b, 0xa6, 0xa4, 0xab, 0x18, 0x99, 0x19, 0x9a, 0x1a, 0x9b, 0x1b, 0x9c, 0x1c, 0x98, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xac, 0x0};
THEN("It should be serialized successfully") {
REQUIRE(serialize_helper(res) == expected);
}
}
Expand Down
Loading