VmsUtils: Update existing methods to parse subscriptions response messages.

Currently, we do not have a way to parse subscriptions response
messages. But we have parsing methods for SUBSCRIPTIONS_CHANGE type of
messages. These messages have the exact same payload as SUBSCRIPTIONS_RESPONSE
messages. So all we need to do is allow existing methods to parse
SUBSCRIPTIONS_RESPONSE messages along with SUBSCRIPTIONS_CHANGE
messages.

Bug: 138664881
Fixes: 138664881, 137955333
Test: Added more tests for the new message type. Ran tests on Hawk.
Change-Id: I53432e2215e03bb94fd36b7d62f42fe0be1994cf
This commit is contained in:
Prachi Hande 2019-08-05 13:17:09 -07:00
parent a2a5ead924
commit 4066574002
3 changed files with 115 additions and 57 deletions

View file

@ -153,7 +153,7 @@ std::unique_ptr<VehiclePropValue> createOfferingMessage(const VmsOffers& offers)
std::unique_ptr<VehiclePropValue> createAvailabilityRequest();
// Creates a VehiclePropValue containing a message of type
// VmsMessageType.AVAILABILITY_REQUEST.
// VmsMessageType.SUBSCRIPTIONS_REQUEST.
std::unique_ptr<VehiclePropValue> createSubscriptionsRequest();
// Creates a VehiclePropValue containing a message of type VmsMessageType.DATA.
@ -202,21 +202,21 @@ int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response);
// Returns true if the new sequence number is greater than the last seen
// sequence number.
bool isSequenceNumberNewer(const VehiclePropValue& subscription_change,
bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state,
const int last_seen_sequence_number);
// Returns sequence number of the message.
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change);
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state);
// Takes a subscription change message and returns the layers that have active
// Takes a subscriptions state message and returns the layers that have active
// subscriptions of the layers that are offered by your HAL client/publisher.
//
// A publisher can use this function when receiving a subscription change message
// to determine which layers to publish data on.
// A publisher can use this function when receiving a subscriptions response or subscriptions
// change message to determine which layers to publish data on.
// The caller of this function can optionally decide to not consume these layers
// if the subscription change has the sequence number less than the last seen
// sequence number.
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_change,
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_state,
const VmsOffers& offers);
// Takes an availability change message and returns true if the parsed message implies that

View file

@ -194,32 +194,35 @@ int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response)
return -1;
}
bool isSequenceNumberNewer(const VehiclePropValue& subscription_change,
bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state,
const int last_seen_sequence_number) {
return (isValidVmsMessage(subscription_change) &&
parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE &&
subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex &&
subscription_change.value.int32Values[kSubscriptionStateSequenceNumberIndex] >
return (isValidVmsMessage(subscriptions_state) &&
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex &&
subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex] >
last_seen_sequence_number);
}
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change) {
if (isValidVmsMessage(subscription_change) &&
parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE &&
subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
return subscription_change.value.int32Values[kSubscriptionStateSequenceNumberIndex];
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state) {
if (isValidVmsMessage(subscriptions_state) &&
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
return subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex];
}
return -1;
}
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_change,
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_state,
const VmsOffers& offers) {
if (isValidVmsMessage(subscription_change) &&
parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE &&
subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
const int32_t num_of_layers = subscription_change.value.int32Values[toInt(
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 = subscription_change.value.int32Values[toInt(
const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
VmsSubscriptionsStateIntegerValuesIndex ::NUMBER_OF_ASSOCIATED_LAYERS)];
std::unordered_set<VmsLayer, VmsLayer::VmsLayerHashFunction> offered_layers;
@ -231,9 +234,9 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_c
int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);
// Add all subscribed layers which are offered by the current publisher.
for (int i = 0; i < num_of_layers; i++) {
VmsLayer layer = VmsLayer(subscription_change.value.int32Values[current_index],
subscription_change.value.int32Values[current_index + 1],
subscription_change.value.int32Values[current_index + 2]);
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);
}
@ -243,15 +246,15 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_c
// 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(subscription_change.value.int32Values[current_index],
subscription_change.value.int32Values[current_index + 1],
subscription_change.value.int32Values[current_index + 2]);
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 = subscription_change.value.int32Values[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 (subscription_change.value.int32Values[current_index] ==
if (subscriptions_state.value.int32Values[current_index] ==
offers.publisher_id) {
subscribed_layers.push_back(layer);
}

View file

@ -214,57 +214,82 @@ TEST(VmsUtilsTest, invalidPublisherIdResponse) {
EXPECT_EQ(parsePublisherIdResponse(*message), -1);
}
TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsState) {
TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), 1234);
}
TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), 1234);
}
TEST(VmsUtilsTest, invalidSubscriptionsState) {
auto message = createBaseVmsMessage(1);
EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), -1);
}
TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumber) {
TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumberForChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_TRUE(isSequenceNumberNewer(*message, 1233));
}
TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumber) {
TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumberForResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_TRUE(isSequenceNumberNewer(*message, 1233));
}
TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumberForChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1235));
}
TEST(VmsUtilsTest, newSequenceNumberForSameNumber) {
TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumberForResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1235));
}
TEST(VmsUtilsTest, newSequenceNumberForSameNumberForChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1234));
}
TEST(VmsUtilsTest, subscribedLayers) {
TEST(VmsUtilsTest, newSequenceNumberForSameNumberForResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1234));
}
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);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
2, // number of layers
1, // number of associated layers
1, // layer 1
0,
1,
0, 1,
4, // layer 2
1,
1,
1, 1,
2, // associated layer
0,
1,
0, 1,
2, // number of publisher IDs
111, // publisher IDs
123};
@ -275,10 +300,18 @@ TEST(VmsUtilsTest, subscribedLayers) {
EXPECT_EQ(result.at(1), VmsLayer(2, 0, 1));
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtype) {
TEST(VmsUtilsTest, subscribedLayersForChange) {
testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersForResponse) {
testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
void testSubscribedLayersWithDifferentSubtype(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
1, // number of layers
0, // number of associated layers
@ -289,36 +322,58 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtype) {
EXPECT_TRUE(getSubscribedLayers(*message, offers).empty());
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentVersion) {
TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForChange) {
testSubscribedLayersWithDifferentSubtype(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForResponse) {
testSubscribedLayersWithDifferentSubtype(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
void subscribedLayersWithDifferentVersion(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
1234, // sequence number
1, // number of layers
0, // number of associated layers
1, // layer 1
0,
2}; // different version
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
1, // number of layers
0, // number of associated layers
1, // layer 1
0, 2}; // different version
EXPECT_TRUE(isValidVmsMessage(*message));
EXPECT_TRUE(getSubscribedLayers(*message, offers).empty());
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherId) {
TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForChange) {
subscribedLayersWithDifferentVersion(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForResponse) {
subscribedLayersWithDifferentVersion(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
void subscribedLayersWithDifferentPublisherId(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
0, // number of layers
1, // number of associated layers
1, // associated layer 1
0,
1,
0, 1,
1, // number of publisher IDs
234}; // publisher ID 1
EXPECT_TRUE(isValidVmsMessage(*message));
EXPECT_TRUE(getSubscribedLayers(*message, offers).empty());
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherIdForChange) {
subscribedLayersWithDifferentPublisherId(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherIdForResponse) {
subscribedLayersWithDifferentPublisherId(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
TEST(VmsUtilsTest, serviceNewlyStarted) {
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 0};