--- /dev/null
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/tsi/alts/handshaker/transport_security_common_api.h"
+
+bool grpc_gcp_rpc_protocol_versions_set_max(
+ grpc_gcp_rpc_protocol_versions* versions, uint32_t max_major,
+ uint32_t max_minor) {
+ if (versions == nullptr) {
+ gpr_log(GPR_ERROR,
+ "versions is nullptr in "
+ "grpc_gcp_rpc_protocol_versions_set_max().");
+ return false;
+ }
+ versions->max_rpc_version.major = max_major;
+ versions->max_rpc_version.minor = max_minor;
+ return true;
+}
+
+bool grpc_gcp_rpc_protocol_versions_set_min(
+ grpc_gcp_rpc_protocol_versions* versions, uint32_t min_major,
+ uint32_t min_minor) {
+ if (versions == nullptr) {
+ gpr_log(GPR_ERROR,
+ "versions is nullptr in "
+ "grpc_gcp_rpc_protocol_versions_set_min().");
+ return false;
+ }
+ versions->min_rpc_version.major = min_major;
+ versions->min_rpc_version.minor = min_minor;
+ return true;
+}
+
+bool grpc_gcp_rpc_protocol_versions_encode(
+ const grpc_gcp_rpc_protocol_versions* versions, grpc_slice* slice) {
+ if (versions == nullptr || slice == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to "
+ "grpc_gcp_rpc_protocol_versions_encode().");
+ return false;
+ }
+ upb::Arena arena;
+ grpc_gcp_RpcProtocolVersions* versions_msg =
+ grpc_gcp_RpcProtocolVersions_new(arena.ptr());
+ grpc_gcp_RpcProtocolVersions_assign_from_struct(versions_msg, arena.ptr(),
+ versions);
+ return grpc_gcp_rpc_protocol_versions_encode(versions_msg, arena.ptr(),
+ slice);
+}
+
+bool grpc_gcp_rpc_protocol_versions_encode(
+ const grpc_gcp_RpcProtocolVersions* versions, upb_arena* arena,
+ grpc_slice* slice) {
+ if (versions == nullptr || arena == nullptr || slice == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid nullptr arguments to "
+ "grpc_gcp_rpc_protocol_versions_encode().");
+ return false;
+ }
+ size_t buf_length;
+ char* buf =
+ grpc_gcp_RpcProtocolVersions_serialize(versions, arena, &buf_length);
+ if (buf == nullptr) {
+ return false;
+ }
+ *slice = grpc_slice_from_copied_buffer(buf, buf_length);
+ return true;
+}
+
+bool grpc_gcp_rpc_protocol_versions_decode(
+ const grpc_slice& slice, grpc_gcp_rpc_protocol_versions* versions) {
+ if (versions == nullptr) {
+ gpr_log(GPR_ERROR,
+ "version is nullptr in "
+ "grpc_gcp_rpc_protocol_versions_decode().");
+ return false;
+ }
+ upb::Arena arena;
+ grpc_gcp_RpcProtocolVersions* versions_msg =
+ grpc_gcp_RpcProtocolVersions_parse(
+ reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(slice)),
+ GRPC_SLICE_LENGTH(slice), arena.ptr());
+ if (versions_msg == nullptr) {
+ gpr_log(GPR_ERROR, "cannot deserialize RpcProtocolVersions message");
+ return false;
+ }
+ grpc_gcp_rpc_protocol_versions_assign_from_upb(versions, versions_msg);
+ return true;
+}
+
+void grpc_gcp_rpc_protocol_versions_assign_from_upb(
+ grpc_gcp_rpc_protocol_versions* versions,
+ const grpc_gcp_RpcProtocolVersions* value) {
+ const grpc_gcp_RpcProtocolVersions_Version* max_version_msg =
+ grpc_gcp_RpcProtocolVersions_max_rpc_version(value);
+ if (max_version_msg != nullptr) {
+ versions->max_rpc_version.major =
+ grpc_gcp_RpcProtocolVersions_Version_major(max_version_msg);
+ versions->max_rpc_version.minor =
+ grpc_gcp_RpcProtocolVersions_Version_minor(max_version_msg);
+ } else {
+ versions->max_rpc_version.major = 0;
+ versions->max_rpc_version.minor = 0;
+ }
+ const grpc_gcp_RpcProtocolVersions_Version* min_version_msg =
+ grpc_gcp_RpcProtocolVersions_min_rpc_version(value);
+ if (min_version_msg != nullptr) {
+ versions->min_rpc_version.major =
+ grpc_gcp_RpcProtocolVersions_Version_major(min_version_msg);
+ versions->min_rpc_version.minor =
+ grpc_gcp_RpcProtocolVersions_Version_minor(min_version_msg);
+ } else {
+ versions->min_rpc_version.major = 0;
+ versions->min_rpc_version.minor = 0;
+ }
+}
+
+void grpc_gcp_RpcProtocolVersions_assign_from_struct(
+ grpc_gcp_RpcProtocolVersions* versions, upb_arena* arena,
+ const grpc_gcp_rpc_protocol_versions* value) {
+ grpc_gcp_RpcProtocolVersions_Version* max_version_msg =
+ grpc_gcp_RpcProtocolVersions_mutable_max_rpc_version(versions, arena);
+ grpc_gcp_RpcProtocolVersions_Version_set_major(max_version_msg,
+ value->max_rpc_version.major);
+ grpc_gcp_RpcProtocolVersions_Version_set_minor(max_version_msg,
+ value->max_rpc_version.minor);
+ grpc_gcp_RpcProtocolVersions_Version* min_version_msg =
+ grpc_gcp_RpcProtocolVersions_mutable_min_rpc_version(versions, arena);
+ grpc_gcp_RpcProtocolVersions_Version_set_major(min_version_msg,
+ value->min_rpc_version.major);
+ grpc_gcp_RpcProtocolVersions_Version_set_minor(min_version_msg,
+ value->min_rpc_version.minor);
+}
+
+bool grpc_gcp_rpc_protocol_versions_copy(
+ const grpc_gcp_rpc_protocol_versions* src,
+ grpc_gcp_rpc_protocol_versions* dst) {
+ if ((src == nullptr && dst != nullptr) ||
+ (src != nullptr && dst == nullptr)) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_rpc_protocol_versions_copy().");
+ return false;
+ }
+ if (src == nullptr) {
+ return true;
+ }
+ grpc_gcp_rpc_protocol_versions_set_max(dst, src->max_rpc_version.major,
+ src->max_rpc_version.minor);
+ grpc_gcp_rpc_protocol_versions_set_min(dst, src->min_rpc_version.major,
+ src->min_rpc_version.minor);
+ return true;
+}
+
+namespace grpc_core {
+namespace internal {
+
+int grpc_gcp_rpc_protocol_version_compare(
+ const grpc_gcp_rpc_protocol_versions_version* v1,
+ const grpc_gcp_rpc_protocol_versions_version* v2) {
+ if ((v1->major > v2->major) ||
+ (v1->major == v2->major && v1->minor > v2->minor)) {
+ return 1;
+ }
+ if ((v1->major < v2->major) ||
+ (v1->major == v2->major && v1->minor < v2->minor)) {
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace internal
+} // namespace grpc_core
+
+bool grpc_gcp_rpc_protocol_versions_check(
+ const grpc_gcp_rpc_protocol_versions* local_versions,
+ const grpc_gcp_rpc_protocol_versions* peer_versions,
+ grpc_gcp_rpc_protocol_versions_version* highest_common_version) {
+ if (local_versions == nullptr || peer_versions == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Invalid arguments to "
+ "grpc_gcp_rpc_protocol_versions_check().");
+ return false;
+ }
+ /* max_common_version is MIN(local.max, peer.max) */
+ const grpc_gcp_rpc_protocol_versions_version* max_common_version =
+ grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
+ &local_versions->max_rpc_version, &peer_versions->max_rpc_version) > 0
+ ? &peer_versions->max_rpc_version
+ : &local_versions->max_rpc_version;
+ /* min_common_version is MAX(local.min, peer.min) */
+ const grpc_gcp_rpc_protocol_versions_version* min_common_version =
+ grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
+ &local_versions->min_rpc_version, &peer_versions->min_rpc_version) > 0
+ ? &local_versions->min_rpc_version
+ : &peer_versions->min_rpc_version;
+ bool result = grpc_core::internal::grpc_gcp_rpc_protocol_version_compare(
+ max_common_version, min_common_version) >= 0
+ ? true
+ : false;
+ if (result && highest_common_version != nullptr) {
+ memcpy(highest_common_version, max_common_version,
+ sizeof(grpc_gcp_rpc_protocol_versions_version));
+ }
+ return result;
+}