mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "VmsUtils: Add new methods to parse availability state messages" into qt-qpr1-dev
This commit is contained in:
@@ -61,7 +61,7 @@ struct VmsLayer {
|
||||
|
||||
struct VmsLayerAndPublisher {
|
||||
VmsLayerAndPublisher(VmsLayer layer, int publisher_id)
|
||||
: layer(layer), publisher_id(publisher_id) {}
|
||||
: layer(std::move(layer)), publisher_id(publisher_id) {}
|
||||
VmsLayer layer;
|
||||
int publisher_id;
|
||||
};
|
||||
@@ -69,6 +69,8 @@ struct VmsLayerAndPublisher {
|
||||
// A VmsAssociatedLayer is used by subscribers to specify which publisher IDs
|
||||
// are acceptable for a given layer.
|
||||
struct VmsAssociatedLayer {
|
||||
VmsAssociatedLayer(VmsLayer layer, std::vector<int> publisher_ids)
|
||||
: layer(std::move(layer)), publisher_ids(std::move(publisher_ids)) {}
|
||||
VmsLayer layer;
|
||||
std::vector<int> publisher_ids;
|
||||
};
|
||||
@@ -77,7 +79,7 @@ struct VmsAssociatedLayer {
|
||||
// its dependencies. Dependencies can be empty.
|
||||
struct VmsLayerOffering {
|
||||
VmsLayerOffering(VmsLayer layer, std::vector<VmsLayer> dependencies)
|
||||
: layer(layer), dependencies(dependencies) {}
|
||||
: layer(std::move(layer)), dependencies(std::move(dependencies)) {}
|
||||
VmsLayerOffering(VmsLayer layer) : layer(layer), dependencies() {}
|
||||
VmsLayer layer;
|
||||
std::vector<VmsLayer> dependencies;
|
||||
@@ -87,7 +89,7 @@ struct VmsLayerOffering {
|
||||
// with the specified publisher ID.
|
||||
struct VmsOffers {
|
||||
VmsOffers(int publisher_id, std::vector<VmsLayerOffering> offerings)
|
||||
: publisher_id(publisher_id), offerings(offerings) {}
|
||||
: publisher_id(publisher_id), offerings(std::move(offerings)) {}
|
||||
int publisher_id;
|
||||
std::vector<VmsLayerOffering> offerings;
|
||||
};
|
||||
@@ -231,6 +233,24 @@ VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
|
||||
const int current_service_id, const int current_client_id,
|
||||
int* new_service_id);
|
||||
|
||||
// Returns true if the new sequence number of the availability state message is greater than
|
||||
// the last seen availability sequence number.
|
||||
bool isAvailabilitySequenceNumberNewer(const VehiclePropValue& availability_state,
|
||||
const int last_seen_availability_sequence_number);
|
||||
|
||||
// Returns sequence number of the availability state message.
|
||||
int32_t getSequenceNumberForAvailabilityState(const VehiclePropValue& availability_state);
|
||||
|
||||
// Takes a availability state message and returns the associated layers that are
|
||||
// available to publish data.
|
||||
//
|
||||
// A subscriber can use this function when receiving an availability response or availability
|
||||
// change message to determine which associated layers are ready to publish data.
|
||||
// The caller of this function can optionally decide to not consume these layers
|
||||
// if the availability change has the sequence number less than the last seen
|
||||
// sequence number.
|
||||
std::vector<VmsAssociatedLayer> getAvailableLayers(const VehiclePropValue& availability_state);
|
||||
|
||||
} // namespace vms
|
||||
} // namespace V2_0
|
||||
} // namespace vehicle
|
||||
|
||||
@@ -219,12 +219,9 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_
|
||||
if (isValidVmsMessage(subscriptions_state) &&
|
||||
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
|
||||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
|
||||
subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
|
||||
const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
|
||||
VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
|
||||
const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
|
||||
VmsSubscriptionsStateIntegerValuesIndex ::NUMBER_OF_ASSOCIATED_LAYERS)];
|
||||
|
||||
subscriptions_state.value.int32Values.size() >
|
||||
toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)) {
|
||||
int subscriptions_state_int_size = subscriptions_state.value.int32Values.size();
|
||||
std::unordered_set<VmsLayer, VmsLayer::VmsLayerHashFunction> offered_layers;
|
||||
for (const auto& offer : offers.offerings) {
|
||||
offered_layers.insert(offer.layer);
|
||||
@@ -232,33 +229,52 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_
|
||||
std::vector<VmsLayer> subscribed_layers;
|
||||
|
||||
int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);
|
||||
|
||||
// Add all subscribed layers which are offered by the current publisher.
|
||||
const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
|
||||
VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
|
||||
for (int i = 0; i < num_of_layers; i++) {
|
||||
if (subscriptions_state_int_size < current_index + kLayerSize) {
|
||||
return {};
|
||||
}
|
||||
VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
|
||||
subscriptions_state.value.int32Values[current_index + 1],
|
||||
subscriptions_state.value.int32Values[current_index + 2]);
|
||||
if (offered_layers.find(layer) != offered_layers.end()) {
|
||||
subscribed_layers.push_back(layer);
|
||||
subscribed_layers.push_back(std::move(layer));
|
||||
}
|
||||
current_index += kLayerSize;
|
||||
}
|
||||
|
||||
// Add all subscribed associated layers which are offered by the current publisher.
|
||||
// For this, we need to check if the associated layer has a publisher ID which is
|
||||
// same as that of the current publisher.
|
||||
for (int i = 0; i < num_of_associated_layers; i++) {
|
||||
VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
|
||||
subscriptions_state.value.int32Values[current_index + 1],
|
||||
subscriptions_state.value.int32Values[current_index + 2]);
|
||||
current_index += kLayerSize;
|
||||
if (offered_layers.find(layer) != offered_layers.end()) {
|
||||
int32_t num_of_publisher_ids = subscriptions_state.value.int32Values[current_index];
|
||||
current_index++;
|
||||
for (int j = 0; j < num_of_publisher_ids; j++) {
|
||||
if (subscriptions_state.value.int32Values[current_index] ==
|
||||
offers.publisher_id) {
|
||||
subscribed_layers.push_back(layer);
|
||||
}
|
||||
if (subscriptions_state_int_size >
|
||||
toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)) {
|
||||
const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
|
||||
VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)];
|
||||
|
||||
for (int i = 0; i < num_of_associated_layers; i++) {
|
||||
if (subscriptions_state_int_size < current_index + kLayerSize) {
|
||||
return {};
|
||||
}
|
||||
VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
|
||||
subscriptions_state.value.int32Values[current_index + 1],
|
||||
subscriptions_state.value.int32Values[current_index + 2]);
|
||||
current_index += kLayerSize;
|
||||
if (offered_layers.find(layer) != offered_layers.end() &&
|
||||
subscriptions_state_int_size > current_index) {
|
||||
int32_t num_of_publisher_ids =
|
||||
subscriptions_state.value.int32Values[current_index];
|
||||
current_index++;
|
||||
for (int j = 0; j < num_of_publisher_ids; j++) {
|
||||
if (subscriptions_state_int_size > current_index &&
|
||||
subscriptions_state.value.int32Values[current_index] ==
|
||||
offers.publisher_id) {
|
||||
subscribed_layers.push_back(std::move(layer));
|
||||
}
|
||||
current_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,6 +316,64 @@ VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
|
||||
return VmsSessionStatus::kInvalidMessage;
|
||||
}
|
||||
|
||||
bool isAvailabilitySequenceNumberNewer(const VehiclePropValue& availability_state,
|
||||
const int last_seen_availability_sequence_number) {
|
||||
return (isValidVmsMessage(availability_state) &&
|
||||
(parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
|
||||
parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
|
||||
availability_state.value.int32Values.size() > kAvailabilitySequenceNumberIndex &&
|
||||
availability_state.value.int32Values[kAvailabilitySequenceNumberIndex] >
|
||||
last_seen_availability_sequence_number);
|
||||
}
|
||||
|
||||
int32_t getSequenceNumberForAvailabilityState(const VehiclePropValue& availability_state) {
|
||||
if (isValidVmsMessage(availability_state) &&
|
||||
(parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
|
||||
parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
|
||||
availability_state.value.int32Values.size() > kAvailabilitySequenceNumberIndex) {
|
||||
return availability_state.value.int32Values[kAvailabilitySequenceNumberIndex];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<VmsAssociatedLayer> getAvailableLayers(const VehiclePropValue& availability_state) {
|
||||
if (isValidVmsMessage(availability_state) &&
|
||||
(parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_CHANGE ||
|
||||
parseMessageType(availability_state) == VmsMessageType::AVAILABILITY_RESPONSE) &&
|
||||
availability_state.value.int32Values.size() >
|
||||
toInt(VmsAvailabilityStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)) {
|
||||
int availability_state_int_size = availability_state.value.int32Values.size();
|
||||
const int32_t num_of_associated_layers = availability_state.value.int32Values[toInt(
|
||||
VmsAvailabilityStateIntegerValuesIndex::NUMBER_OF_ASSOCIATED_LAYERS)];
|
||||
int current_index = toInt(VmsAvailabilityStateIntegerValuesIndex::LAYERS_START);
|
||||
std::vector<VmsAssociatedLayer> available_layers;
|
||||
for (int i = 0; i < num_of_associated_layers; i++) {
|
||||
if (availability_state_int_size < current_index + kLayerSize) {
|
||||
return {};
|
||||
}
|
||||
VmsLayer layer = VmsLayer(availability_state.value.int32Values[current_index],
|
||||
availability_state.value.int32Values[current_index + 1],
|
||||
availability_state.value.int32Values[current_index + 2]);
|
||||
current_index += kLayerSize;
|
||||
std::vector<int> publisher_ids;
|
||||
if (availability_state_int_size > current_index) {
|
||||
int32_t num_of_publisher_ids = availability_state.value.int32Values[current_index];
|
||||
current_index++;
|
||||
for (int j = 0; j < num_of_publisher_ids; j++) {
|
||||
if (availability_state_int_size > current_index) {
|
||||
publisher_ids.push_back(
|
||||
availability_state.value.int32Values[current_index]);
|
||||
current_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
available_layers.emplace_back(layer, std::move(publisher_ids));
|
||||
}
|
||||
return available_layers;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace vms
|
||||
} // namespace V2_0
|
||||
} // namespace vehicle
|
||||
|
||||
@@ -279,7 +279,7 @@ void testSubscribedLayers(VmsMessageType type) {
|
||||
VmsOffers offers = {123,
|
||||
{VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
|
||||
VmsLayerOffering(VmsLayer(2, 0, 1))}};
|
||||
auto message = createBaseVmsMessage(2);
|
||||
auto message = createBaseVmsMessage(16);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
|
||||
1234, // sequence number
|
||||
2, // number of layers
|
||||
@@ -308,9 +308,28 @@ TEST(VmsUtilsTest, subscribedLayersForResponse) {
|
||||
testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
|
||||
}
|
||||
|
||||
void testGetSubscribedLayersMalformedData(VmsMessageType type) {
|
||||
VmsOffers offers = {123,
|
||||
{VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
|
||||
VmsLayerOffering(VmsLayer(2, 0, 1))}};
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type), 1234}; // sequence number
|
||||
EXPECT_TRUE(isValidVmsMessage(*message));
|
||||
auto result = getSubscribedLayers(*message, offers);
|
||||
EXPECT_EQ(static_cast<int>(result.size()), 0);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, subscribedLayersForMalformedChange) {
|
||||
testGetSubscribedLayersMalformedData(VmsMessageType::SUBSCRIPTIONS_CHANGE);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, subscribedLayersForMalformedResponse) {
|
||||
testGetSubscribedLayersMalformedData(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
|
||||
}
|
||||
|
||||
void testSubscribedLayersWithDifferentSubtype(VmsMessageType type) {
|
||||
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
|
||||
auto message = createBaseVmsMessage(2);
|
||||
auto message = createBaseVmsMessage(7);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
|
||||
1234, // sequence number
|
||||
1, // number of layers
|
||||
@@ -332,7 +351,7 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForResponse) {
|
||||
|
||||
void subscribedLayersWithDifferentVersion(VmsMessageType type) {
|
||||
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
|
||||
auto message = createBaseVmsMessage(2);
|
||||
auto message = createBaseVmsMessage(7);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
|
||||
1234, // sequence number
|
||||
1, // number of layers
|
||||
@@ -353,7 +372,7 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForResponse) {
|
||||
|
||||
void subscribedLayersWithDifferentPublisherId(VmsMessageType type) {
|
||||
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
|
||||
auto message = createBaseVmsMessage(2);
|
||||
auto message = createBaseVmsMessage(9);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
|
||||
1234, // sequence number
|
||||
0, // number of layers
|
||||
@@ -475,6 +494,113 @@ TEST(VmsUtilsTest, startSessionInvalidMessageFormat) {
|
||||
EXPECT_EQ(new_service_id, 123);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingSmallerNumberForChange) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
|
||||
EXPECT_TRUE(isAvailabilitySequenceNumberNewer(*message, 1233));
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingSmallerNumberForResponse) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
|
||||
EXPECT_TRUE(isAvailabilitySequenceNumberNewer(*message, 1233));
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingGreaterNumberForChange) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
|
||||
EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1235));
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, newAvailabilitySequenceNumberForExistingGreaterNumberForResponse) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
|
||||
EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1235));
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, newAvailabilitySequenceNumberForSameNumberForChange) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
|
||||
EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1234));
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, newAvailabilitySequenceNumberForSameNumberForResponse) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
|
||||
EXPECT_FALSE(isAvailabilitySequenceNumberNewer(*message, 1234));
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, validSequenceNumberForAvailabilityChange) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 1234};
|
||||
EXPECT_EQ(getSequenceNumberForAvailabilityState(*message), 1234);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, validSequenceNumberForAvailabilityResponse) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values =
|
||||
hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_RESPONSE), 1234};
|
||||
EXPECT_EQ(getSequenceNumberForAvailabilityState(*message), 1234);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, invalidAvailabilityState) {
|
||||
auto message = createBaseVmsMessage(1);
|
||||
EXPECT_EQ(getSequenceNumberForAvailabilityState(*message), -1);
|
||||
}
|
||||
|
||||
void testGetAvailableLayers(VmsMessageType type) {
|
||||
auto message = createBaseVmsMessage(13);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
|
||||
1234, // sequence number
|
||||
2, // number of associated layers
|
||||
1, // associated layer 1
|
||||
0, 1,
|
||||
2, // number of publisher IDs
|
||||
111, // publisher IDs
|
||||
123,
|
||||
2, // associated layer 2
|
||||
0, 1, 0}; // number of publisher IDs
|
||||
EXPECT_TRUE(isValidVmsMessage(*message));
|
||||
auto result = getAvailableLayers(*message);
|
||||
EXPECT_EQ(static_cast<int>(result.size()), 2);
|
||||
EXPECT_EQ(result.at(0).layer, VmsLayer(1, 0, 1));
|
||||
EXPECT_EQ(result.at(0).publisher_ids.at(0), 111);
|
||||
EXPECT_EQ(result.at(0).publisher_ids.at(1), 123);
|
||||
EXPECT_EQ(result.at(1).layer, VmsLayer(2, 0, 1));
|
||||
EXPECT_EQ(static_cast<int>(result.at(1).publisher_ids.size()), 0);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, availableLayersForChange) {
|
||||
testGetAvailableLayers(VmsMessageType::AVAILABILITY_CHANGE);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, availableLayersForResponse) {
|
||||
testGetAvailableLayers(VmsMessageType::AVAILABILITY_RESPONSE);
|
||||
}
|
||||
|
||||
void testGetAvailableLayersMalformedData(VmsMessageType type) {
|
||||
auto message = createBaseVmsMessage(2);
|
||||
message->value.int32Values = hidl_vec<int32_t>{toInt(type), 1234}; // sequence number
|
||||
EXPECT_TRUE(isValidVmsMessage(*message));
|
||||
auto result = getAvailableLayers(*message);
|
||||
EXPECT_EQ(static_cast<int>(result.size()), 0);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, availableLayersForMalformedChange) {
|
||||
testGetAvailableLayersMalformedData(VmsMessageType::AVAILABILITY_CHANGE);
|
||||
}
|
||||
|
||||
TEST(VmsUtilsTest, availableLayersForMalformedResponse) {
|
||||
testGetAvailableLayersMalformedData(VmsMessageType::AVAILABILITY_RESPONSE);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace vms
|
||||
|
||||
Reference in New Issue
Block a user