Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculate type hash from TypeDescription (rep2011) #1027

Merged
merged 8 commits into from Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions rcl/CMakeLists.txt
Expand Up @@ -4,6 +4,7 @@ project(rcl)

find_package(ament_cmake_ros REQUIRED)

find_package(libyaml_vendor REQUIRED)
find_package(rcl_interfaces REQUIRED)
find_package(rcl_logging_interface REQUIRED)
find_package(rcl_yaml_param_parser REQUIRED)
Expand All @@ -13,6 +14,8 @@ find_package(rmw_implementation REQUIRED)
find_package(rosidl_runtime_c REQUIRED)
find_package(service_msgs REQUIRED)
find_package(tracetools REQUIRED)
find_package(type_description_interfaces REQUIRED)
find_package(yaml REQUIRED)

include(cmake/rcl_set_symbol_visibility_hidden.cmake)
include(cmake/get_default_rcl_logging_implementation.cmake)
Expand Down Expand Up @@ -64,6 +67,7 @@ set(${PROJECT_NAME}_sources
src/rcl/subscription.c
src/rcl/time.c
src/rcl/timer.c
src/rcl/type_hash.c
src/rcl/validate_enclave_name.c
src/rcl/validate_topic_name.c
src/rcl/wait.c
Expand All @@ -86,6 +90,8 @@ ament_target_dependencies(${PROJECT_NAME}
"rosidl_runtime_c"
"service_msgs"
"tracetools"
"type_description_interfaces"
"yaml"
)

# Causes the visibility macros to use dllexport rather than dllimport,
Expand Down Expand Up @@ -127,6 +133,7 @@ ament_export_dependencies(${RCL_LOGGING_IMPL})
ament_export_dependencies(rosidl_runtime_c)
ament_export_dependencies(service_msgs)
ament_export_dependencies(tracetools)
ament_export_dependencies(type_description_interfaces)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
Expand Down
79 changes: 79 additions & 0 deletions rcl/include/rcl/type_hash.h
@@ -0,0 +1,79 @@
// Copyright 2023 Open Source Robotics Foundation, Inc.
//
// 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.

#ifndef RCL__TYPE_HASH_H_
#define RCL__TYPE_HASH_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include "rcl/types.h"
#include "rcl/visibility_control.h"
#include "rcutils/sha256.h"
#include "rosidl_runtime_c/type_hash.h"
#include "type_description_interfaces/msg/type_description.h"

/// Given a TypeDescription, output a string of the hashable JSON representation of that data.
/**
* The output here is generally hashed via rcl_calculate_type_hash() below.
* Compare this reference implementation with the .json output files from
* `rosidl_generator_type_description.generate_type_hash`.
* Both must produce the same output for the same types, providing a stable reference for
* external implementations of the ROS 2 Type Version Hash.
*
* The JSON representation contains all types and fields of the original message, but excludes:
* - Default values
* - Comments
* - The input plaintext files that generated the TypeDescription
*
* \param[in] type_description Prefilled TypeDescription message to be translated
* \param[out] output_repr An initialized empty char array that will be filled with
* the JSON representation of type_description. Note that output_repr will have a
* terminating null character, which should be omitted from hashing. To do so, use
* (output_repr.buffer_length - 1) or strlen(output_repr.buffer) for the size of data to hash.
* \return #RCL_RET_OK on success, or
* \return #RCL_RET_ERROR if any problems occur in translation.
*/
RCL_PUBLIC
rcl_ret_t
rcl_type_description_to_hashable_json(
const type_description_interfaces__msg__TypeDescription * type_description,
rcutils_char_array_t * output_repr);

/// Calculate the Type Version Hash for a given TypeDescription.
/**
* This function produces a stable hash value for a ROS communication interface type.
* For design motivations leading to this implementation, see REP-2011.
*
* This convenience wrapper calls rcl_type_description_to_hashable_json,
* then runs sha256 hash on the result.
*
* \param[in] msg Prefilled TypeDescription message describing the type to be hashed
* \param[out] message_digest Preallocated buffer, to be filled with calculated checksum
* \return #RCL_RET_OK on success, or
* \return #RCL_RET_ERROR if any problems occur while hashing.
*/
RCL_PUBLIC
rcl_ret_t
rcl_calculate_type_hash(
const type_description_interfaces__msg__TypeDescription * type_description,
rosidl_type_hash_t * out_type_hash);

#ifdef __cplusplus
}
#endif

#endif // RCL__TYPE_HASH_H_
3 changes: 3 additions & 0 deletions rcl/package.xml
Expand Up @@ -19,6 +19,7 @@

<build_export_depend>rmw</build_export_depend>

<depend>libyaml_vendor</depend>
<depend>rcl_interfaces</depend>
<depend>rcl_logging_interface</depend>
<depend>rcl_logging_spdlog</depend> <!-- the default logging impl -->
Expand All @@ -28,6 +29,8 @@
<depend>rosidl_runtime_c</depend>
<depend>service_msgs</depend>
<depend>tracetools</depend>
<depend>type_description_interfaces</depend>
<depend>yaml</depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_lint_auto</test_depend>
Expand Down