Skip to content

Commit c48313c

Browse files
Runtime error handling API (backport #212) (#219)
* Runtime error handling API (#212) * Initial Signed-off-by: Pablo Garrido <pablogs9@gmail.com> Uncrustify Signed-off-by: Pablo Garrido <pablogs9@gmail.com> Update Signed-off-by: Pablo Garrido <pablogs9@gmail.com> Uncrus Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Update Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Refactor Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Update Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Update Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Remove include old error handler Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Update Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Client Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Update Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Uncrustify Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Fix Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Fix Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Fix Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Update rmw_microxrcedds_c/src/rmw_microros_internal/error_handling_internal.h Co-authored-by: Antonio Cuadros <49162117+Acuadros95@users.noreply.github.com> (cherry picked from commit 266248d) # Conflicts: # rmw_microxrcedds_c/src/rmw_get_endpoint_network_flow.c # rmw_microxrcedds_c/src/rmw_qos_profile_check_compatible.c # rmw_microxrcedds_c/src/rmw_wait.c * Fix conflicts Signed-off-by: Pablo Garrido <pablogs9@gmail.com> * Revert "Fix conflicts" This reverts commit 1db99e0. * Fix conflicts Signed-off-by: Pablo Garrido <pablogs9@gmail.com> Co-authored-by: Pablo Garrido <pablogs9@gmail.com>
1 parent e1a1d52 commit c48313c

59 files changed

Lines changed: 573 additions & 320 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rmw_microxrcedds_c/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ find_package(rmw REQUIRED)
3535
# Build options
3636
option(BUILD_DOCUMENTATION "Use doxygen to create product documentation" OFF)
3737
option(RMW_UXRCE_GRAPH "Allows to perform graph-related operations to the user" OFF)
38+
option(RMW_UROS_ERROR_HANDLING "Provides error handling callback functionality to user-space" OFF)
3839

3940
if(RMW_UXRCE_GRAPH)
4041
find_package(micro_ros_msgs REQUIRED)
@@ -146,6 +147,10 @@ endif()
146147

147148
set(DOC_INSTALL_DIR ${DOC_DIR} CACHE PATH "Installation directory for documentation")
148149

150+
if(BUILD_TESTING)
151+
set(RMW_UROS_ERROR_HANDLING ON)
152+
endif()
153+
149154
set(SRCS
150155
src/identifiers.c
151156
src/memory.c
@@ -190,6 +195,7 @@ set(SRCS
190195
$<$<OR:$<BOOL:${RMW_UXRCE_TRANSPORT_UDP}>,$<BOOL:${RMW_UXRCE_TRANSPORT_TCP}>>:src/rmw_microros/discovery.c>
191196
$<$<BOOL:${RMW_UXRCE_TRANSPORT_CUSTOM}>:src/rmw_microros/custom_transport.c>
192197
$<$<BOOL:${RMW_UXRCE_GRAPH}>:src/rmw_graph.c>
198+
$<$<BOOL:${RMW_UROS_ERROR_HANDLING}>:src/rmw_microros/error_handling.c>
193199
)
194200

195201
add_library(${PROJECT_NAME}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file
17+
*/
18+
19+
#ifndef RMW_MICROROS__ERROR_HANDLING_H_
20+
#define RMW_MICROROS__ERROR_HANDLING_H_
21+
22+
#ifdef RMW_UROS_ERROR_HANDLING
23+
24+
#include <ucdr/microcdr.h>
25+
#include <rosidl_typesupport_microxrcedds_c/message_type_support.h>
26+
#include <rosidl_typesupport_microxrcedds_c/service_type_support.h>
27+
28+
#if defined(__cplusplus)
29+
extern "C"
30+
{
31+
#endif // if defined(__cplusplus)
32+
33+
typedef enum
34+
{
35+
RMW_UROS_ERROR_ON_UNKNOWN = 0,
36+
RMW_UROS_ERROR_ON_NODE,
37+
RMW_UROS_ERROR_ON_SERVICE,
38+
RMW_UROS_ERROR_ON_CLIENT,
39+
RMW_UROS_ERROR_ON_SUBSCRIPTION,
40+
RMW_UROS_ERROR_ON_PUBLISHER,
41+
RMW_UROS_ERROR_ON_GRAPH,
42+
RMW_UROS_ERROR_ON_GUARD_CONDITION,
43+
RMW_UROS_ERROR_ON_TOPIC
44+
} rmw_uros_error_entity_type_t;
45+
46+
typedef enum
47+
{
48+
RMW_UROS_ERROR_ENTITY_CREATION = 0,
49+
RMW_UROS_ERROR_ENTITY_DESTRUCTION,
50+
RMW_UROS_ERROR_CHECK,
51+
RMW_UROS_ERROR_NOT_IMPLEMENTED,
52+
RMW_UROS_ERROR_MIDDLEWARE_ALLOCATION,
53+
} rmw_uros_error_source_t;
54+
55+
typedef struct
56+
{
57+
const char * node;
58+
const char * node_namespace;
59+
const char * topic_name;
60+
const ucdrBuffer * ucdr;
61+
const size_t size;
62+
union {
63+
const message_type_support_callbacks_t * message_callbacks;
64+
const service_type_support_callbacks_t * service_callbacks;
65+
} type_support;
66+
const char * description;
67+
} rmw_uros_error_context_t;
68+
69+
typedef void (* rmw_uros_error_handling)(
70+
const rmw_uros_error_entity_type_t entity,
71+
const rmw_uros_error_source_t source,
72+
const rmw_uros_error_context_t context,
73+
const char * file,
74+
const int line);
75+
76+
/** \addtogroup rmw micro-ROS RMW API
77+
* @{
78+
*/
79+
80+
/**
81+
* \brief Sets the callback functions for handling error in static memory handling
82+
*
83+
* \param[in] error_cb callback to be triggered on static memory failure
84+
*/
85+
void rmw_uros_set_error_handling_callback(
86+
rmw_uros_error_handling error_cb);
87+
88+
/** @}*/
89+
90+
#if defined(__cplusplus)
91+
}
92+
#endif // if defined(__cplusplus)
93+
94+
#endif // RMW_UROS_ERROR_HANDLING
95+
96+
#endif // RMW_MICROROS__ERROR_HANDLING_H_

rmw_microxrcedds_c/include/rmw_microros/rmw_microros.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#include <rmw_microros/custom_transport.h>
3535
#endif // RMW_UXRCE_TRANSPORT_CUSTOM
3636

37+
#ifdef RMW_UROS_ERROR_HANDLING
38+
#include <rmw_microros/error_handling.h>
39+
#endif // RMW_UROS_ERROR_HANDLING
40+
3741
#if defined(__cplusplus)
3842
extern "C"
3943
{

rmw_microxrcedds_c/include/rmw_microros/time_sync.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <rmw/rmw.h>
2323
#include <rmw/ret_types.h>
2424
#include <rmw/init_options.h>
25-
#include <rmw/error_handling.h>
2625
#include <uxr/client/util/time.h>
2726

2827
#if defined(__cplusplus)

rmw_microxrcedds_c/include/rmw_microros/timing.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <rmw/rmw.h>
2323
#include <rmw/ret_types.h>
2424
#include <rmw/init_options.h>
25-
#include <rmw/error_handling.h>
2625
#include <uxr/client/util/time.h>
2726

2827
#if defined(__cplusplus)

rmw_microxrcedds_c/include/rmw_microxrcedds_c/rmw_c_macros.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
#ifndef RMW_MICROXRCEDDS_C__RMW_C_MACROS_H_
1616
#define RMW_MICROXRCEDDS_C__RMW_C_MACROS_H_
1717

18-
#define RMW_CHECK_TYPE_IDENTIFIERS_MATCH(ElementName, ElementTypeID, ExpectedTypeID, OnFailure) \
18+
#include <rmw/error_handling.h>
19+
#include <rmw_microros_internal/identifiers.h>
20+
21+
#define RMW_CHECK_TYPE_IDENTIFIERS_MATCH(identifier, ret_on_failure) \
1922
{ \
20-
if (strcmp(ElementTypeID, ExpectedTypeID) != 0) { \
23+
if (NULL != identifier && strcmp(identifier, eprosima_microxrcedds_identifier) != 0) { \
2124
RMW_SET_ERROR_MSG("Implementation identifiers does not match"); \
22-
OnFailure; \
25+
return ret_on_failure; \
2326
} \
2427
}
2528

rmw_microxrcedds_c/src/callbacks.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
// limitations under the License.
1414

1515
#include <rmw_microros_internal/callbacks.h>
16-
17-
#include <rmw/error_handling.h>
16+
#include "./rmw_microros_internal/error_handling_internal.h"
1817

1918
void on_status(
2019
struct uxrSession * session,
@@ -75,8 +74,15 @@ void on_topic(
7574
rmw_uxrce_mempool_item_t * memory_node = rmw_uxrce_get_static_input_buffer_for_entity(
7675
custom_subscription, custom_subscription->qos);
7776
if (!memory_node) {
78-
RMW_SET_ERROR_MSG("Not available static buffer memory node");
7977
UXR_UNLOCK(&static_buffer_memory.mutex);
78+
RMW_UROS_TRACE_ERROR(
79+
RMW_UROS_ERROR_ON_SUBSCRIPTION, RMW_UROS_ERROR_MIDDLEWARE_ALLOCATION,
80+
"Not available static buffer memory node in on_topic callback",
81+
.node = custom_subscription->owner_node->node_name,
82+
.node_namespace = custom_subscription->owner_node->node_namespace,
83+
.topic_name = custom_subscription->topic_name, .ucdr = ub,
84+
.size = length,
85+
.type_support.message_callbacks = custom_subscription->type_support_callbacks);
8086
return;
8187
}
8288

@@ -127,8 +133,15 @@ void on_request(
127133
rmw_uxrce_mempool_item_t * memory_node = rmw_uxrce_get_static_input_buffer_for_entity(
128134
custom_service, custom_service->qos);
129135
if (!memory_node) {
130-
RMW_SET_ERROR_MSG("Not available static buffer memory node");
131136
UXR_UNLOCK(&static_buffer_memory.mutex);
137+
RMW_UROS_TRACE_ERROR(
138+
RMW_UROS_ERROR_ON_SERVICE, RMW_UROS_ERROR_MIDDLEWARE_ALLOCATION,
139+
"Not available static buffer memory node in on_request callback",
140+
.node = custom_service->owner_node->node_name,
141+
.node_namespace = custom_service->owner_node->node_namespace,
142+
.topic_name = custom_service->service_name, .ucdr = ub,
143+
.size = length,
144+
.type_support.service_callbacks = custom_service->type_support_callbacks);
132145
return;
133146
}
134147

@@ -181,8 +194,15 @@ void on_reply(
181194
rmw_uxrce_mempool_item_t * memory_node = rmw_uxrce_get_static_input_buffer_for_entity(
182195
custom_client, custom_client->qos);
183196
if (!memory_node) {
184-
RMW_SET_ERROR_MSG("Not available static buffer memory node");
185197
UXR_UNLOCK(&static_buffer_memory.mutex);
198+
RMW_UROS_TRACE_ERROR(
199+
RMW_UROS_ERROR_ON_CLIENT, RMW_UROS_ERROR_MIDDLEWARE_ALLOCATION,
200+
"Not available static buffer memory node in on_reply callback",
201+
.node = custom_client->owner_node->node_name,
202+
.node_namespace = custom_client->owner_node->node_namespace,
203+
.topic_name = custom_client->service_name, .ucdr = ub,
204+
.size = length,
205+
.type_support.service_callbacks = custom_client->type_support_callbacks);
186206
return;
187207
}
188208

rmw_microxrcedds_c/src/config.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#cmakedefine RMW_UXRCE_USE_REFS
1313
#cmakedefine RMW_UXRCE_ALLOW_DYNAMIC_ALLOCATIONS
1414
#cmakedefine RMW_UXRCE_GRAPH
15+
#cmakedefine RMW_UROS_ERROR_HANDLING
1516

1617
#ifdef RMW_UXRCE_TRANSPORT_UDP
1718
#define RMW_UXRCE_MAX_TRANSPORT_MTU UXR_CONFIG_UDP_TRANSPORT_MTU

rmw_microxrcedds_c/src/rmw_client.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
#include <rmw/rmw.h>
2424
#include <rmw/allocators.h>
25-
#include <rmw/error_handling.h>
2625

2726
#include "./rmw_microros_internal/utils.h"
27+
#include "./rmw_microros_internal/error_handling_internal.h"
2828

2929
rmw_client_t *
3030
rmw_create_client(
@@ -35,20 +35,20 @@ rmw_create_client(
3535
{
3636
rmw_client_t * rmw_client = NULL;
3737
if (!node) {
38-
RMW_SET_ERROR_MSG("node handle is null");
38+
RMW_UROS_TRACE_MESSAGE("node handle is null")
3939
} else if (!type_support) {
40-
RMW_SET_ERROR_MSG("type support is null");
40+
RMW_UROS_TRACE_MESSAGE("type support is null")
4141
} else if (!is_uxrce_rmw_identifier_valid(node->implementation_identifier)) {
42-
RMW_SET_ERROR_MSG("node handle not from this implementation");
42+
RMW_UROS_TRACE_MESSAGE("node handle not from this implementation")
4343
} else if (!service_name || strlen(service_name) == 0) {
44-
RMW_SET_ERROR_MSG("service name is null or empty string");
44+
RMW_UROS_TRACE_MESSAGE("service name is null or empty string")
4545
} else if (!qos_policies) {
46-
RMW_SET_ERROR_MSG("qos_profile is null");
46+
RMW_UROS_TRACE_MESSAGE("qos_profile is null")
4747
} else {
4848
rmw_uxrce_node_t * custom_node = (rmw_uxrce_node_t *)node->data;
4949
rmw_uxrce_mempool_item_t * memory_node = get_memory(&client_memory);
5050
if (!memory_node) {
51-
RMW_SET_ERROR_MSG("Not available memory node");
51+
RMW_UROS_TRACE_MESSAGE("Not available memory node")
5252
return NULL;
5353
}
5454
rmw_uxrce_client_t * custom_client = (rmw_uxrce_client_t *)memory_node->data;
@@ -58,7 +58,7 @@ rmw_create_client(
5858
rmw_client->implementation_identifier = rmw_get_implementation_identifier();
5959
rmw_client->service_name = custom_client->service_name;
6060
if ((strlen(service_name) + 1 ) > sizeof(custom_client->service_name)) {
61-
RMW_SET_ERROR_MSG("failed to allocate string");
61+
RMW_UROS_TRACE_MESSAGE("failed to allocate string")
6262
goto fail;
6363
}
6464

@@ -80,15 +80,15 @@ rmw_create_client(
8080
}
8181
#endif /* ifdef ROSIDL_TYPESUPPORT_MICROXRCEDDS_CPP__IDENTIFIER_VALUE */
8282
if (NULL == type_support_xrce) {
83-
RMW_SET_ERROR_MSG("Undefined type support");
83+
RMW_UROS_TRACE_MESSAGE("Undefined type support")
8484
goto fail;
8585
}
8686

8787
custom_client->type_support_callbacks =
8888
(const service_type_support_callbacks_t *)type_support_xrce->data;
8989

9090
if (custom_client->type_support_callbacks == NULL) {
91-
RMW_SET_ERROR_MSG("type support data is NULL");
91+
RMW_UROS_TRACE_MESSAGE("type support data is NULL")
9292
goto fail;
9393
}
9494

@@ -109,7 +109,7 @@ rmw_create_client(
109109
custom_client->type_support_callbacks, qos_policies, rmw_uxrce_entity_naming_buffer,
110110
sizeof(rmw_uxrce_entity_naming_buffer)))
111111
{
112-
RMW_SET_ERROR_MSG("failed to generate xml request for client creation");
112+
RMW_UROS_TRACE_MESSAGE("failed to generate xml request for client creation")
113113
goto fail;
114114
}
115115
client_req = uxr_buffer_create_requester_xml(
@@ -190,22 +190,22 @@ rmw_destroy_client(
190190
{
191191
rmw_ret_t result_ret = RMW_RET_OK;
192192
if (!node) {
193-
RMW_SET_ERROR_MSG("node handle is null");
193+
RMW_UROS_TRACE_MESSAGE("node handle is null")
194194
result_ret = RMW_RET_ERROR;
195195
} else if (!is_uxrce_rmw_identifier_valid(node->implementation_identifier)) {
196-
RMW_SET_ERROR_MSG("node handle not from this implementation");
196+
RMW_UROS_TRACE_MESSAGE("node handle not from this implementation")
197197
result_ret = RMW_RET_ERROR;
198198
} else if (!node->data) {
199-
RMW_SET_ERROR_MSG("node imp is null");
199+
RMW_UROS_TRACE_MESSAGE("node imp is null")
200200
result_ret = RMW_RET_ERROR;
201201
} else if (!client) {
202-
RMW_SET_ERROR_MSG("client handle is null");
202+
RMW_UROS_TRACE_MESSAGE("client handle is null")
203203
result_ret = RMW_RET_ERROR;
204204
} else if (!is_uxrce_rmw_identifier_valid(client->implementation_identifier)) {
205-
RMW_SET_ERROR_MSG("client handle not from this implementation");
205+
RMW_UROS_TRACE_MESSAGE("client handle not from this implementation")
206206
result_ret = RMW_RET_ERROR;
207207
} else if (!client->data) {
208-
RMW_SET_ERROR_MSG("client imp is null");
208+
RMW_UROS_TRACE_MESSAGE("client imp is null")
209209
result_ret = RMW_RET_ERROR;
210210
} else {
211211
rmw_uxrce_node_t * custom_node = (rmw_uxrce_node_t *)node->data;

rmw_microxrcedds_c/src/rmw_compare_gids_equal.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
#include <rmw/rmw.h>
1616
#include <rmw/error_handling.h>
1717

18+
#include <rmw_microxrcedds_c/rmw_c_macros.h>
19+
#include "./rmw_microros_internal/error_handling_internal.h"
20+
1821
rmw_ret_t
1922
rmw_compare_gids_equal(
2023
const rmw_gid_t * gid1,
@@ -24,13 +27,12 @@ rmw_compare_gids_equal(
2427
// Check
2528
RMW_CHECK_ARGUMENT_FOR_NULL(gid1, RMW_RET_INVALID_ARGUMENT);
2629
RMW_CHECK_ARGUMENT_FOR_NULL(gid2, RMW_RET_INVALID_ARGUMENT);
27-
if (gid1->implementation_identifier != rmw_get_implementation_identifier()) {
28-
RMW_SET_ERROR_MSG("publisher handle not from this implementation");
29-
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION;
30-
} else if (gid2->implementation_identifier != rmw_get_implementation_identifier()) {
31-
RMW_SET_ERROR_MSG("publisher handle not from this implementation");
32-
return RMW_RET_INCORRECT_RMW_IMPLEMENTATION;
33-
}
30+
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
31+
gid1->implementation_identifier,
32+
RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
33+
RMW_CHECK_TYPE_IDENTIFIERS_MATCH(
34+
gid2->implementation_identifier,
35+
RMW_RET_INCORRECT_RMW_IMPLEMENTATION);
3436

3537
*result = memcmp(gid1->data, gid2->data, sizeof(rmw_gid_t)) == 0;
3638

0 commit comments

Comments
 (0)