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

Commit c62ce9d6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 3737a9ca 2bc0c5f2
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