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

Commit 991f3e8a authored by Prachi Hande's avatar Prachi Hande Committed by android-build-merger
Browse files

Merge "Add utility methods to create and parse handshake messages." into qt-dev

am: c62ce9d6

Change-Id: I1afa87ebfbf90e630e082061c84eb00e32a6ca36
parents abad4f5a c62ce9d6
Loading
Loading
Loading
Loading
+35 −7
Original line number Diff line number Diff line
@@ -105,6 +105,24 @@ struct VmsAvailabilityState {
    std::vector<VmsAssociatedLayer> associated_layers;
};

// An enum to represent the result of parsing START_SESSION message from the VMS service.
enum VmsSessionStatus {
    // New server session is received if the new client ID is -1 and the new server ID is not an
    // invalid ID.
    kNewServerSession,
    // Ack to new client session is received if the new client ID is same as the old one and the new
    // server ID is not an invalid ID.
    kAckToNewClientSession,
    // Error codes:
    // Invalid message with either invalid format or unexpected data.
    kInvalidMessage,
    // Invalid server ID. New ID should always be greater than or equal to max_of(0, current server
    // ID)
    kInvalidServiceId,
    // Invalid client ID. New ID should always be either -1 or the current client ID.
    kInvalidClientId
};

// Creates an empty base VMS message with some pre-populated default fields.
std::unique_ptr<VehiclePropValue> createBaseVmsMessage(size_t message_size);

@@ -146,11 +164,21 @@ std::unique_ptr<VehiclePropValue> createSubscriptionsRequest();
// Creates a VehiclePropValue containing a message of type VmsMessageType.DATA.
// Returns a nullptr if the byte string in bytes is empty.
//
// For example, to build a VehiclePropMessage containing a proto, the caller
// For example, to build a VehiclePropValue message containing a proto, the caller
// should convert the proto to a byte string using the SerializeToString proto
// API, then use this inteface to build the VehicleProperty.
std::unique_ptr<VehiclePropValue> createDataMessage(const std::string& bytes);

// Creates a VehiclePropValue containing a message of type
// VmsMessageType.PUBLISHER_ID_REQUEST with the given publisher information.
// Returns a nullptr if the input is empty.
std::unique_ptr<VehiclePropValue> createPublisherIdRequest(
        const std::string& vms_provider_description);

// Creates a VehiclePropValue message of type VmsMessageType.START_SESSION.
std::unique_ptr<VehiclePropValue> createStartSessionMessage(const int service_id,
                                                            const int client_id);

// Returns true if the VehiclePropValue pointed to by value contains a valid Vms
// message, i.e. the VehicleProperty, VehicleArea, and VmsMessageType are all
// valid. Note: If the VmsMessageType enum is extended, this function will
@@ -169,12 +197,6 @@ VmsMessageType parseMessageType(const VehiclePropValue& value);
// function to ParseFromString.
std::string parseData(const VehiclePropValue& value);

// Creates a VehiclePropValue containing a message of type
// VmsMessageType.PUBLISHER_ID_REQUEST with the given publisher information.
// Returns a nullptr if the input is empty.
std::unique_ptr<VehiclePropValue> createPublisherIdRequest(
        const std::string& vms_provider_description);

// Returns the publisher ID by parsing the VehiclePropValue containing the ID.
// Returns null if the message is invalid.
int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response);
@@ -204,6 +226,12 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_c
// has newly started or restarted.
bool hasServiceNewlyStarted(const VehiclePropValue& availability_change);

// Takes a start session message, current service ID, current client ID; and returns the type/status
// of the message. It also populates the new service ID with the correct value.
VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
                                          const int service_id, const int client_id,
                                          int* new_service_id);

}  // namespace vms
}  // namespace V2_0
}  // namespace vehicle
+50 −13
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ static constexpr int kPublisherIdSize = 1;
static constexpr int kLayerNumberSize = 1;
static constexpr int kLayerSize = 3;
static constexpr int kLayerAndPublisherSize = 4;
static constexpr int kSessionIdsSize = 2;
static constexpr int kPublisherIdIndex =
        toInt(VmsPublisherInformationIntegerValuesIndex::PUBLISHER_ID);
static constexpr int kSubscriptionStateSequenceNumberIndex =
@@ -41,9 +42,9 @@ static constexpr int kAvailabilitySequenceNumberIndex =
// TODO(aditin): We should extend the VmsMessageType enum to include a first and
// last, which would prevent breakages in this API. However, for all of the
// functions in this module, we only need to guarantee that the message type is
// between SUBSCRIBE and PUBLISHER_ID_RESPONSE.
// between SUBSCRIBE and START_SESSION.
static constexpr int kFirstMessageType = toInt(VmsMessageType::SUBSCRIBE);
static constexpr int kLastMessageType = toInt(VmsMessageType::PUBLISHER_ID_RESPONSE);
static constexpr int kLastMessageType = toInt(VmsMessageType::START_SESSION);

std::unique_ptr<VehiclePropValue> createBaseVmsMessage(size_t message_size) {
    auto result = createVehiclePropValue(VehiclePropertyType::INT32, message_size);
@@ -132,6 +133,28 @@ std::unique_ptr<VehiclePropValue> createDataMessage(const std::string& bytes) {
    return result;
}

std::unique_ptr<VehiclePropValue> createPublisherIdRequest(
        const std::string& vms_provider_description) {
    auto result = createBaseVmsMessage(kMessageTypeSize);
    result->value.int32Values = hidl_vec<int32_t>{
            toInt(VmsMessageType::PUBLISHER_ID_REQUEST),
    };
    result->value.bytes =
            std::vector<uint8_t>(vms_provider_description.begin(), vms_provider_description.end());
    return result;
}

std::unique_ptr<VehiclePropValue> createStartSessionMessage(const int service_id,
                                                            const int client_id) {
    auto result = createBaseVmsMessage(kMessageTypeSize + kSessionIdsSize);
    result->value.int32Values = hidl_vec<int32_t>{
            toInt(VmsMessageType::START_SESSION),
            service_id,
            client_id,
    };
    return result;
}

bool isValidVmsProperty(const VehiclePropValue& value) {
    return (value.prop == toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
}
@@ -159,17 +182,6 @@ std::string parseData(const VehiclePropValue& value) {
    }
}

std::unique_ptr<VehiclePropValue> createPublisherIdRequest(
        const std::string& vms_provider_description) {
    auto result = createBaseVmsMessage(kMessageTypeSize);
    result->value.int32Values = hidl_vec<int32_t>{
            toInt(VmsMessageType::PUBLISHER_ID_REQUEST),
    };
    result->value.bytes =
            std::vector<uint8_t>(vms_provider_description.begin(), vms_provider_description.end());
    return result;
}

int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response) {
    if (isValidVmsMessage(publisher_id_response) &&
        parseMessageType(publisher_id_response) == VmsMessageType::PUBLISHER_ID_RESPONSE &&
@@ -256,6 +268,31 @@ bool hasServiceNewlyStarted(const VehiclePropValue& availability_change) {
            availability_change.value.int32Values[kAvailabilitySequenceNumberIndex] == 0);
}

VmsSessionStatus parseStartSessionMessage(const VehiclePropValue& start_session,
                                          const int service_id, const int client_id,
                                          int* new_service_id) {
    if (isValidVmsMessage(start_session) &&
        parseMessageType(start_session) == VmsMessageType::START_SESSION &&
        start_session.value.int32Values.size() == kSessionIdsSize + 1) {
        *new_service_id = start_session.value.int32Values[1];
        const int new_client_id = start_session.value.int32Values[2];
        if (*new_service_id < std::max(0, service_id)) {
            *new_service_id = service_id;
            return VmsSessionStatus::kInvalidServiceId;
        }
        if (new_client_id == -1) {
            return VmsSessionStatus::kNewServerSession;
        }
        if (new_client_id == client_id) {
            return VmsSessionStatus::kAckToNewClientSession;
        }
        *new_service_id = service_id;
        return VmsSessionStatus::kInvalidClientId;
    }
    *new_service_id = service_id;
    return VmsSessionStatus::kInvalidMessage;
}

}  // namespace vms
}  // namespace V2_0
}  // namespace vehicle
+93 −1
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ TEST(VmsUtilsTest, emptyMessageInvalid) {
TEST(VmsUtilsTest, invalidMessageType) {
    VmsLayer layer(1, 0, 2);
    auto message = createSubscribeMessage(layer);
    message->value.int32Values[0] = 0;
    message->value.int32Values[0] = -1;

    EXPECT_FALSE(isValidVmsMessage(*message));
}
@@ -325,6 +325,98 @@ TEST(VmsUtilsTest, invalidAvailabilityChange) {
    EXPECT_FALSE(hasServiceNewlyStarted(*message));
}

TEST(VmsUtilsTest, startSessionRequest) {
    auto message = createStartSessionMessage(123, 456);
    ASSERT_NE(message, nullptr);
    EXPECT_TRUE(isValidVmsMessage(*message));
    EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
    EXPECT_EQ(message->value.int32Values.size(), 0x3ul);
    EXPECT_EQ(parseMessageType(*message), VmsMessageType::START_SESSION);
    EXPECT_EQ(message->value.int32Values[1], 123);
    EXPECT_EQ(message->value.int32Values[2], 456);
}

TEST(VmsUtilsTest, startSessionServiceNewlyStarted) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, -1};
    EXPECT_EQ(parseStartSessionMessage(*message, 122, 456, &new_service_id),
              VmsSessionStatus::kNewServerSession);
    EXPECT_EQ(new_service_id, 123);
}

TEST(VmsUtilsTest, startSessionServiceNewlyStartedEdgeCase) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, -1};
    EXPECT_EQ(parseStartSessionMessage(*message, -1, 0, &new_service_id),
              VmsSessionStatus::kNewServerSession);
    EXPECT_EQ(new_service_id, 0);
}

TEST(VmsUtilsTest, startSessionClientNewlyStarted) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 456};
    EXPECT_EQ(parseStartSessionMessage(*message, -1, 456, &new_service_id),
              VmsSessionStatus::kAckToNewClientSession);
    EXPECT_EQ(new_service_id, 123);
}

TEST(VmsUtilsTest, startSessionClientNewlyStartedWithSameServerId) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 456};
    EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
              VmsSessionStatus::kAckToNewClientSession);
    EXPECT_EQ(new_service_id, 123);
}

TEST(VmsUtilsTest, startSessionClientNewlyStartedEdgeCase) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, 0};
    EXPECT_EQ(parseStartSessionMessage(*message, 0, 0, &new_service_id),
              VmsSessionStatus::kAckToNewClientSession);
    EXPECT_EQ(new_service_id, 0);
}

TEST(VmsUtilsTest, startSessionOldServiceId) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 120, 456};
    EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
              VmsSessionStatus::kInvalidServiceId);
    EXPECT_EQ(new_service_id, 123);
}

TEST(VmsUtilsTest, startSessionInvalidServiceIdEdgeCase) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), -1, 456};
    EXPECT_EQ(parseStartSessionMessage(*message, -1, 456, &new_service_id),
              VmsSessionStatus::kInvalidServiceId);
    EXPECT_EQ(new_service_id, -1);
}

TEST(VmsUtilsTest, startSessionInvalidClientId) {
    auto message = createBaseVmsMessage(3);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123, 457};
    EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
              VmsSessionStatus::kInvalidClientId);
    EXPECT_EQ(new_service_id, 123);
}

TEST(VmsUtilsTest, startSessionInvalidMessageFormat) {
    auto message = createBaseVmsMessage(2);
    int new_service_id;
    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 123};
    EXPECT_EQ(parseStartSessionMessage(*message, 123, 456, &new_service_id),
              VmsSessionStatus::kInvalidMessage);
    EXPECT_EQ(new_service_id, 123);
}

}  // namespace

}  // namespace vms