Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbce8697 authored by Prachi Hande's avatar Prachi Hande
Browse files

VmsUtils: Add new methods to parse availability state messages

These methods are needed in the HAL client to parse sequence number and
associated layers when the availablity of the VMS layers change.
HAL client relies on these messages by either explicitly requesting the
availability or through availability change message sent by the Car
service.

Bug: 144434783
Fixes: 144434783

Test: Added new tests for the new methods. Ran the tests on Hawk.
Change-Id: I09497640367a894e1dfb6143ac3bbdb63d64b53e
parent 2b7fefdc
Loading
Loading
Loading
Loading
+23 −3
Original line number Original line Diff line number Diff line
@@ -61,7 +61,7 @@ struct VmsLayer {


struct VmsLayerAndPublisher {
struct VmsLayerAndPublisher {
    VmsLayerAndPublisher(VmsLayer layer, int publisher_id)
    VmsLayerAndPublisher(VmsLayer layer, int publisher_id)
        : layer(layer), publisher_id(publisher_id) {}
        : layer(std::move(layer)), publisher_id(publisher_id) {}
    VmsLayer layer;
    VmsLayer layer;
    int publisher_id;
    int publisher_id;
};
};
@@ -69,6 +69,8 @@ struct VmsLayerAndPublisher {
// A VmsAssociatedLayer is used by subscribers to specify which publisher IDs
// A VmsAssociatedLayer is used by subscribers to specify which publisher IDs
// are acceptable for a given layer.
// are acceptable for a given layer.
struct VmsAssociatedLayer {
struct VmsAssociatedLayer {
    VmsAssociatedLayer(VmsLayer layer, std::vector<int> publisher_ids)
        : layer(std::move(layer)), publisher_ids(std::move(publisher_ids)) {}
    VmsLayer layer;
    VmsLayer layer;
    std::vector<int> publisher_ids;
    std::vector<int> publisher_ids;
};
};
@@ -77,7 +79,7 @@ struct VmsAssociatedLayer {
// its dependencies. Dependencies can be empty.
// its dependencies. Dependencies can be empty.
struct VmsLayerOffering {
struct VmsLayerOffering {
    VmsLayerOffering(VmsLayer layer, std::vector<VmsLayer> dependencies)
    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() {}
    VmsLayerOffering(VmsLayer layer) : layer(layer), dependencies() {}
    VmsLayer layer;
    VmsLayer layer;
    std::vector<VmsLayer> dependencies;
    std::vector<VmsLayer> dependencies;
@@ -87,7 +89,7 @@ struct VmsLayerOffering {
// with the specified publisher ID.
// with the specified publisher ID.
struct VmsOffers {
struct VmsOffers {
    VmsOffers(int publisher_id, std::vector<VmsLayerOffering> offerings)
    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;
    int publisher_id;
    std::vector<VmsLayerOffering> offerings;
    std::vector<VmsLayerOffering> offerings;
};
};
@@ -231,6 +233,24 @@ VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
                                          const int current_service_id, const int current_client_id,
                                          const int current_service_id, const int current_client_id,
                                          int* new_service_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 vms
}  // namespace V2_0
}  // namespace V2_0
}  // namespace vehicle
}  // namespace vehicle
+94 −20
Original line number Original line Diff line number Diff line
@@ -219,12 +219,9 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_
    if (isValidVmsMessage(subscriptions_state) &&
    if (isValidVmsMessage(subscriptions_state) &&
        (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
        (parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
         parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
         parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
        subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
        subscriptions_state.value.int32Values.size() >
        const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
                toInt(VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)) {
                VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
        int subscriptions_state_int_size = subscriptions_state.value.int32Values.size();
        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;
        std::unordered_set<VmsLayer, VmsLayer::VmsLayerHashFunction> offered_layers;
        for (const auto& offer : offers.offerings) {
        for (const auto& offer : offers.offerings) {
            offered_layers.insert(offer.layer);
            offered_layers.insert(offer.layer);
@@ -232,36 +229,55 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_
        std::vector<VmsLayer> subscribed_layers;
        std::vector<VmsLayer> subscribed_layers;


        int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);
        int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);

        // Add all subscribed layers which are offered by the current publisher.
        // 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++) {
        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],
            VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
                                      subscriptions_state.value.int32Values[current_index + 1],
                                      subscriptions_state.value.int32Values[current_index + 1],
                                      subscriptions_state.value.int32Values[current_index + 2]);
                                      subscriptions_state.value.int32Values[current_index + 2]);
            if (offered_layers.find(layer) != offered_layers.end()) {
            if (offered_layers.find(layer) != offered_layers.end()) {
                subscribed_layers.push_back(layer);
                subscribed_layers.push_back(std::move(layer));
            }
            }
            current_index += kLayerSize;
            current_index += kLayerSize;
        }
        }

        // Add all subscribed associated layers which are offered by the current publisher.
        // 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
        // For this, we need to check if the associated layer has a publisher ID which is
        // same as that of the current publisher.
        // same as that of the current publisher.
        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++) {
            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],
                VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
                                          subscriptions_state.value.int32Values[current_index + 1],
                                          subscriptions_state.value.int32Values[current_index + 1],
                                          subscriptions_state.value.int32Values[current_index + 2]);
                                          subscriptions_state.value.int32Values[current_index + 2]);
                current_index += kLayerSize;
                current_index += kLayerSize;
            if (offered_layers.find(layer) != offered_layers.end()) {
                if (offered_layers.find(layer) != offered_layers.end() &&
                int32_t num_of_publisher_ids = subscriptions_state.value.int32Values[current_index];
                    subscriptions_state_int_size > current_index) {
                    int32_t num_of_publisher_ids =
                            subscriptions_state.value.int32Values[current_index];
                    current_index++;
                    current_index++;
                    for (int j = 0; j < num_of_publisher_ids; j++) {
                    for (int j = 0; j < num_of_publisher_ids; j++) {
                    if (subscriptions_state.value.int32Values[current_index] ==
                        if (subscriptions_state_int_size > current_index &&
                            subscriptions_state.value.int32Values[current_index] ==
                                    offers.publisher_id) {
                                    offers.publisher_id) {
                        subscribed_layers.push_back(layer);
                            subscribed_layers.push_back(std::move(layer));
                        }
                        }
                        current_index++;
                        current_index++;
                    }
                    }
                }
                }
            }
            }
        }
        return subscribed_layers;
        return subscribed_layers;
    }
    }
    return {};
    return {};
@@ -300,6 +316,64 @@ VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
    return VmsSessionStatus::kInvalidMessage;
    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 vms
}  // namespace V2_0
}  // namespace V2_0
}  // namespace vehicle
}  // namespace vehicle
+130 −4
Original line number Original line Diff line number Diff line
@@ -279,7 +279,7 @@ void testSubscribedLayers(VmsMessageType type) {
    VmsOffers offers = {123,
    VmsOffers offers = {123,
                        {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
                        {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
                         VmsLayerOffering(VmsLayer(2, 0, 1))}};
                         VmsLayerOffering(VmsLayer(2, 0, 1))}};
    auto message = createBaseVmsMessage(2);
    auto message = createBaseVmsMessage(16);
    message->value.int32Values = hidl_vec<int32_t>{toInt(type),
    message->value.int32Values = hidl_vec<int32_t>{toInt(type),
                                                   1234,  // sequence number
                                                   1234,  // sequence number
                                                   2,     // number of layers
                                                   2,     // number of layers
@@ -308,9 +308,28 @@ TEST(VmsUtilsTest, subscribedLayersForResponse) {
    testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
    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) {
void testSubscribedLayersWithDifferentSubtype(VmsMessageType type) {
    VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
    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),
    message->value.int32Values = hidl_vec<int32_t>{toInt(type),
                                                   1234,  // sequence number
                                                   1234,  // sequence number
                                                   1,     // number of layers
                                                   1,     // number of layers
@@ -332,7 +351,7 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForResponse) {


void subscribedLayersWithDifferentVersion(VmsMessageType type) {
void subscribedLayersWithDifferentVersion(VmsMessageType type) {
    VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
    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),
    message->value.int32Values = hidl_vec<int32_t>{toInt(type),
                                                   1234,             // sequence number
                                                   1234,             // sequence number
                                                   1,                // number of layers
                                                   1,                // number of layers
@@ -353,7 +372,7 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForResponse) {


void subscribedLayersWithDifferentPublisherId(VmsMessageType type) {
void subscribedLayersWithDifferentPublisherId(VmsMessageType type) {
    VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
    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),
    message->value.int32Values = hidl_vec<int32_t>{toInt(type),
                                                   1234,  // sequence number
                                                   1234,  // sequence number
                                                   0,     // number of layers
                                                   0,     // number of layers
@@ -475,6 +494,113 @@ TEST(VmsUtilsTest, startSessionInvalidMessageFormat) {
    EXPECT_EQ(new_service_id, 123);
    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


}  // namespace vms
}  // namespace vms