Merge "VmsUtils: Add new methods to parse availability state messages" into qt-qpr1-dev

This commit is contained in:
Prachi Hande
2019-11-19 20:44:17 +00:00
committed by Android (Google) Code Review
3 changed files with 247 additions and 27 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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