Skip to content

Commit 78a54ca

Browse files
authored
Service Discovery messages add EVSide Se/Deserialization (#91)
* Service Discovery messages add EVSide Se/Deserialization * Fixed a couple of things suggested by the pull request review. * Add unit tests with service_discovery_req/res vas_list * Changed all auto const to const auto Signed-off-by: Roger Bedell <rogerbedell@hotmail.com>
1 parent 8dce9d7 commit 78a54ca

File tree

3 files changed

+201
-5
lines changed

3 files changed

+201
-5
lines changed

src/iso15118/message/service_discovery.cpp

+67-2
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,60 @@ template <> void convert(const struct iso20_ServiceDiscoveryReqType& in, Service
2020
}
2121
}
2222

23+
template <> void convert(const struct iso20_ServiceDiscoveryResType& in, ServiceDiscoveryResponse& out) {
24+
25+
cb_convert_enum(in.ResponseCode, out.response_code);
26+
27+
out.service_renegotiation_supported = in.ServiceRenegotiationSupported;
28+
29+
// remove the default AC service
30+
out.energy_transfer_service_list.clear();
31+
out.energy_transfer_service_list.reserve(in.EnergyTransferServiceList.Service.arrayLen);
32+
33+
for (auto i = 0; i < in.EnergyTransferServiceList.Service.arrayLen; i++) {
34+
const auto& service = in.EnergyTransferServiceList.Service.array[i];
35+
auto& out_service = out.energy_transfer_service_list.emplace_back();
36+
cb_convert_enum(service.ServiceID, out_service.service_id);
37+
out_service.free_service = service.FreeService;
38+
}
39+
40+
if (in.VASList_isUsed) {
41+
42+
out.vas_list.emplace();
43+
out.vas_list->reserve(in.VASList.Service.arrayLen);
44+
45+
for (auto i = 0; i < in.VASList.Service.arrayLen; i++) {
46+
const auto& service = in.VASList.Service.array[i];
47+
auto& out_service = out.vas_list->emplace_back();
48+
cb_convert_enum(service.ServiceID, out_service.service_id);
49+
out_service.free_service = service.FreeService;
50+
}
51+
}
52+
53+
convert(in.Header, out.header);
54+
}
55+
56+
template <> void convert(const ServiceDiscoveryRequest& in, iso20_ServiceDiscoveryReqType& out) {
57+
init_iso20_ServiceDiscoveryReqType(&out);
58+
59+
if (in.supported_service_ids) {
60+
auto& out_service_ids = out.SupportedServiceIDs.ServiceID.array;
61+
const auto& supported_service_ids = in.supported_service_ids.value();
62+
std::copy(supported_service_ids.begin(), supported_service_ids.end(), out_service_ids);
63+
out.SupportedServiceIDs.ServiceID.arrayLen = supported_service_ids.size();
64+
CB_SET_USED(out.SupportedServiceIDs);
65+
}
66+
convert(in.header, out.Header);
67+
}
68+
2369
template <> void convert(const ServiceDiscoveryResponse& in, iso20_ServiceDiscoveryResType& out) {
2470
init_iso20_ServiceDiscoveryResType(&out);
2571

2672
cb_convert_enum(in.response_code, out.ResponseCode);
2773
out.ServiceRenegotiationSupported = in.service_renegotiation_supported;
2874

2975
uint8_t index = 0;
30-
for (auto const& service : in.energy_transfer_service_list) {
76+
for (const auto& service : in.energy_transfer_service_list) {
3177
auto& out_service = out.EnergyTransferServiceList.Service.array[index++];
3278
cb_convert_enum(service.service_id, out_service.ServiceID);
3379
out_service.FreeService = service.free_service;
@@ -36,7 +82,7 @@ template <> void convert(const ServiceDiscoveryResponse& in, iso20_ServiceDiscov
3682

3783
if (in.vas_list) {
3884
index = 0;
39-
for (auto const& service : *in.vas_list) {
85+
for (const auto& service : *in.vas_list) {
4086
auto& out_service = out.VASList.Service.array[index++];
4187
cb_convert_enum(service.service_id, out_service.ServiceID);
4288
out_service.FreeService = service.free_service;
@@ -52,6 +98,10 @@ template <> void insert_type(VariantAccess& va, const struct iso20_ServiceDiscov
5298
va.insert_type<ServiceDiscoveryRequest>(in);
5399
};
54100

101+
template <> void insert_type(VariantAccess& va, const struct iso20_ServiceDiscoveryResType& in) {
102+
va.insert_type<ServiceDiscoveryResponse>(in);
103+
};
104+
55105
template <> int serialize_to_exi(const ServiceDiscoveryResponse& in, exi_bitstream_t& out) {
56106
iso20_exiDocument doc;
57107
init_iso20_exiDocument(&doc);
@@ -63,8 +113,23 @@ template <> int serialize_to_exi(const ServiceDiscoveryResponse& in, exi_bitstre
63113
return encode_iso20_exiDocument(&out, &doc);
64114
}
65115

116+
template <> int serialize_to_exi(const ServiceDiscoveryRequest& in, exi_bitstream_t& out) {
117+
iso20_exiDocument doc;
118+
init_iso20_exiDocument(&doc);
119+
120+
CB_SET_USED(doc.ServiceDiscoveryReq);
121+
122+
convert(in, doc.ServiceDiscoveryReq);
123+
124+
return encode_iso20_exiDocument(&out, &doc);
125+
}
126+
66127
template <> size_t serialize(const ServiceDiscoveryResponse& in, const io::StreamOutputView& out) {
67128
return serialize_helper(in, out);
68129
}
69130

131+
template <> size_t serialize(const ServiceDiscoveryRequest& in, const io::StreamOutputView& out) {
132+
return serialize_helper(in, out);
133+
}
134+
70135
} // namespace iso15118::message_20

src/iso15118/message/variant.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ static void handle_main(VariantAccess& va) {
5858
insert_type(va, doc.AuthorizationRes);
5959
} else if (doc.ServiceDiscoveryReq_isUsed) {
6060
insert_type(va, doc.ServiceDiscoveryReq);
61+
} else if (doc.ServiceDiscoveryRes_isUsed) {
62+
insert_type(va, doc.ServiceDiscoveryRes);
6163
} else if (doc.ServiceDetailReq_isUsed) {
6264
insert_type(va, doc.ServiceDetailReq);
6365
} else if (doc.ServiceSelectionReq_isUsed) {

test/exi/cb/iso20/service_discovery.cpp

+132-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ SCENARIO("Se/Deserialize service_discovery messages") {
1818

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

21-
THEN("It should be decoded succussfully") {
21+
THEN("It should be decoded successfully") {
2222

2323
REQUIRE(variant.get_type() == message_20::Type::ServiceDiscoveryReq);
2424

@@ -30,7 +30,58 @@ SCENARIO("Se/Deserialize service_discovery messages") {
3030
}
3131
}
3232

33-
// TODO(sl): Adding test with service_discovery_req supported_service_ids
33+
GIVEN("Deserialize service_discovery_req_with_supported_service_ids") {
34+
35+
uint8_t doc_raw[] = {0x80, 0x7c, 0x04, 0x02, 0x75, 0xff, 0x96, 0x4a, 0x2c, 0xed,
36+
0xa1, 0x0e, 0x38, 0x7e, 0x8a, 0x60, 0x62, 0x00, 0x44};
37+
38+
const io::StreamInputView stream_view{doc_raw, sizeof(doc_raw)};
39+
40+
message_20::Variant variant(io::v2gtp::PayloadType::Part20Main, stream_view);
41+
42+
THEN("It should be decoded successfully") {
43+
44+
REQUIRE(variant.get_type() == message_20::Type::ServiceDiscoveryReq);
45+
46+
const auto& msg = variant.get<message_20::ServiceDiscoveryRequest>();
47+
const auto& header = msg.header;
48+
49+
REQUIRE(header.session_id == std::array<uint8_t, 8>{0x04, 0xEB, 0xFF, 0x2C, 0x94, 0x59, 0xDB, 0x42});
50+
REQUIRE(header.timestamp == 1692009443);
51+
REQUIRE(msg.supported_service_ids.has_value() == true);
52+
REQUIRE(msg.supported_service_ids.value().size() == 1);
53+
REQUIRE(msg.supported_service_ids.value()[0] == 2);
54+
}
55+
}
56+
57+
GIVEN("Serialize service_discovery_req") {
58+
59+
message_20::ServiceDiscoveryRequest req;
60+
61+
req.header = message_20::Header{{0x04, 0xEB, 0xFF, 0x2C, 0x94, 0x59, 0xDB, 0x42}, 1692009443};
62+
63+
std::vector<uint8_t> expected = {0x80, 0x7c, 0x04, 0x02, 0x75, 0xff, 0x96, 0x4a, 0x2c,
64+
0xed, 0xa1, 0x0e, 0x38, 0x7e, 0x8a, 0x60, 0x62, 0x80};
65+
66+
THEN("It should be serialized successfully") {
67+
REQUIRE(serialize_helper(req) == expected);
68+
}
69+
}
70+
71+
GIVEN("Serialize service_discovery_req_with_supported_service_ids") {
72+
73+
message_20::ServiceDiscoveryRequest req;
74+
75+
req.header = message_20::Header{{0x04, 0xEB, 0xFF, 0x2C, 0x94, 0x59, 0xDB, 0x42}, 1692009443};
76+
req.supported_service_ids = {2};
77+
78+
std::vector<uint8_t> expected = {0x80, 0x7c, 0x04, 0x02, 0x75, 0xff, 0x96, 0x4a, 0x2c, 0xed,
79+
0xa1, 0x0e, 0x38, 0x7e, 0x8a, 0x60, 0x62, 0x00, 0x44};
80+
81+
THEN("It should be serialized successfully") {
82+
REQUIRE(serialize_helper(req) == expected);
83+
}
84+
}
3485

3586
GIVEN("Serialize service_discovery_res") {
3687

@@ -45,8 +96,86 @@ SCENARIO("Se/Deserialize service_discovery messages") {
4596
std::vector<uint8_t> expected = {0x80, 0x80, 0x04, 0x1e, 0xa6, 0x5f, 0xc9, 0x9b, 0xa7, 0x6c, 0x4d, 0x8c,
4697
0x2b, 0xfe, 0x1b, 0x60, 0x62, 0x00, 0x00, 0x02, 0x00, 0x01, 0x80, 0x50};
4798

48-
THEN("It should be serialized succussfully") {
99+
THEN("It should be serialized successfully") {
100+
REQUIRE(serialize_helper(res) == expected);
101+
}
102+
}
103+
104+
GIVEN("Serialize service_discovery_res_with_vas_list") {
105+
106+
message_20::ServiceDiscoveryResponse res;
107+
108+
res.header = message_20::Header{{0x3D, 0x4C, 0xBF, 0x93, 0x37, 0x4E, 0xD8, 0x9B}, 1725456322};
109+
res.response_code = message_20::datatypes::ResponseCode::OK;
110+
res.service_renegotiation_supported = false;
111+
res.energy_transfer_service_list = {{message_20::datatypes::ServiceCategory::DC, false},
112+
{message_20::datatypes::ServiceCategory::DC_BPT, false}};
113+
res.vas_list = {{message_20::datatypes::ServiceCategory::Internet, true}};
114+
115+
std::vector<uint8_t> expected = {0x80, 0x80, 0x04, 0x1e, 0xa6, 0x5f, 0xc9, 0x9b, 0xa7, 0x6c, 0x4d, 0x8c, 0x2b,
116+
0xfe, 0x1b, 0x60, 0x62, 0x00, 0x00, 0x02, 0x00, 0x01, 0x80, 0x40, 0x82, 0x22};
117+
118+
THEN("It should be serialized successfully") {
49119
REQUIRE(serialize_helper(res) == expected);
50120
}
51121
}
122+
123+
GIVEN("Deserialize service_discovery_res") {
124+
125+
uint8_t doc_raw[] = {0x80, 0x80, 0x04, 0x1e, 0xa6, 0x5f, 0xc9, 0x9b, 0xa7, 0x6c, 0x4d, 0x8c,
126+
0x2b, 0xfe, 0x1b, 0x60, 0x62, 0x00, 0x00, 0x02, 0x00, 0x01, 0x80, 0x50};
127+
128+
const io::StreamInputView stream_view{doc_raw, sizeof(doc_raw)};
129+
130+
message_20::Variant variant(io::v2gtp::PayloadType::Part20Main, stream_view);
131+
132+
THEN("It should be decoded successfully") {
133+
134+
REQUIRE(variant.get_type() == message_20::Type::ServiceDiscoveryRes);
135+
136+
const auto& msg = variant.get<message_20::ServiceDiscoveryResponse>();
137+
const auto& header = msg.header;
138+
139+
REQUIRE(header.session_id == std::array<uint8_t, 8>{0x3D, 0x4C, 0xBF, 0x93, 0x37, 0x4E, 0xD8, 0x9B});
140+
REQUIRE(header.timestamp == 1725456322);
141+
REQUIRE(msg.response_code == message_20::datatypes::ResponseCode::OK);
142+
REQUIRE(msg.service_renegotiation_supported == false);
143+
REQUIRE(msg.energy_transfer_service_list.size() == 2);
144+
REQUIRE(msg.energy_transfer_service_list[0].service_id == message_20::datatypes::ServiceCategory::DC);
145+
REQUIRE(msg.energy_transfer_service_list[0].free_service == false);
146+
REQUIRE(msg.energy_transfer_service_list[1].service_id == message_20::datatypes::ServiceCategory::DC_BPT);
147+
REQUIRE(msg.energy_transfer_service_list[1].free_service == false);
148+
}
149+
}
150+
151+
GIVEN("Deserialize service_discovery_res_with_vas_list") {
152+
153+
uint8_t doc_raw[] = {0x80, 0x80, 0x04, 0x1e, 0xa6, 0x5f, 0xc9, 0x9b, 0xa7, 0x6c, 0x4d, 0x8c, 0x2b,
154+
0xfe, 0x1b, 0x60, 0x62, 0x00, 0x00, 0x02, 0x00, 0x01, 0x80, 0x40, 0x82, 0x22};
155+
156+
const io::StreamInputView stream_view{doc_raw, sizeof(doc_raw)};
157+
158+
message_20::Variant variant(io::v2gtp::PayloadType::Part20Main, stream_view);
159+
160+
THEN("It should be decoded successfully") {
161+
162+
REQUIRE(variant.get_type() == message_20::Type::ServiceDiscoveryRes);
163+
164+
const auto& msg = variant.get<message_20::ServiceDiscoveryResponse>();
165+
const auto& header = msg.header;
166+
167+
REQUIRE(header.session_id == std::array<uint8_t, 8>{0x3D, 0x4C, 0xBF, 0x93, 0x37, 0x4E, 0xD8, 0x9B});
168+
REQUIRE(header.timestamp == 1725456322);
169+
REQUIRE(msg.response_code == message_20::datatypes::ResponseCode::OK);
170+
REQUIRE(msg.service_renegotiation_supported == false);
171+
REQUIRE(msg.energy_transfer_service_list.size() == 2);
172+
REQUIRE(msg.energy_transfer_service_list[0].service_id == message_20::datatypes::ServiceCategory::DC);
173+
REQUIRE(msg.energy_transfer_service_list[0].free_service == false);
174+
REQUIRE(msg.energy_transfer_service_list[1].service_id == message_20::datatypes::ServiceCategory::DC_BPT);
175+
REQUIRE(msg.energy_transfer_service_list[1].free_service == false);
176+
REQUIRE(msg.vas_list.value().size() == 1);
177+
REQUIRE(msg.vas_list.value()[0].service_id == message_20::datatypes::ServiceCategory::Internet);
178+
REQUIRE(msg.vas_list.value()[0].free_service == true);
179+
}
180+
}
52181
}

0 commit comments

Comments
 (0)