From 0f0660fef9babd1d0be19da0cc95f080d4d81e46 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Tue, 22 Mar 2022 14:53:00 +0100 Subject: [PATCH 01/27] Fix CMake _confgen invocation It turns out add_custom_command uses "ARGS" to separate the command from its arguments, but add_custom_target "COMMAND" doesn't. Signed-off-by: Erik Boasson --- src/tools/_confgen/CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/_confgen/CMakeLists.txt b/src/tools/_confgen/CMakeLists.txt index 9df1b82a..d5ca793d 100644 --- a/src/tools/_confgen/CMakeLists.txt +++ b/src/tools/_confgen/CMakeLists.txt @@ -60,33 +60,33 @@ if (NOT ${_confgen_hash_correct}) add_custom_target( _confgen - COMMAND _confgen-exe ARGS -f defconfig -o "${generated_defconfig_src}" - COMMAND _confgen-exe ARGS -f rnc -o "${generated_cyclonedds_rnc}" - COMMAND _confgen-exe ARGS -f xsd -o "${generated_cyclonedds_xsd}" - COMMAND _confgen-exe ARGS -f md -o "${generated_options_md}" + COMMAND _confgen-exe -f defconfig -o "${generated_defconfig_src}" + COMMAND _confgen-exe -f rnc -o "${generated_cyclonedds_rnc}" + COMMAND _confgen-exe -f xsd -o "${generated_cyclonedds_xsd}" + COMMAND _confgen-exe -f md -o "${generated_options_md}" # Append hashes to defconfig.c - COMMAND ${CMAKE_COMMAND} ARGS + COMMAND ${CMAKE_COMMAND} "-DPREFIX=/*" "-DPOSTFIX=*/" -DHASH_FILES=${out_confgen_hash_files} -DAPPEND_FILES=${generated_defconfig_src} -P ${CMAKE_SOURCE_DIR}/cmake/AppendHashScript.cmake # Append hashes to rnc - COMMAND ${CMAKE_COMMAND} ARGS + COMMAND ${CMAKE_COMMAND} "-DPREFIX=#" "-DPOSTFIX=" -DHASH_FILES=${out_confgen_hash_files} -DAPPEND_FILES=${generated_cyclonedds_rnc} -P ${CMAKE_SOURCE_DIR}/cmake/AppendHashScript.cmake # Append hashes to xsd - COMMAND ${CMAKE_COMMAND} ARGS + COMMAND ${CMAKE_COMMAND} "-DPREFIX=" -DHASH_FILES=${out_confgen_hash_files} -DAPPEND_FILES=${generated_cyclonedds_xsd} -P ${CMAKE_SOURCE_DIR}/cmake/AppendHashScript.cmake # Append hashes to md - COMMAND ${CMAKE_COMMAND} ARGS + COMMAND ${CMAKE_COMMAND} "-DPREFIX=" -DHASH_FILES=${out_confgen_hash_files} From 22a9955e7a519cff184ad99d76711894d7099f49 Mon Sep 17 00:00:00 2001 From: reicheratwork <66302498+reicheratwork@users.noreply.github.com> Date: Fri, 25 Mar 2022 11:00:59 +0100 Subject: [PATCH 02/27] Add default_nested compiler option (#1221) * Add default_nested compiler option This allows setting of the "default" default nestedness, so the value in absence of an annotation, through the command line -n parameter Signed-off-by: Martijn Reicher * Improved documentation for idlc nestedness command line option Signed-off-by: Martijn Reicher --- src/idl/include/idl/processor.h | 1 + src/idl/src/processor.c | 28 ++++++++++++++++++++++++++++ src/idl/tests/annotation.c | 27 ++++++++++++++++++++------- src/tools/idlc/src/idlc.c | 21 +++++++++++++++++++++ 4 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/idl/include/idl/processor.h b/src/idl/include/idl/processor.h index 4e23085a..b27a21eb 100644 --- a/src/idl/include/idl/processor.h +++ b/src/idl/include/idl/processor.h @@ -78,6 +78,7 @@ struct idl_pstate { struct { uint32_t flags; /**< processor options */ int default_extensibility; /**< default extensibility for aggregated types */ + bool default_nested; /**< default nestedness for aggregated types */ const idl_warning_t *disable_warnings; /**< list of warning that will be suppressed */ size_t n_disable_warnings; /**< number of items in disable_warnings */ } config; diff --git a/src/idl/src/processor.c b/src/idl/src/processor.c index 216decd3..2d5e83d0 100644 --- a/src/idl/src/processor.c +++ b/src/idl/src/processor.c @@ -156,6 +156,7 @@ idl_create_pstate( pstate->config.flags = flags; pstate->config.default_extensibility = IDL_DEFAULT_EXTENSIBILITY_UNDEFINED; + pstate->config.default_nested = false; pstate->global_scope = pstate->scope = scope; if (pstate->config.flags & IDL_FLAG_ANNOTATIONS) { @@ -476,6 +477,31 @@ static idl_retcode_t validate_bitbound(idl_pstate_t *pstate) return idl_visit(pstate, pstate->root, &visitor, NULL); } +static void +set_nestedness( + const idl_pstate_t* pstate, + void* node, + bool current_fallback) +{ + IDL_FOREACH(node, node) { + if (idl_is_module(node)) { + idl_module_t *mod = node; + if (!mod->default_nested.annotation) + mod->default_nested.value = current_fallback; + else + current_fallback = mod->default_nested.value; + + IDL_FOREACH(node, mod->definitions) { + set_nestedness(pstate, node, current_fallback); + } + } else if (idl_is_union(node) && !((idl_union_t*)node)->nested.annotation) { + ((idl_union_t*)node)->nested.value = current_fallback; + } else if (idl_is_struct(node) && !((idl_struct_t*)node)->nested.annotation) { + ((idl_struct_t*)node)->nested.value = current_fallback; + } + } +} + static idl_retcode_t set_type_extensibility(idl_pstate_t *pstate) { if (pstate->config.default_extensibility == IDL_DEFAULT_EXTENSIBILITY_UNDEFINED && idl_has_unset_extensibility_r(pstate->root)) { @@ -563,6 +589,8 @@ idl_retcode_t idl_parse(idl_pstate_t *pstate) if ((ret = idl_set_xcdr2_required(pstate->root) != IDL_RETCODE_OK)) goto err; + set_nestedness(pstate, pstate->root, pstate->config.default_nested); + if (pstate->keylists) { if ((ret = idl_validate_keylists(pstate)) != IDL_RETCODE_OK) goto err; diff --git a/src/idl/tests/annotation.c b/src/idl/tests/annotation.c index 6a9d26a7..1c6505e7 100644 --- a/src/idl/tests/annotation.c +++ b/src/idl/tests/annotation.c @@ -432,12 +432,18 @@ CU_Test(idl_annotation, default_nested) const char *str; struct { bool a; bool v; } dn[3]; struct { bool a; bool v; } n[2]; + bool pstate_default_nested; } tests[] = { - { M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{0,0},{0,0},{0,0}}, {{0,0},{0,0}} }, - { DN() M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{0,1},{0,1}} }, - { DN() M("m1", DN(NO) M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{1,0},{0,1}}, {{0,0},{0,1}} }, - { DN(NO) M("m1", DN(YES) M("m2", S("s1")) M("m3", S("s2"))), {{1,0},{1,1},{0,0}}, {{0,1},{0,0}} }, - { DN(YES) M("m1", M("m2", N(NO) S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{1,0},{0,1}} } + { M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{0,0},{0,0},{0,0}}, {{0,0},{0,0}}, false }, + { DN() M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{0,1},{0,1}}, false }, + { DN() M("m1", DN(NO) M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{1,0},{0,1}}, {{0,0},{0,1}}, false }, + { DN(NO) M("m1", DN(YES) M("m2", S("s1")) M("m3", S("s2"))), {{1,0},{1,1},{0,0}}, {{0,1},{0,0}}, false }, + { DN(YES) M("m1", M("m2", N(NO) S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{1,0},{0,1}}, false }, + { M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{0,1},{0,1},{0,1}}, {{0,1},{0,1}}, true }, + { DN() M("m1", M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{0,1},{0,1}}, true }, + { DN() M("m1", DN(NO) M("m2", S("s1")) M("m3", S("s2"))), {{1,1},{1,0},{0,1}}, {{0,0},{0,1}}, true }, + { DN(NO) M("m1", DN(YES) M("m2", S("s1")) M("m3", S("s2"))), {{1,0},{1,1},{0,0}}, {{0,1},{0,0}}, true }, + { DN(YES) M("m1", M("m2", N(NO) S("s1")) M("m3", S("s2"))), {{1,1},{0,1},{0,1}}, {{1,0},{0,1}}, true }, }; static const size_t n = sizeof(tests)/sizeof(tests[0]); @@ -449,7 +455,13 @@ CU_Test(idl_annotation, default_nested) for (size_t i=0; i < n; i++) { pstate = NULL; - ret = parse_string(IDL_FLAG_ANNOTATIONS, tests[i].str, &pstate); + ret = idl_create_pstate(IDL_FLAG_ANNOTATIONS, NULL, &pstate); + if (IDL_RETCODE_OK == ret) { + pstate->config.default_extensibility = IDL_FINAL; + pstate->config.default_nested = tests[i].pstate_default_nested; + ret = idl_parse_string(pstate, tests[i].str); + } + CU_ASSERT_EQUAL(ret, IDL_RETCODE_OK); if (ret == IDL_RETCODE_OK) { m = (idl_module_t *)pstate->root; @@ -473,7 +485,8 @@ CU_Test(idl_annotation, default_nested) CU_ASSERT(!tests[i].n[1].a == !s->nested.annotation); CU_ASSERT(s->nested.value == tests[i].n[1].v); } - idl_delete_pstate(pstate); + if (pstate) + idl_delete_pstate(pstate); } } #undef M diff --git a/src/tools/idlc/src/idlc.c b/src/tools/idlc/src/idlc.c index bc25c228..3ea2edb7 100644 --- a/src/tools/idlc/src/idlc.c +++ b/src/tools/idlc/src/idlc.c @@ -59,6 +59,7 @@ static struct { int keylist; int case_sensitive; int default_extensibility; + bool default_nested; struct idlc_disable_warning_list disable_warnings; int help; int version; @@ -314,6 +315,7 @@ static idl_retcode_t idlc_parse(void) pstate->scanner.position.column = 1; pstate->config.flags |= IDL_WRITE; pstate->config.default_extensibility = config.default_extensibility; + pstate->config.default_nested = config.default_nested; pstate->config.disable_warnings = config.disable_warnings.list; pstate->config.n_disable_warnings = config.disable_warnings.count; } @@ -442,6 +444,18 @@ static int config_default_extensibility(const idlc_option_t *opt, const char *ar return 0; } +static int config_default_nested(const idlc_option_t *opt, const char *arg) +{ + (void)opt; + if (strcmp(arg, "true") == 0) + config.default_nested = true; + else if (strcmp(arg, "false") == 0) + config.default_nested = false; + else + return IDLC_BAD_ARGUMENT; + return 0; +} + static int add_disable_warning(idl_warning_t warning) { if (config.disable_warnings.count == config.disable_warnings.size) { @@ -539,6 +553,12 @@ static const idlc_option_t *compopts[] = { "Set the default extensibility that is used in case no extensibility" "is set on a type. Possible values are final, appendable and mutable. " "(default: final)" }, + &(idlc_option_t){ + IDLC_FUNCTION, { .function = &config_default_nested }, 'n', "", "", + "Set the default nestedness that is used in the absence of nestedness specifiers on a type " + "(@topic/nested), or other specifiers in its hierarchy (@default_nestedness on modules), " + "with an unset nestedness implicitly being false. Possible values for this option are: true, " + "false (default: true). " }, &(idlc_option_t){ IDLC_FUNCTION, { .function = &config_warning }, 'W', "", "", "Enable or disable warnings. Possible values are: no-implicit-extensibility, " @@ -602,6 +622,7 @@ int main(int argc, char *argv[]) config.compile = 1; config.preprocess = 1; config.default_extensibility = IDL_DEFAULT_EXTENSIBILITY_UNDEFINED; + config.default_nested = false; config.disable_warnings.list = NULL; config.disable_warnings.size = 0; config.disable_warnings.count = 0; From 63ac81fc05ead221191c2a48dd12bb28f039cf88 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 23 Mar 2022 12:48:27 +0100 Subject: [PATCH 03/27] Add thread_state_awake when using entity index for re-matching when types are resolved Signed-off-by: Dennis Potman --- src/core/ddsi/src/ddsi_typelib.c | 2 ++ src/core/ddsi/src/q_entity.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index ee799c7d..ac264453 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -648,6 +648,7 @@ uint32_t ddsi_type_get_gpe_matches (struct ddsi_domaingv *gv, const struct ddsi_ return 0; uint32_t n = 0; + thread_state_awake (lookup_thread_state (), gv); *gpe_match_upd = ddsrt_realloc (*gpe_match_upd, (*n_match_upd + ddsi_type_proxy_guid_list_count (&type->proxy_guids)) * sizeof (**gpe_match_upd)); struct ddsi_type_proxy_guid_list_iter it; for (ddsi_guid_t guid = ddsi_type_proxy_guid_list_iter_first (&type->proxy_guids, &it); !is_null_guid (&guid); guid = ddsi_type_proxy_guid_list_iter_next (&it)) @@ -664,6 +665,7 @@ uint32_t ddsi_type_get_gpe_matches (struct ddsi_domaingv *gv, const struct ddsi_ } *n_match_upd += n; ddsi_type_register_with_proxy_endpoints_locked (gv, type); + thread_state_asleep (lookup_thread_state ()); return n; } diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index 1ce7f8de..d55ca35a 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -3329,6 +3329,7 @@ void update_proxy_endpoint_matching (const struct ddsi_domaingv *gv, struct gene const char *tp = entity_topic_name (&proxy_ep->e); ddsrt_mtime_t tnow = ddsrt_time_monotonic (); + thread_state_awake (lookup_thread_state (), gv); entidx_enum_init_topic (&it, gv->entity_index, mkind, tp, &max); while ((em = entidx_enum_next_max (&it, &max)) != NULL) { @@ -3336,6 +3337,7 @@ void update_proxy_endpoint_matching (const struct ddsi_domaingv *gv, struct gene generic_do_match_connect (&proxy_ep->e, em, tnow, false); } entidx_enum_fini (&it); + thread_state_asleep (lookup_thread_state ()); } From 847ddfb23429fd58222f637a702ade3a7b855394 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 23 Mar 2022 13:32:52 +0100 Subject: [PATCH 04/27] Bugfix in resolving type dependencies: in case type info from proxy endpoint was received before creating local topic using the same top-level type, the type object for the local type dependencies was not added in the type library Signed-off-by: Dennis Potman --- src/core/ddsi/src/ddsi_typelib.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index ac264453..2ae3135f 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -323,18 +323,6 @@ static struct ddsi_type * ddsi_type_new (struct ddsi_domaingv *gv, const struct return type; } -static bool type_has_dep (const struct ddsi_type *type, const struct DDS_XTypes_TypeIdentifier *dep_type_id) -{ - struct ddsi_type_dep *dep = type->deps; - while (dep) - { - if (!ddsi_typeid_compare_impl (&dep->type->xt.id.x, dep_type_id)) - return true; - dep = dep->prev; - } - return false; -} - static void type_add_dep (struct ddsi_domaingv *gv, struct ddsi_type *type, const struct DDS_XTypes_TypeIdentifier *dep_type_id, const struct DDS_XTypes_TypeObject *dep_type_obj, uint32_t *n_match_upd, struct generic_proxy_endpoint ***gpe_match_upd) { struct ddsi_typeid_str tistr, tistrdep; @@ -376,11 +364,22 @@ static void type_add_deps (struct ddsi_domaingv *gv, struct ddsi_type *type, con for (uint32_t n = 0; dep_ids && n < dep_ids->_length; n++) { const struct DDS_XTypes_TypeIdentifier *dep_type_id = &dep_ids->_buffer[n].type_id; - if (ddsi_typeid_compare_impl (&type->xt.id.x, dep_type_id) && !type_has_dep (type, dep_type_id)) + if (!ddsi_typeid_compare_impl (&type->xt.id.x, dep_type_id)) + continue; + const struct DDS_XTypes_TypeObject *dep_type_obj = type_map ? ddsi_typemap_typeobj (type_map, dep_type_id) : NULL; + struct ddsi_type_dep *dep = type->deps; + while (dep) { - const struct DDS_XTypes_TypeObject *dep_type_obj = type_map ? ddsi_typemap_typeobj (type_map, dep_type_id) : NULL; - type_add_dep (gv, type, dep_type_id, dep_type_obj, n_match_upd, gpe_match_upd); + if (!ddsi_typeid_compare_impl (&dep->type->xt.id.x, dep_type_id) && dep_type_obj != NULL && ddsi_xt_type_add_typeobj (gv, &dep->type->xt, dep_type_obj) == DDS_RETCODE_OK) + { + dep->type->state = DDSI_TYPE_RESOLVED; + (void) ddsi_type_get_gpe_matches (gv, dep->type, gpe_match_upd, n_match_upd); + break; + } + dep = dep->prev; } + if (!dep) + type_add_dep (gv, type, dep_type_id, dep_type_obj, n_match_upd, gpe_match_upd); } } } From 6219a721e9726fb330db0f83213240d6c144d274 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 28 Mar 2022 13:32:22 +0200 Subject: [PATCH 05/27] Check type lookup request/reply type As the getDependencies service operation for the type lookup service is not supported yet, the code that handles the requests and replies should check that the message is a getTypes request or reponse. Signed-off-by: Dennis Potman --- src/core/ddsi/src/ddsi_typelookup.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/core/ddsi/src/ddsi_typelookup.c b/src/core/ddsi/src/ddsi_typelookup.c index 161d0b94..2210dcc5 100644 --- a/src/core/ddsi/src/ddsi_typelookup.c +++ b/src/core/ddsi/src/ddsi_typelookup.c @@ -172,6 +172,13 @@ void ddsi_tl_handle_request (struct ddsi_domaingv *gv, struct ddsi_serdata *d) DDS_Builtin_TypeLookup_Request req; memset (&req, 0, sizeof (req)); ddsi_serdata_to_sample (d, &req, NULL, NULL); + if (req.data._d != DDS_Builtin_TypeLookup_getTypes_HashId) + { + GVTRACE (" handle-tl-req wr "PGUIDFMT " unknown req-type %"PRIi32, PGUID (from_guid (&req.header.requestId.writer_guid)), req.data._d); + ddsi_sertype_free_sample (d->type, &req, DDS_FREE_CONTENTS); + return; + } + GVTRACE (" handle-tl-req wr "PGUIDFMT " seqnr %"PRIu64" ntypeids %"PRIu32, PGUID (from_guid (&req.header.requestId.writer_guid)), from_seqno (&req.header.requestId.sequence_number), req.data._u.getTypes.type_ids._length); ddsrt_mutex_lock (&gv->typelib_lock); @@ -221,6 +228,13 @@ void ddsi_tl_handle_reply (struct ddsi_domaingv *gv, struct ddsi_serdata *d) DDS_Builtin_TypeLookup_Reply reply; memset (&reply, 0, sizeof (reply)); ddsi_serdata_to_sample (d, &reply, NULL, NULL); + if (reply.return_data._d != DDS_Builtin_TypeLookup_getTypes_HashId) + { + GVTRACE (" handle-tl-reply wr "PGUIDFMT " unknown reply-type %"PRIi32, PGUID (from_guid (&reply.header.requestId.writer_guid)), reply.return_data._d); + ddsi_sertype_free_sample (d->type, &reply, DDS_FREE_CONTENTS); + return; + } + bool resolved = false; ddsrt_mutex_lock (&gv->typelib_lock); GVTRACE ("handle-tl-reply wr "PGUIDFMT " seqnr %"PRIu64" ntypeids %"PRIu32"\n", PGUID (from_guid (&reply.header.requestId.writer_guid)), from_seqno (&reply.header.requestId.sequence_number), reply.return_data._u.getType._u.result.types._length); From 163e13fee3ad76089ad7b20ace75f3aaac0c61ba Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 28 Mar 2022 16:46:43 +0200 Subject: [PATCH 06/27] Fix find_package_handle_standard_args in FindLcov Signed-off-by: Dennis Potman --- cmake/Modules/FindLcov.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/FindLcov.cmake b/cmake/Modules/FindLcov.cmake index dc2eebb7..de4aba52 100644 --- a/cmake/Modules/FindLcov.cmake +++ b/cmake/Modules/FindLcov.cmake @@ -78,7 +78,7 @@ include(FindPackageHandleStandardArgs) find_program(LCOV_BIN lcov) find_program(GENINFO_BIN geninfo) find_program(GENHTML_BIN genhtml) -find_package_handle_standard_args(lcov +find_package_handle_standard_args(Lcov REQUIRED_VARS LCOV_BIN GENINFO_BIN GENHTML_BIN ) From 72bc6cae9690ec37445288a0cc87e31f4123675c Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 28 Mar 2022 17:26:29 +0200 Subject: [PATCH 07/27] Set gcovr version to 5.0 Signed-off-by: Dennis Potman --- .azure/templates/build-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure/templates/build-test.yml b/.azure/templates/build-test.yml index f8076a12..db55d0fc 100644 --- a/.azure/templates/build-test.yml +++ b/.azure/templates/build-test.yml @@ -79,7 +79,7 @@ steps: pre-commit run --all-files name: run_pre_commit - bash: | - pip install gcovr --user --upgrade + pip install gcovr==5.0 --user --upgrade condition: eq(variables['coverage'], 'on') name: install_gcovr - bash: | From 4b0acfad591cec0641d771067d5d05fe59891959 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Mon, 28 Mar 2022 14:54:19 +0200 Subject: [PATCH 08/27] Fix memory leak when no network interfaces found Fixes Coverity issues 350494/350493. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_ownip.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ddsi/src/ddsi_ownip.c b/src/core/ddsi/src/ddsi_ownip.c index 6e06a8fe..bbf8e97d 100644 --- a/src/core/ddsi/src/ddsi_ownip.c +++ b/src/core/ddsi/src/ddsi_ownip.c @@ -273,7 +273,11 @@ static bool gather_interfaces (struct ddsi_domaingv * const gv, size_t *n_interf ddsrt_freeifaddrs (ifa_root); assert ((*n_interfaces > 0) == (*maxq_count > 0)); if (*n_interfaces == 0) + { GVERROR ("failed to find interfaces for \"%s\"\n", gv->m_factory->m_typename); + ddsrt_free (*maxq_list); + ddsrt_free (*interfaces); + } return (*n_interfaces > 0); } From b31d9fb57384037eba671ccdf59eda6d2bb0dea1 Mon Sep 17 00:00:00 2001 From: Martijn Reicher Date: Fri, 25 Mar 2022 10:52:28 +0100 Subject: [PATCH 09/27] Fix for coverity issue 349351 An unitialized array was passed as the in parameter to a function, fixed the issue by initializing this array to 0 Signed-off-by: Martijn Reicher --- src/tools/ddsperf/ddsperf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/ddsperf/ddsperf.c b/src/tools/ddsperf/ddsperf.c index f5645d5f..de24ab0f 100644 --- a/src/tools/ddsperf/ddsperf.c +++ b/src/tools/ddsperf/ddsperf.c @@ -2125,7 +2125,7 @@ int main (int argc, char *argv[]) sigset_t sigset, osigset; ddsrt_thread_t sigtid; #endif - char netload_if[256]; + char netload_if[256] = {0}; double netload_bw = -1; double rss_init = 0.0, rss_final = 0.0; ddsrt_threadattr_init (&attr); From ca066120ad376942af5e8f48a31d5595f4fe1613 Mon Sep 17 00:00:00 2001 From: Martijn Reicher Date: Fri, 25 Mar 2022 13:46:04 +0100 Subject: [PATCH 10/27] Fix for coverity issue 349352 Fix passing uninitialized crypto_session_key_t.data contents to print_octets function Signed-off-by: Martijn Reicher --- .../tests/encode_rtps_message/src/encode_rtps_message_utests.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c index bb900f16..1f556556 100644 --- a/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c +++ b/src/security/builtin_plugins/tests/encode_rtps_message/src/encode_rtps_message_utests.c @@ -464,7 +464,7 @@ crypto_decrypt_data( { bool result = true; EVP_CIPHER_CTX *ctx; - crypto_session_key_t session_key; + crypto_session_key_t session_key = {.data = {0} }; uint32_t key_size = crypto_get_key_size(CRYPTO_TRANSFORM_KIND(transformation_kind)); int len = 0; From 0cab815c83b058c0a6f560ccb1dd012bcbd4af4c Mon Sep 17 00:00:00 2001 From: Thijs Miedema Date: Wed, 30 Mar 2022 14:24:48 +0200 Subject: [PATCH 11/27] Fix cmake mistake --- cmake/CheckHashScript.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/CheckHashScript.cmake b/cmake/CheckHashScript.cmake index 4edc4bb2..f6f90218 100644 --- a/cmake/CheckHashScript.cmake +++ b/cmake/CheckHashScript.cmake @@ -3,11 +3,11 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Modules") include(HashUtilities) check_hashes( - OUTVAR _test + _test HASH_FILES ${HASH_FILES} APPEND_FILES ${APPEND_FILES} ) if (NOT ${_test}) message(FATAL_ERROR "Not up to date") -endif() \ No newline at end of file +endif() From 441c54ec24a58d55bfa5ff61e755295005d2adb4 Mon Sep 17 00:00:00 2001 From: LanderU Date: Thu, 31 Mar 2022 08:49:37 +0200 Subject: [PATCH 12/27] Fix Android port reference links Signed-off-by: LanderU --- ports/android/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/android/README.md b/ports/android/README.md index 0888e8f5..0173ce12 100644 --- a/ports/android/README.md +++ b/ports/android/README.md @@ -16,7 +16,7 @@ document. [1]: https://developer.android.com/studio [2]: https://stackoverflow.com/questions/43923996/adb-root-is-not-working-on-emulator-cannot-run-as-root-in-production-builds - * Download [Android Studio](1) and extract the archive. + * Download [Android Studio][1] and extract the archive. * Run `android-studio/bin/studio.sh` to launch the *Android Studio Setup Wizard* and install the *Android SDK*. Select the *Android Virtual Device* @@ -38,7 +38,7 @@ document. to download the emulator image. When the download is finished, select *Q*, click *Next*, then *Finish* to create the *Android Virtual Device (AVD)*. -> As can be read from [this StackOverflow post](2), it is important to NOT +> As can be read from [this StackOverflow post][2], it is important to NOT > select a *Google Play* image, as these images do not allow you to gain > root privileges. @@ -48,9 +48,9 @@ document. [3]: https://developer.android.com/ndk/guides/cmake [4]: https://developer.android.com/ndk/guides/cmake#variables -The [Android NDK supports CMake](3) via a toolchain file. Build parameters +The [Android NDK supports CMake][3] via a toolchain file. Build parameters such as ABI can specified on the command line. For the complete list of -supported variables, consult the [Toolchain Arguments](4) section. +supported variables, consult the [Toolchain Arguments][4] section. ``` $ cd cyclonedds @@ -137,7 +137,7 @@ $ ip rule add from all lookup main pref 99 * You should now be able to ping the host from the emulator and vice versa. -> The [KDE Community Wiki](5) is an excellent source of information on the +> The [KDE Community Wiki][5] is an excellent source of information on the > Android emulator. The second-to-last instruction stems from there and was > vital to establish communication between the emulator and the host. From 66f340ad3ef36a7c2a1eed7e52fe93b4bc906012 Mon Sep 17 00:00:00 2001 From: eboasson Date: Thu, 31 Mar 2022 18:35:49 +0200 Subject: [PATCH 13/27] Update README and added XTypes release notes (#1236) * Update README and added XTypes release notes Signed-off-by: Erik Boasson * Small clarifications in README Signed-off-by: Erik Boasson --- README.md | 281 +++++++++++++++++++++++------------- docs/dev/xtypes_relnotes.md | 44 ++++++ 2 files changed, 221 insertions(+), 104 deletions(-) create mode 100644 docs/dev/xtypes_relnotes.md diff --git a/README.md b/README.md index 9b5ec01a..4e0ef126 100644 --- a/README.md +++ b/README.md @@ -6,31 +6,117 @@ # Eclipse Cyclone DDS -Eclipse Cyclone DDS is a very performant and robust open-source DDS implementation. Cyclone DDS is developed completely in the open as an Eclipse IoT project -(see [eclipse-cyclone-dds](https://projects.eclipse.org/projects/iot.cyclonedds)) with a growing list of [adopters](https://iot.eclipse.org/adopters/?#iot.cyclonedds) (if you're one of them, please add your [logo](https://github.com/EclipseFdn/iot.eclipse.org/issues/new?template=adopter_request.md)). It is a tier-1 middleware for the Robot Operating System [ROS 2](https://docs.ros.org/en/rolling/). +Eclipse Cyclone DDS is a very performant and robust open-source implementation of the [OMG DDS specification](https://www.omg.org/spec/DDS/1.4/About-DDS/). +Cyclone DDS is developed completely in the open as an Eclipse IoT project (see [eclipse-cyclone-dds](https://projects.eclipse.org/projects/iot.cyclonedds)) with a growing list of [adopters](https://iot.eclipse.org/adopters/?#iot.cyclonedds) (if you're one of them, please add your [logo](https://github.com/EclipseFdn/iot.eclipse.org/issues/new?template=adopter_request.md)). +It is a tier-1 middleware for the Robot Operating System [ROS 2](https://docs.ros.org/en/rolling/). +* [What is DDS?](#what-is-dds) * [Getting Started](#getting-started) * [Performance](#performance) -* [Configuration](#configuration) - -> Consult the [roadmap](ROADMAP.md) for a high-level overview of upcoming features. +* [Configuration](#run-time-configuration) + +# What is DDS? + +DDS is the best-kept secret in distributed systems, one that has been around for much longer than most publish-subscribe messaging systems and still outclasses so many of them. +DDS is used in a wide variety of systems, including air-traffic control, jet engine testing, railway control, medical systems, naval command-and-control, smart greenhouses and much more. +In short, it is well-established in aerospace and defense but no longer limited to that. +And yet it is easy to use! + +Types are usually defined in IDL and preprocessed with the IDL compiler included in Cyclone, but our [Python binding](https://github.com/eclipse-cyclonedds/cyclonedds-python) allows you to define data types on the fly: +```Python +from dataclasses import dataclass +from cyclonedds.domain import DomainParticipant +from cyclonedds.core import Qos, Policy +from cyclonedds.pub import DataWriter +from cyclonedds.sub import DataReader +from cyclonedds.topic import Topic +from cyclonedds.idl import IdlStruct +from cyclonedds.idl.annotations import key +from time import sleep +import numpy as np +try: + from names import get_full_name + name = get_full_name() +except: + import os + name = f"{os.getpid()}" + +# C, C++ require using IDL, Python doesn't +@dataclass +class Chatter(IdlStruct, typename="Chatter"): + name: str + key("name") + message: str + count: int + +rng = np.random.default_rng() +dp = DomainParticipant() +tp = Topic(dp, "Hello", Chatter, qos=Qos(Policy.Reliability.Reliable(0))) +dw = DataWriter(dp, tp) +dr = DataReader(dp, tp) +count = 0 +while True: + sample = Chatter(name=name, message="Hello, World!", count=count) + count = count + 1 + print("Writing ", sample) + dw.write(sample) + for sample in dr.take(10): + print("Read ", sample) + sleep(rng.exponential()) +``` + +Today DDS is also popular in robotics and autonomous vehicles because those really depend on high-throuhgput, low-latency control systems without introducing a single point of failure by having a message broker in the middle. +Indeed, it is by far the most used and the default middleware choice in ROS 2. +It is used to transfer commands, sensor data and even video and point clouds between components. + +The OMG DDS specifications cover everything one needs to build systems using publish-subscribe messaging. +They define a structural type system that allows automatic endianness conversion and type checking between readers and writers. +This type system also supports type evolution. +The interoperable networking protocol and standard C++ API make it easy to build systems that integrate multiple DDS implementations. +Zero-configuration discovery is also included in the standard and supported by all implementations. + +DDS actually brings more: publish-subscribe messaging is a nice abstraction over "ordinary" networking, but plain publish-subscribe doesn't affect how one *thinks* about systems. +A very powerful architecture that truly changes the perspective on distributed systems is that of the "shared data space", in itself an old idea, and really just a distributed database. +Most shared data space designs have failed miserably in real-time control systems because they provided strong consistency guarantees and sacrificed too much performance and flexibility. +The *eventually consistent* shared data space of DDS has been very successful in helping with building systems that need to satisfy many "ilities": dependability, maintainability, extensibility, upgradeability, ... +Truth be told, that's why it was invented, and publish-subscribe messaging was simply an implementation technique. + +Cyclone DDS aims at full coverage of the specs and today already covers most of this. +Some optional parts are still missing. +With references to the individual OMG specifications: + +- [DCPS](https://www.omg.org/spec/DDS/1.4/PDF) the base specification + - zero configuration discovery (if multicast works) + - publish/subscribe messaging + - configurable storage of data in subscribers + - many QoS settings - liveliness monitoring, deadlines, historical data, ... + - coverage includes the Minimum, Ownership and (partially) Content profiles +- [DDS Security](https://www.omg.org/spec/DDS-SECURITY/1.1/PDF) - providing authentication, access control and encryption +- [DDS C++ API](https://www.omg.org/spec/DDS-PSM-Cxx/1.0/PDF) +- [DDS XTypes](https://www.omg.org/spec/DDS-XTypes/1.3/PDF) - the structural type system (some [caveats](docs/dev/xtypes_relnotes.md) here) +- [DDSI-RTPS](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF) - the interoperable network protocol + +The network stack in Cyclone DDS has been around for over a decade in one form or another and has proven itself in many systems, including large, high-availability ones and systems where interoperation with other implementations was needed. + +This repository provides the core of Cyclone DDS including its C API, the [OMG C++](https://github.com/eclipse-cyclonedds/cyclonedds-cxx) and the [Python](https://github.com/eclipse-cyclonedds/cyclonedds-python) language bindings are in sibling repositories. + +Consult the [roadmap](ROADMAP.md) for a high-level overview of upcoming features. # Getting Started ## Building Eclipse Cyclone DDS -In order to build Cyclone DDS you need a Linux, Mac or Windows 10 machine (or, with some caveats, a *BSD, OpenIndiana or a Solaris 2.6 one) with the following installed on your host: +In order to build Cyclone DDS you need a Linux, Mac or Windows 10 machine (or, with some caveats, a *BSD, QNX, OpenIndiana or a Solaris 2.6 one) with the following installed on your host: * C compiler (most commonly GCC on Linux, Visual Studio on Windows, Xcode on macOS); - * GIT version control system; + * Optionally GIT version control system; * [CMake](https://cmake.org/download/), version 3.10 or later; - * [OpenSSL](https://www.openssl.org/), preferably version 1.1 or later if you want to use TLS over - TCP. You can explicitly disable it by setting ``ENABLE_SSL=NO``, which is very useful for - reducing the footprint or when the FindOpenSSL CMake script gives you trouble; + * Optionally [OpenSSL](https://www.openssl.org/), preferably version 1.1; + * Optionally [Eclipse Iceoryx](https://iceoryx.io) version 2.0 for shared memory and zero-copy support; * Optionally [Bison](https://www.gnu.org/software/bison/) parser generator. A cached source is checked into the repository. -If you want to play around with the parser you will need to install the bison parser generator. On Ubuntu ``apt install bison`` should do the trick for getting it installed. -On Windows, installing chocolatey and ``choco install winflexbison3`` should get you a long way. On macOS, ``brew install bison`` is easiest. +If you want to play around with the parser you will need to install the bison parser generator. On Ubuntu `apt install bison` should do the trick for getting it installed. +On Windows, installing chocolatey and `choco install winflexbison3` should get you a long way. On macOS, `brew install bison` is easiest. To obtain Eclipse Cyclone DDS, do @@ -38,30 +124,44 @@ To obtain Eclipse Cyclone DDS, do $ cd cyclonedds $ mkdir build -Depending on whether you want to develop applications using Cyclone DDS or contribute to it you can -follow different procedures +Depending on whether you want to develop applications using Cyclone DDS or contribute to it you can follow different procedures: + +### Build configuration + +There are some configuration options specified using CMake defines in addition to the standard options like `CMAKE_BUILD_TYPE`: + +* `-DBUILD_EXAMPLES=ON`: to build the included examples +* `-DBUILD_TESTING=ON`: to build the test suite (this requires [CUnit](http://cunit.sourceforge.net/), see [Contributing to Eclipse Cyclone DDS](#contributing-to-eclipse-cyclone-dds) below for more information) +* `-DBUILD_IDLC=NO`: to disable building the IDL compiler (affects building examples, tests and `ddsperf`) +* `-DBUILD_DDSPERF=NO`: to disable building the [`ddsperf`](https://github.com/eclipse-cyclonedds/cyclonedds/tree/master/src/tools/ddsperf) tool for performance measurement +* `-DENABLE_SSL=NO`: to not look for OpenSSL, remove TLS/TCP support and avoid building the plugins that implement authentication and encryption (default is `AUTO` to enable them if OpenSSL is found) +* `-DENABLE_SHM=NO`: to not look for Iceoryx and disabled shared memory support (default is `AUTO` to enable it if Iceoryx is found) +* `-DENABLE_SECURITY=NO`: to not build the security interfaces and hooks in the core code, nor the plugins (one can enable security without OpenSSL present, you'll just have to find plugins elsewhere in that case) +* `-DENABLE_LIFESPAN=NO`: to exclude support for finite lifespans QoS +* `-DENABLE_DEADLINE_MISSED=NO`: to exclude support for finite deadline QoS settings +* `-DENABLE_TYPE_DISCOVERY=YES`: to include support for type discovery and checking type compatibility (likely to become enabled by default in the future) +* `-DENABLE_TOPIC_DISCOVERY=YES`: to include support for topic discovery (requires `-DENABLE_TYPE_DISCOVERY=YES`; somewhat likely to become enabled by default in the future) ### For application developers To build and install the required libraries needed to develop your own applications using Cyclone -DDS requires a few simple steps. There are some small differences between Linux and macOS on the one -hand, and Windows on the other. For Linux or macOS: +DDS requires a few simple steps. +There are some small differences between Linux and macOS on the one +hand, and Windows on the other. +For Linux or macOS: $ cd build - $ cmake -DCMAKE_INSTALL_PREFIX= -DBUILD_EXAMPLES=ON .. + $ cmake -DCMAKE_INSTALL_PREFIX= .. $ cmake --build . and for Windows: $ cd build - $ cmake -G "" -DCMAKE_INSTALL_PREFIX= -DBUILD_EXAMPLES=ON .. + $ cmake -G "" -DCMAKE_INSTALL_PREFIX= .. $ cmake --build . -where you should replace ```` by the directory under which you would like to -install Cyclone DDS and ```` by one of the ways -CMake [generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) offer for -generating build files. For example, "Visual Studio 15 2017 Win64" would target a 64-bit build -using Visual Studio 2017. +where you should replace `` by the directory under which you would like to install Cyclone DDS and `` by one of the ways CMake [generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) offer for generating build files. +For example, "Visual Studio 15 2017 Win64" would target a 64-bit build using Visual Studio 2017. To install it after a successful build, do: @@ -69,59 +169,49 @@ To install it after a successful build, do: which will copy everything to: - * ``/lib`` - * ``/bin`` - * ``/include/ddsc`` - * ``/share/CycloneDDS`` + * `/lib` + * `/bin` + * `/include/ddsc` + * `/share/CycloneDDS` Depending on the installation location you may need administrator privileges. At this point you are ready to use Eclipse Cyclone DDS in your own projects. -Note that the default build type is a release build with debug information included -(RelWithDebInfo), which is generally the most convenient type of build to use from applications -because of a good mix between performance and still being able to debug things. If you'd rather -have a Debug or pure Release build, set ``CMAKE_BUILD_TYPE`` accordingly. +Note that the default build type is a release build with debug information included (RelWithDebInfo), which is generally the most convenient type of build to use from applications because of a good mix between performance and still being able to debug things. If you'd rather have a Debug or pure Release build, set `CMAKE_BUILD_TYPE` accordingly. ### Contributing to Eclipse Cyclone DDS We very much welcome all contributions to the project, whether that is questions, examples, bug -fixes, enhancements or improvements to the documentation, or anything else really. When considering -contributing code, it might be good to know that build configurations for Travis CI and AppVeyor are -present in the repository and that there is a test suite using CTest and CUnit that can be built -locally if desired. To build it, set the cmake variable ``BUILD_TESTING`` to on when configuring, e.g.: +fixes, enhancements or improvements to the documentation, or anything else really. +When considering contributing code, it might be good to know that build configurations for Azure pipelines are present in the repository and that there is a test suite using CTest and CUnit that can be built locally if desired. +To build it, set the cmake variable `BUILD_TESTING` to on when configuring, e.g.: $ cd build $ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON .. $ cmake --build . $ ctest -Such a build requires the presence of [CUnit](http://cunit.sourceforge.net/). You can install this -yourself, or you can choose to instead rely on the [Conan](https://conan.io) packaging system that -the CI build infrastructure also uses. In that case, install Conan and do: +Such a build requires the presence of [CUnit](http://cunit.sourceforge.net/). +You can install this yourself, or you can choose to instead rely on the [Conan](https://conan.io) packaging system that the CI build infrastructure also uses. +In that case, install Conan and do: $ conan install .. --build missing in the build directory prior to running cmake. -For Windows, depending on the generator, you might also need to add switches to select the architecture -and build type, e.g., ``conan install -s arch=x86_64 -s build_type=Debug ..`` This will automatically -download and/or build CUnit (and, at the moment, OpenSSL). +For Windows, depending on the generator, you might also need to add switches to select the architecture and build type, e.g., `conan install -s arch=x86_64 -s build_type=Debug ..` +This will automatically download and/or build CUnit (and, at the moment, OpenSSL). ## Documentation -The documentation is still rather limited, and at the moment only available in the sources (in the -form of restructured text files in ``docs`` and Doxygen comments in the header files), or as -a -[PDF](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/pdf/CycloneDDS-0.1.0.pdf). The -intent is to automate the process of building the documentation and have them available in more -convenient formats and in the usual locations. +The [documentation](https://cyclonedds.io) is still rather limited and some parts of it are still only available in the form of text files in the `docs` directory. +This README is usually out-of-date and the state of the documentation is slowly improving, so it definitely worth hopping over to have a look. ## Building and Running the Roundtrip Example -We will show you how to build and run an example program that measures latency. The examples are -built automatically when you build Cyclone DDS, so you don't need to follow these steps to be able -to run the program, it is merely to illustrate the process. +We will show you how to build and run an example program that measures latency. +The examples are built automatically when you build Cyclone DDS, so you don't need to follow these steps to be able to run the program, it is merely to illustrate the process. $ mkdir roundtrip $ cd roundtrip @@ -152,35 +242,29 @@ On another terminal, start the application that will be sending the pings: 9 28242 17 16 24 132 28242 8 6 28242 1 0 10 28075 17 16 23 46 28075 8 6 28075 1 0 -The numbers above were measured on Mac running a 4.2 GHz Intel Core i7 on December 12th 2018. From -these numbers you can see how the roundtrip is very stable and the minimal latency is now down to 17 -micro-seconds (used to be 25 micro-seconds) on this HW. +The numbers above were measured on Mac running a 4.2 GHz Intel Core i7 on December 12th 2018. +From these numbers you can see how the roundtrip is very stable and the minimal latency is now down to 17 micro-seconds (used to be 25 micro-seconds) on this HW. # Performance Reliable message throughput is over 1MS/s for very small samples and is roughly 90% of GbE with 100 -byte samples, and latency is about 30us when measured using [ddsperf](src/tools/ddsperf) between two -Intel(R) Xeon(R) CPU E3-1270 V2 @ 3.50GHz (that's 2012 hardware ...) running Ubuntu 16.04, with the -executables built on Ubuntu 18.04 using gcc 7.4.0 for a default (i.e., "RelWithDebInfo") build. +byte samples, and latency is about 30us when measured using [ddsperf](src/tools/ddsperf) between two Intel(R) Xeon(R) CPU E3-1270 V2 @ 3.50GHz (that's 2012 hardware ...) running Ubuntu 16.04, with the executables built on Ubuntu 18.04 using gcc 7.4.0 for a default (i.e., "RelWithDebInfo") build. ThroughputThroughput This is with the subscriber in listener mode, using asynchronous delivery for the throughput -test. The configuration is a marginally tweaked out-of-the-box configuration: an increased maximum +test. +The configuration is a marginally tweaked out-of-the-box configuration: an increased maximum message size and fragment size, and an increased high-water mark for the reliability window on the -writer side. For details, see the [scripts](examples/perfscript) directory, +writer side. +For details, see the [scripts](examples/perfscript) directory, the -[environment details](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/config.txt) and -the -[throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/sub.log) and -[latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/ping.log) data -underlying the graphs. These also include CPU usage ([throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-cpu.png) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/latency-sync-listener-bwcpu.png)) and [memory usage](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-memory.png). +[environment details](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/config.txt) and the [throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/sub.log) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/ping.log) data underlying the graphs. These also include CPU usage ([throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-cpu.png) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/latency-sync-listener-bwcpu.png)) and [memory usage](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-memory.png). -# Configuration +# Run-time configuration -The out-of-the-box configuration should usually be fine, but there are a great many options that can -be tweaked by creating an XML file with the desired settings and defining the ``CYCLONEDDS_URI`` to -point to it. E.g. (on Linux): +The out-of-the-box configuration should usually be fine, but there are a great many options that can be tweaked by creating an XML file with the desired settings and defining the `CYCLONEDDS_URI` to point to it. +E.g. (on Linux): $ cat cyclonedds.xml @@ -192,7 +276,6 @@ point to it. E.g. (on Linux): default 65500B - 4000B @@ -201,52 +284,42 @@ point to it. E.g. (on Linux): config - stdout + cdds.log.${CYCLONEDDS_PID} $ export CYCLONEDDS_URI=file://$PWD/cyclonedds.xml -(on Windows, one would have to use ``set CYCLONEDDS_URI=file://...`` instead.) +(on Windows, one would have to use `set CYCLONEDDS_URI=file://...` instead.) This example shows a few things: -* ``Interfaces`` can be used to override the interfaces selected by default. Members are - * ``NetworkInterface[@autodetermine]`` tells Cyclone DDS to autoselect the interface it deems best. - * ``NetworkInterface[@name]`` specifies the name of an interface to select (not shown above, alternative for autodetermine). - * ``NetworkInterface[@ip]`` specifies the ipv4/ipv6 address of an interface to select (not shown above, alternative for autodetermine). - * ``NetworkInterface[@multicast]`` specifies whether multicast should be used on this interface. - The default value 'default' means Cyclone DDS will check the OS reported flags of the interface - and enable multicast if it is supported. Use 'true' to ignore what the OS reports and enable it - anyway and 'false' to always disable multicast on this interface. - * ``NetworkInterface[@priority]`` specifies the priority of an interface. The default value (``default``) - means priority ``0`` for normal interfaces and ``2`` for loopback interfaces. -* ``AllowMulticast`` configures the circumstances under which multicast will be used. If the - selected interface doesn't support it, it obviously won't be used (``false``); but if it does - support it, the type of the network adapter determines the default value. For a wired network, it - will use multicast for initial discovery as well as for data when there are multiple peers that - the data needs to go to (``true``); but on a WiFi network it will use it only for initial - discovery (``spdp``), because multicast on WiFi is very unreliable. -* ``Verbosity`` allows control over the tracing, "config" dumps the configuration to the trace - output (which defaults to "cyclonedds.log"). Which interface is used, what multicast settings are - used, etc., is all in the trace. Setting the verbosity to "finest" gives way more output on the - inner workings, and there are various other levels as well. -* ``MaxMessageSize`` and ``FragmentSize`` control the maximum size of the RTPS messages (basically - the size of the UDP payload), and the size of the fragments into which very large samples get - split (which needs to be "a bit" less). Large values such as these typically improve performance - over the (current) default values. -* ``WhcHigh`` determines when the sender will wait for acknowledgements from the readers because it - has buffered too much unacknowledged data. There is some auto-tuning, the (current) default value - is a bit small to get really high throughput. - -Background information on configuring Cyclone DDS can be found -[here](docs/manual/config.rst) and a list of settings is -[available](docs/manual/options.md). +* `Interfaces` can be used to override the interfaces selected by default. + Members are + * `NetworkInterface[@autodetermine]` tells Cyclone DDS to autoselect the interface it deems best. + * `NetworkInterface[@name]` specifies the name of an interface to select (not shown above, alternative for autodetermine). + * `NetworkInterface[@ip]` specifies the ipv4/ipv6 address of an interface to select (not shown above, alternative for autodetermine). + * `NetworkInterface[@multicast]` specifies whether multicast should be used on this interface. + The default value 'default' means Cyclone DDS will check the OS reported flags of the interface and enable multicast if it is supported. + Use 'true' to ignore what the OS reports and enable it anyway and 'false' to always disable multicast on this interface. + * `NetworkInterface[@priority]` specifies the priority of an interface. + The default value (`default`) means priority `0` for normal interfaces and `2` for loopback interfaces. +* `AllowMulticast` configures the circumstances under which multicast will be used. + If the selected interface doesn't support it, it obviously won't be used (`false`); but if it does support it, the type of the network adapter determines the default value. + For a wired network, it will use multicast for initial discovery as well as for data when there are multiple peers that the data needs to go to (`true`). + On a WiFi network it will use it only for initial discovery (`spdp`), because multicast on WiFi is very unreliable. +* `Verbosity` allows control over the tracing, "config" dumps the configuration to the trace output (which defaults to "cyclonedds.log", but here the process id is appended). + Which interface is used, what multicast settings are used, etc., is all in the trace. + Setting the verbosity to "finest" gives way more output on the inner workings, and there are various other levels as well. +* `MaxMessageSize` controls the maximum size of the RTPS messages (basically the size of the UDP payload). + Large values such as these typically improve performance over the (current) default values on a loopback interface. +* `WhcHigh` determines when the sender will wait for acknowledgements from the readers because it has buffered too much unacknowledged data. + There is some auto-tuning, the (current) default value is a bit small to get really high throughput. + +Background information on configuring Cyclone DDS can be found [here](docs/manual/config.rst) and a list of settings is [available](docs/manual/options.md). # Trademarks -* "Eclipse Cyclone DDS" and "Cyclone DDS" are trademarks of the Eclipse Foundation. - +* "Eclipse Cyclone DDS", "Cyclone DDS", "Eclipse Iceoryx" and "Iceoryx" are trademarks of the Eclipse Foundation. * "DDS" is a trademark of the Object Management Group, Inc. - * "ROS" is a trademark of Open Source Robotics Foundation, Inc. diff --git a/docs/dev/xtypes_relnotes.md b/docs/dev/xtypes_relnotes.md new file mode 100644 index 00000000..90415773 --- /dev/null +++ b/docs/dev/xtypes_relnotes.md @@ -0,0 +1,44 @@ +# Cyclone XTypes support + +## Release 0.9 + +### Type System + +- The following data types are not supported: map, bitset, wide-strings, char16, float128 +- For the C language binding, additionally the following types are not supported as part of a type’s key: union, sequence +- Union types: + - Using bitmask type as discriminator is not supported + - Inheritance (7.2.2.4.5) is not supported + - Extensibility `mutable` for unions is not supported +- The Dynamic Language Binding (7.5.2) is not supported (7.6.6, DynamicData and DynamicType API). Note: the Python API supports dynamic types without requiring a separate API. +- The built-in TypeLookup service (7.6.3.3) has no support for requesting type dependencies (service operation `getTypeDependencies`, section 7.6.3.3.4.1) and replying to a request of this type. + - Because of this, handling `PublicationBuiltinTopicData` or `SubscriptionBuiltinTopicData` with an incomplete set of dependent types (i.e. number of entries in `dependent_typeids` is less than `dependent_typeid_count`) may result in a failure to match a reader with a writer. +- In case a union has a default case, the C (de)serializer requires that the default case comes last because of a limitation of the IDL compiler. +- Using the `try_construct` annotation (7.2.2.7) with a parameter other than `DISCARD` (the default) is not supported. +- The C deserializer does not support explicit defaults for members of an aggregated type (`default` annotation) +- External (7.3.1.2.1.4) collections element types not supported (e.g. `sequence<@external b>`) +- Using `default_literal` (7.3.1.2.1.10) to set the default for enumerated types is not supported +- Default extensibility is `final` rather than `appendable` to maintain backwards compatibility with DDS implementations that do not support XTypes (including Cyclone DDS versions prior to 0.9.0). The IDL compiler has command-line option to select a different default. + +### Type Representation + +- Type Object type representation + - Recursive types are not supported (Strongly Connected Components, 7.3.4.9) + - User-defined annotations (7.3.1.2.4) and `verbatim` annotations (7.3.2.5.1.1) are not included in complete type objects +- IDL type representation + - Pragma declarations other than `keylist` are not supported + - Alternative Annotation Syntax (7.3.1.2.3) is not supported + - `verbatim` annotation (7.3.2.5.1.1) is not supported + - `ignore_literal_names` annotation (7.3.1.2.1.11) is not supported + - `non_serialized` annotation (7.3.1.2.1.14) is not supported +- XML (7.3.2) and XSD (7.3.3) type representation not supported + +### Data Representation + +- Default data representation is XCDR1 for `@final` types without optional members to maintain backwards compatibility with DDS implementations that do not support XTypes (including Cyclone DDS versions prior to 0.9.0). + + All other types require XCDR2: following 7.6.3.1.1 there is no need to support XCDR1 for interoperating with DDS implementations (ignoring those that only support XTypes 1.0 or 1.1, but not 1.2 or later). + + The C serializer does not support PL-CDR version 1 nor optional members in PLAIN-CDR version 1. + +- XML data representation (7.4.4) is not supported \ No newline at end of file From 436f470197f5ae9904bbdffaf4818ba80f774a0f Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 21 Apr 2022 15:57:23 +0200 Subject: [PATCH 14/27] Reword confusing README phrasing Signed-off-by: Erik Boasson --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 4e0ef126..53047154 100644 --- a/README.md +++ b/README.md @@ -82,8 +82,7 @@ The *eventually consistent* shared data space of DDS has been very successful in Truth be told, that's why it was invented, and publish-subscribe messaging was simply an implementation technique. Cyclone DDS aims at full coverage of the specs and today already covers most of this. -Some optional parts are still missing. -With references to the individual OMG specifications: +With references to the individual OMG specifications, the following is available: - [DCPS](https://www.omg.org/spec/DDS/1.4/PDF) the base specification - zero configuration discovery (if multicast works) From a128c0f7c7ab1fbe428f2a35d44317fc82a06fb0 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 11 Apr 2022 21:57:27 +0200 Subject: [PATCH 15/27] Fix bug in validation of type_information parameter value in discovery data Signed-off-by: Dennis Potman --- src/core/ddsi/src/ddsi_plist.c | 2 +- src/core/ddsi/src/ddsi_typelib.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/ddsi/src/ddsi_plist.c b/src/core/ddsi/src/ddsi_plist.c index 9cabeafc..8dbff081 100644 --- a/src/core/ddsi/src/ddsi_plist.c +++ b/src/core/ddsi/src/ddsi_plist.c @@ -730,7 +730,7 @@ static dds_return_t ser_type_information (struct nn_xmsg *xmsg, nn_parameterid_t static dds_return_t valid_type_information (const void *src, size_t srcoff) { ddsi_typeinfo_t const * const * x = deser_generic_src (src, &srcoff, alignof (ddsi_typeinfo_t *)); - return *x != NULL && ddsi_typeinfo_valid (*x); + return (*x != NULL && ddsi_typeinfo_valid (*x)) ? DDS_RETCODE_OK : DDS_RETCODE_BAD_PARAMETER; } static bool equal_type_information (const void *srcx, const void *srcy, size_t srcoff) diff --git a/src/core/ddsi/src/ddsi_typelib.c b/src/core/ddsi/src/ddsi_typelib.c index 2ae3135f..b3c84103 100644 --- a/src/core/ddsi/src/ddsi_typelib.c +++ b/src/core/ddsi/src/ddsi_typelib.c @@ -134,7 +134,7 @@ const ddsi_typeid_t *ddsi_typeinfo_complete_typeid (const ddsi_typeinfo_t *typei return (const ddsi_typeid_t *) &typeinfo->x.complete.typeid_with_size.type_id; } -static bool typeinfo_dependent_typeids_valid (const struct DDS_XTypes_TypeIdentifierWithDependencies *t) +static bool typeinfo_dependent_typeids_valid (const struct DDS_XTypes_TypeIdentifierWithDependencies *t, ddsi_typeid_kind_t kind) { if (t->dependent_typeid_count == -1) { @@ -149,8 +149,9 @@ static bool typeinfo_dependent_typeids_valid (const struct DDS_XTypes_TypeIdenti return false; for (uint32_t n = 0; n < t->dependent_typeids._length; n++) { - if (!ddsi_typeid_is_minimal_impl (&t->dependent_typeids._buffer[n].type_id) || - t->dependent_typeids._buffer[n].typeobject_serialized_size == 0) + if ((kind == DDSI_TYPEID_KIND_MINIMAL && !ddsi_typeid_is_minimal_impl (&t->dependent_typeids._buffer[n].type_id)) + || (kind == DDSI_TYPEID_KIND_COMPLETE && !ddsi_typeid_is_complete_impl (&t->dependent_typeids._buffer[n].type_id)) + || t->dependent_typeids._buffer[n].typeobject_serialized_size == 0) return false; } } @@ -164,8 +165,8 @@ bool ddsi_typeinfo_valid (const ddsi_typeinfo_t *typeinfo) if (ddsi_typeid_is_none (tid_min) || !ddsi_typeid_is_hash (tid_min) || ddsi_typeid_is_none (tid_compl) || !ddsi_typeid_is_hash (tid_compl)) return false; - if (!typeinfo_dependent_typeids_valid (&typeinfo->x.minimal) || - !typeinfo_dependent_typeids_valid (&typeinfo->x.complete)) + if (!typeinfo_dependent_typeids_valid (&typeinfo->x.minimal, DDSI_TYPEID_KIND_MINIMAL) || + !typeinfo_dependent_typeids_valid (&typeinfo->x.complete, DDSI_TYPEID_KIND_COMPLETE)) return false; return true; } From 43c80a4b4a979357d6ed66d52104d058efa96bf9 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Mon, 11 Apr 2022 22:00:57 +0200 Subject: [PATCH 16/27] Set default TRY_CONSTRUCT flags in type object for collection elements, struct members and union members Signed-off-by: Dennis Potman --- src/tools/idlc/src/descriptor_type_meta.c | 83 +++++++++++++++-------- src/tools/idlc/tests/type_meta.c | 75 ++++++++++---------- 2 files changed, 95 insertions(+), 63 deletions(-) diff --git a/src/tools/idlc/src/descriptor_type_meta.c b/src/tools/idlc/src/descriptor_type_meta.c index 338051bf..4f54ed9e 100644 --- a/src/tools/idlc/src/descriptor_type_meta.c +++ b/src/tools/idlc/src/descriptor_type_meta.c @@ -198,6 +198,12 @@ has_fully_descriptive_typeid (const idl_type_spec_t *type_spec) static idl_retcode_t get_typeid(const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, const idl_type_spec_t *type_spec, bool alias_related_type, DDS_XTypes_TypeIdentifier *ti, DDS_XTypes_TypeKind kind, bool array_element); +static DDS_XTypes_CollectionElementFlag +get_sequence_element_flags(const idl_sequence_t *seq); + +static DDS_XTypes_CollectionElementFlag +get_array_element_flags(const idl_node_t *node); + static idl_retcode_t get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, const idl_type_spec_t *type_spec, bool alias_related_type, DDS_XTypes_TypeIdentifier *ti, DDS_XTypes_TypeKind kind) { @@ -220,6 +226,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, ti->_u.array_sdefn.element_identifier = calloc (1, sizeof (*ti->_u.array_sdefn.element_identifier)); if ((ret = get_typeid (pstate, dtm, type_spec, false, ti->_u.array_sdefn.element_identifier, kind, true)) < 0) return ret; + ti->_u.array_sdefn.header.element_flags = get_array_element_flags (type_spec); if (has_fully_descriptive_typeid_impl (type_spec, true, alias_related_type)) ti->_u.array_sdefn.header.equiv_kind = DDS_XTypes_EK_BOTH; else @@ -227,6 +234,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, } else { ti->_d = DDS_XTypes_TI_PLAIN_ARRAY_LARGE; ti->_u.array_ldefn.element_identifier = calloc (1, sizeof (*ti->_u.array_ldefn.element_identifier)); + ti->_u.array_ldefn.header.element_flags = get_array_element_flags (type_spec); for (; literal; literal = idl_next (literal)) { assert (literal->value.uint64 < UINT32_MAX); uint32_t val = literal->value.uint32; @@ -275,6 +283,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, if (!idl_is_bounded (seq) || seq->maximum <= UINT8_MAX) { ti->_d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL; ti->_u.seq_sdefn.bound = (uint8_t) seq->maximum; + ti->_u.seq_sdefn.header.element_flags = get_sequence_element_flags (seq); ti->_u.seq_sdefn.element_identifier = calloc (1, sizeof (*ti->_u.seq_sdefn.element_identifier)); if ((ret = get_typeid (pstate, dtm, idl_type_spec (type_spec), false, ti->_u.seq_sdefn.element_identifier, kind, false)) < 0) return ret; @@ -285,6 +294,7 @@ get_plain_typeid (const idl_pstate_t *pstate, struct descriptor_type_meta *dtm, } else { ti->_d = DDS_XTypes_TI_PLAIN_SEQUENCE_LARGE; ti->_u.seq_ldefn.bound = seq->maximum; + ti->_u.seq_ldefn.header.element_flags = get_sequence_element_flags (seq); ti->_u.seq_ldefn.element_identifier = calloc (1, sizeof (*ti->_u.seq_ldefn.element_identifier)); if ((ret = get_typeid (pstate, dtm, idl_type_spec (type_spec), false, ti->_u.seq_ldefn.element_identifier, kind, false)) < 0) return ret; @@ -386,19 +396,18 @@ static DDS_XTypes_StructMemberFlag get_struct_member_flags(const idl_member_t *member) { DDS_XTypes_StructMemberFlag flags = 0u; - if (member->try_construct.annotation) { - switch (member->try_construct.value) { - case IDL_DISCARD: - flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; - break; - case IDL_USE_DEFAULT: - flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT; - break; - case IDL_TRIM: - flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM; - break; - } + switch (member->try_construct.value) { + case IDL_DISCARD: + flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; + break; + case IDL_USE_DEFAULT: + flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT; + break; + case IDL_TRIM: + flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM; + break; } + if (member->external.value) flags |= DDS_XTypes_IS_EXTERNAL; if (member->key.value) @@ -434,6 +443,10 @@ static DDS_XTypes_UnionDiscriminatorFlag get_union_discriminator_flags(const idl_switch_type_spec_t *switch_type_spec) { DDS_XTypes_UnionDiscriminatorFlag flags = 0u; + + // FIXME: support non-default try-construct + flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; + // XTypes spec 7.2.2.4.4.4.6: In a union type, the discriminator member shall always have the 'must understand' attribute set to true flags |= DDS_XTypes_IS_MUST_UNDERSTAND; if (switch_type_spec->key.value) @@ -446,18 +459,16 @@ static DDS_XTypes_UnionMemberFlag get_union_case_flags(const idl_case_t *_case) { DDS_XTypes_UnionMemberFlag flags = 0u; - if (_case->try_construct.annotation) { - switch (_case->try_construct.value) { - case IDL_DISCARD: - flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; - break; - case IDL_USE_DEFAULT: - flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT; - break; - case IDL_TRIM: - flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM; - break; - } + switch (_case->try_construct.value) { + case IDL_DISCARD: + flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; + break; + case IDL_USE_DEFAULT: + flags |= DDS_XTypes_TRY_CONSTRUCT_USE_DEFAULT; + break; + case IDL_TRIM: + flags |= DDS_XTypes_TRY_CONSTRUCT_TRIM; + break; } if (_case->external.value) flags |= DDS_XTypes_IS_EXTERNAL; @@ -468,10 +479,13 @@ get_union_case_flags(const idl_case_t *_case) } static DDS_XTypes_CollectionElementFlag -get_collection_element_flags(const idl_sequence_t *seq) +get_sequence_element_flags(const idl_sequence_t *seq) { DDS_XTypes_CollectionElementFlag flags = 0u; + // FIXME: support non-default try-construct + flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; + (void) seq; // FIXME: support @external for sequence element type // if (seq->external) @@ -479,6 +493,21 @@ get_collection_element_flags(const idl_sequence_t *seq) return flags; } +static DDS_XTypes_CollectionElementFlag +get_array_element_flags(const idl_node_t *node) +{ + DDS_XTypes_CollectionElementFlag flags = 0u; + + // FIXME: support non-default try-construct + flags |= DDS_XTypes_TRY_CONSTRUCT_DISCARD; + + (void) node; + // FIXME: support @external for array element type + // if (arr->external) + // flags |= DDS_XTypes_IS_EXTERNAL; + return flags; +} + static DDS_XTypes_BitmaskTypeFlag get_bitmask_flags(const idl_bitmask_t *_bitmask) { @@ -988,7 +1017,7 @@ add_array ( if (!revisit) { dtm->stack->to_minimal->_u.minimal._u.array_type.element.common.element_flags = - dtm->stack->to_complete->_u.complete._u.array_type.element.common.element_flags = get_collection_element_flags (node); + dtm->stack->to_complete->_u.complete._u.array_type.element.common.element_flags = get_sequence_element_flags (node); if ((ret = get_complete_type_detail (type_spec, &dtm->stack->to_complete->_u.complete._u.array_type.header.detail)) < 0) return ret; @@ -1428,7 +1457,7 @@ emit_sequence( No need to include sequence_type.header.detail here, because sequences are anonymous types and there is no type name to store */ dtm->stack->to_minimal->_u.minimal._u.sequence_type.element.common.element_flags = - dtm->stack->to_complete->_u.complete._u.sequence_type.element.common.element_flags = get_collection_element_flags (node); + dtm->stack->to_complete->_u.complete._u.sequence_type.element.common.element_flags = get_sequence_element_flags (node); dtm->stack->to_minimal->_u.minimal._u.sequence_type.header.common.bound = dtm->stack->to_complete->_u.complete._u.sequence_type.header.common.bound = seq->maximum; return IDL_VISIT_REVISIT | IDL_VISIT_TYPE_SPEC; diff --git a/src/tools/idlc/tests/type_meta.c b/src/tools/idlc/tests/type_meta.c index 48fffc55..b5df38a8 100644 --- a/src/tools/idlc/tests/type_meta.c +++ b/src/tools/idlc/tests/type_meta.c @@ -202,7 +202,7 @@ static DDS_XTypes_TypeObject *get_typeobj_union(const char *name, uint16_t flags ._d = DDS_XTypes_TK_UNION, ._u.union_type = (DDS_XTypes_CompleteUnionType) { .union_flags = flags, - .discriminator = { .common = { .member_flags = DDS_XTypes_IS_MUST_UNDERSTAND, .type_id = disc_type } }, + .discriminator = { .common = { .member_flags = DDS_XTypes_IS_MUST_UNDERSTAND | DDS_XTypes_TRY_CONSTRUCT_DISCARD, .type_id = disc_type } }, .member_seq = { ._maximum = member_cnt, ._length = member_cnt, @@ -224,9 +224,9 @@ static DDS_XTypes_TypeObject *get_typeobj1 (void) DDS_XTypes_IS_APPENDABLE, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 3, (smember_t[]) { - { 0, DDS_XTypes_IS_KEY | DDS_XTypes_IS_MUST_UNDERSTAND, { ._d = DDS_XTypes_TK_INT64 }, "f1" }, - { 1, DDS_XTypes_IS_OPTIONAL, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2" }, - { 4, DDS_XTypes_IS_EXTERNAL, { ._d = DDS_XTypes_TK_CHAR8 }, "f3" } + { 0, DDS_XTypes_IS_KEY | DDS_XTypes_IS_MUST_UNDERSTAND | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT64 }, "f1" }, + { 1, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2" }, + { 4, DDS_XTypes_IS_EXTERNAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_CHAR8 }, "f3" } }); } @@ -237,8 +237,8 @@ static DDS_XTypes_TypeObject *get_typeobj2 (void) DDS_XTypes_IS_MUTABLE, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 2, (smember_t[]) { - { 0, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL, { ._d = DDS_XTypes_TK_UINT32 }, "f1" }, - { 1, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL, { ._d = DDS_XTypes_TK_UINT32 }, "f2" } + { 0, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_UINT32 }, "f1" }, + { 1, DDS_XTypes_IS_OPTIONAL | DDS_XTypes_IS_EXTERNAL | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_UINT32 }, "f2" } }); } @@ -249,8 +249,8 @@ static DDS_XTypes_TypeObject *get_typeobj3 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_INT16 }, 2, (umember_t[]) { - { 0, 0, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 1 } }, - { 1, DDS_XTypes_IS_EXTERNAL | DDS_XTypes_IS_DEFAULT, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2", 2, (int32_t[]) { 2, 3 } } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 1 } }, + { 1, DDS_XTypes_IS_EXTERNAL | DDS_XTypes_IS_DEFAULT | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TI_STRING8_SMALL, ._u.string_sdefn.bound = 0 }, "f2", 2, (int32_t[]) { 2, 3 } } }); } @@ -273,14 +273,14 @@ static DDS_XTypes_TypeObject *get_typeobj4 (void) DDS_XTypes_IS_MUTABLE | DDS_XTypes_IS_NESTED, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 1, (smember_t[]) { - { 5, 0, { ._d = DDS_XTypes_TK_INT32 }, "a1" } + { 5, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "a1" } })); return get_typeobj_struct ( "t4::test_struct", DDS_XTypes_IS_MUTABLE, ti_base, 1, (smember_t[]) { - { 10, 0, { ._d = DDS_XTypes_TK_INT32 }, "f1" } + { 10, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "f1" } }); } @@ -301,7 +301,7 @@ static DDS_XTypes_TypeObject *get_typeobj5 (void) .body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL, ._u.seq_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .bound = 0, .element_identifier = ti_long } @@ -314,7 +314,7 @@ static DDS_XTypes_TypeObject *get_typeobj5 (void) DDS_XTypes_TypeIdentifier ti_seq = { ._d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL, ._u.seq_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .bound = 0 } }; @@ -326,8 +326,8 @@ static DDS_XTypes_TypeObject *get_typeobj5 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 2, (smember_t[]) { - { 0, 0, ti_seq, "f1" }, - { 1, 0, ti_alias, "f2" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_seq, "f1" }, + { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_alias, "f2" } }); } @@ -345,7 +345,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) ti_f1 = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL, ._u.array_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = f1bound_seq, ._release = true }, .element_identifier = ti_f1_el } @@ -356,6 +356,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) // the other 2 fields. ti_f1._u.array_sdefn.array_bound_seq._buffer = f1bound_seq; ti_f1._u.array_sdefn.element_identifier = ti_f1_el; + ti_f1._u.array_sdefn.header.element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD; } /* f2 type identifier: string<555> f2[999][3] */ @@ -370,7 +371,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) ti_f2 = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_ARRAY_LARGE, ._u.array_ldefn = { - .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .array_bound_seq = { ._maximum = 2, ._length = 2, ._buffer = f2bound_seq, ._release = true }, .element_identifier = ti_f2_el } @@ -378,6 +379,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) // Clang's static analyzer ... ti_f2._u.array_ldefn.array_bound_seq._buffer = f2bound_seq; ti_f2._u.array_ldefn.element_identifier = ti_f2_el; + ti_f2._u.array_ldefn.header.element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD; } /* f3 type identifier: a[3] f3 */ @@ -389,7 +391,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) DDS_XTypes_IS_FINAL | DDS_XTypes_IS_NESTED, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 1, (smember_t[]) { - { 0, 0, { ._d = DDS_XTypes_TK_INT32 }, "a1" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "a1" } })); uint8_t *f3bound_seq = calloc (1, sizeof (*f3bound_seq)); @@ -397,7 +399,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) ti_f3 = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL, ._u.array_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = f3bound_seq, ._release = true }, .element_identifier = ti_a } @@ -405,6 +407,7 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) // Clang's static analyzer ... ti_f3._u.array_sdefn.array_bound_seq._buffer = f3bound_seq; ti_f3._u.array_sdefn.element_identifier = ti_a; + ti_f3._u.array_sdefn.header.element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD; } return get_typeobj_struct ( @@ -412,9 +415,9 @@ static DDS_XTypes_TypeObject *get_typeobj6 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 3, (smember_t[]) { - { 0, 0, ti_f1, "f1" }, - { 1, 0, ti_f2, "f2" }, - { 2, 0, ti_f3, "f3" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" }, + { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f2, "f2" }, + { 2, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f3, "f3" } }); } @@ -465,8 +468,8 @@ static DDS_XTypes_TypeObject *get_typeobj7 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 2, (smember_t[]) { - { 0, 0, ti_f1, "f1" }, - { 1, 0, ti_f2, "f2" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" }, + { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f2, "f2" } }); } @@ -485,7 +488,7 @@ static DDS_XTypes_TypeObject *get_typeobj8 (void) ti_f1 = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL, ._u.array_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .array_bound_seq = { ._maximum = 2, ._length = 2, ._buffer = f1bound_seq, ._release = true }, .element_identifier = ti_f1_el } @@ -497,7 +500,7 @@ static DDS_XTypes_TypeObject *get_typeobj8 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 1, (smember_t[]) { - { 0, 0, ti_f1, "f1" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" } }); } @@ -529,8 +532,8 @@ static DDS_XTypes_TypeObject *get_typeobj9 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 2, (smember_t[]) { - { 0, 0, ti_f, "f1" }, - { 1, 0, ti_f, "f2" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f1" }, + { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f2" } }); } @@ -562,8 +565,8 @@ static DDS_XTypes_TypeObject *get_typeobj10 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 2, (smember_t[]) { - { 0, 0, ti_f, "f1" }, - { 1, 0, ti_f, "f2" } + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f1" }, + { 1, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f, "f2" } }); } @@ -574,8 +577,8 @@ static DDS_XTypes_TypeObject *get_typeobj11 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_CHAR8 }, 2, (umember_t[]) { - { 99, 0, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 'a' } }, - { 5, DDS_XTypes_IS_DEFAULT, { ._d = DDS_XTypes_TK_UINT16 }, "f2", 0, (int32_t[]) { 0 } } + { 99, DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_INT32 }, "f1", 1, (int32_t[]) { 'a' } }, + { 5, DDS_XTypes_IS_DEFAULT | DDS_XTypes_TRY_CONSTRUCT_DISCARD, { ._d = DDS_XTypes_TK_UINT16 }, "f2", 0, (int32_t[]) { 0 } } }); } @@ -602,7 +605,7 @@ static DDS_XTypes_TypeObject *get_typeobj12 (void) .body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_SEQUENCE_SMALL, ._u.seq_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .bound = 0, .element_identifier = ti_long } @@ -624,7 +627,7 @@ static DDS_XTypes_TypeObject *get_typeobj12 (void) .body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL, ._u.array_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_COMPLETE, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = bound_seq, ._release = true }, .element_identifier = ti_alias_seq } @@ -639,7 +642,7 @@ static DDS_XTypes_TypeObject *get_typeobj12 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 1, (smember_t[]) { - { 0, 0, ti_f1, "f1" }, + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" }, }); } @@ -665,7 +668,7 @@ static DDS_XTypes_TypeObject *get_typeobj13 (void) .body = { .common = { .related_flags = 0, .related_type = (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TI_PLAIN_ARRAY_SMALL, ._u.array_sdefn = { - .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = 0 }, + .header = { .equiv_kind = DDS_XTypes_EK_BOTH, .element_flags = DDS_XTypes_TRY_CONSTRUCT_DISCARD }, .array_bound_seq = { ._maximum = 1, ._length = 1, ._buffer = bound_seq, ._release = true }, .element_identifier = ti_long } @@ -694,7 +697,7 @@ static DDS_XTypes_TypeObject *get_typeobj13 (void) DDS_XTypes_IS_FINAL, (DDS_XTypes_TypeIdentifier) { ._d = DDS_XTypes_TK_NONE }, 1, (smember_t[]) { - { 0, 0, ti_f1, "f1" }, + { 0, DDS_XTypes_TRY_CONSTRUCT_DISCARD, ti_f1, "f1" }, }); } From 2b318d7d423f0389a88f683a56c080257fa0f5da Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Tue, 10 May 2022 10:03:33 +0200 Subject: [PATCH 17/27] Initialize writer lease to NULL in case lease duration is not set (defaults to infinite) Signed-off-by: Dennis Potman --- src/core/ddsi/src/q_entity.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index d55ca35a..f04deeca 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -4000,6 +4000,10 @@ static dds_return_t new_writer_guid (struct writer **wr_out, const struct ddsi_g } } } + else + { + wr->lease = NULL; + } return 0; } From 7fbd7b07bc0105972da01a7a1c6cfcc42c3eccaa Mon Sep 17 00:00:00 2001 From: Sven Trittler <45872415+trittsv@users.noreply.github.com> Date: Tue, 10 May 2022 16:55:25 +0200 Subject: [PATCH 18/27] optional ipv6 support (#1272) * optional ipv6 support * add documentation for missing cmake options --- README.md | 2 ++ src/CMakeLists.txt | 1 + src/ddsrt/CMakeLists.txt | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 53047154..2a9b041d 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,8 @@ There are some configuration options specified using CMake defines in addition t * `-DENABLE_DEADLINE_MISSED=NO`: to exclude support for finite deadline QoS settings * `-DENABLE_TYPE_DISCOVERY=YES`: to include support for type discovery and checking type compatibility (likely to become enabled by default in the future) * `-DENABLE_TOPIC_DISCOVERY=YES`: to include support for topic discovery (requires `-DENABLE_TYPE_DISCOVERY=YES`; somewhat likely to become enabled by default in the future) +* `-DENABLE_SOURCE_SPECIFIC_MULTICAST=NO`: to disable support for source-specific multicast (disabling this and `-DENABLE_IPV6=NO` may be needed for QNX builds) +* `-DENABLE_IPV6=NO`: to disable ipv6 support (disabling this and `-DENABLE_SOURCE_SPECIFIC_MULTICAST=NO` may be needed for QNX builds) ### For application developers diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac30414c..8c0049c7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,7 @@ option(ENABLE_LIFESPAN "Enable Lifespan QoS support" ON) option(ENABLE_DEADLINE_MISSED "Enable Deadline Missed QoS support" ON) option(ENABLE_NETWORK_PARTITIONS "Enable network partition support" ON) option(ENABLE_SOURCE_SPECIFIC_MULTICAST "Enable support for source-specific multicast" ON) +option(ENABLE_IPV6 "Enable ipv6 support" ON) option(ENABLE_TYPE_DISCOVERY "Enable Type Discovery support" OFF) option(ENABLE_TOPIC_DISCOVERY "Enable Topic Discovery support" OFF) if(ENABLE_TOPIC_DISCOVERY) diff --git a/src/ddsrt/CMakeLists.txt b/src/ddsrt/CMakeLists.txt index 01fdec45..2e357365 100644 --- a/src/ddsrt/CMakeLists.txt +++ b/src/ddsrt/CMakeLists.txt @@ -160,8 +160,10 @@ if(DDSRT_HAVE_GETADDRINFO OR DDSRT_HAVE_GETHOSTBYNAME_R) set(DDSRT_HAVE_DNS TRUE) endif() check_type_size("struct sockaddr_in6" SIZEOF_SOCKADDR_IN6) -if(SIZEOF_SOCKADDR_IN6) - set(DDSRT_HAVE_IPV6 TRUE) +if(ENABLE_IPV6) + if(SIZEOF_SOCKADDR_IN6) + set(DDSRT_HAVE_IPV6 TRUE) + endif() endif() if(WITH_FREERTOS) From c87a797a81588107a7bb7901f49dea17ae251896 Mon Sep 17 00:00:00 2001 From: "john.fan" Date: Thu, 21 Apr 2022 14:56:52 +0800 Subject: [PATCH 19/27] fix zero pointer problem when we use tcp mode. Signed-off-by: john.fan --- src/core/ddsi/src/ddsi_tcp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index eca7e147..5dd0c4f4 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -805,6 +805,10 @@ static dds_return_t ddsi_tcp_create_conn (ddsi_tran_conn_t *conn_out, struct dds struct ddsi_tran_factory_tcp * const fact = (struct ddsi_tran_factory_tcp *) fact_cmn; (void) qos; (void) port; + struct ddsi_domaingv const * const gv = fact->fact.gv; + struct nn_interface const * const intf = qos->m_interface ? qos->m_interface : &gv->interfaces[0]; + + fact->ddsi_tcp_conn_client.m_base.m_interf = intf; *conn_out = &fact->ddsi_tcp_conn_client.m_base; return DDS_RETCODE_OK; } From 13a649e9459822d3735fc740184b27a5dff53d17 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Wed, 11 May 2022 11:35:18 +0200 Subject: [PATCH 20/27] Fix wrong unlock in participant sec attributes An incorrect call to "unlock" on an unlocked mutex causes a problem on QNX (and is illegal on all platforms). It should have been a call to "destroy". With that change, the three lines are identical to what "participant_sec_attributes_free" does. Signed-off-by: Erik Boasson --- src/core/ddsi/src/ddsi_security_omg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/ddsi/src/ddsi_security_omg.c b/src/core/ddsi/src/ddsi_security_omg.c index 717e81e4..48028abd 100644 --- a/src/core/ddsi/src/ddsi_security_omg.c +++ b/src/core/ddsi/src/ddsi_security_omg.c @@ -1259,9 +1259,7 @@ static void cleanup_participant_sec_attributes(void *arg) if (!sc->crypto_context->crypto_key_factory->unregister_participant(sc->crypto_context->crypto_key_factory, attr->crypto_handle, &exception)) EXCEPTION_ERROR(gv, &exception, "Failed to unregister participant"); - ddsrt_avl_cfree(&pp_proxypp_treedef, &attr->proxy_participants, NULL); - ddsrt_mutex_unlock(&attr->lock); - ddsrt_free(attr); + participant_sec_attributes_free(attr); ddsrt_free(arg); } From 06dd709d5e48719a62c39944b047545ea462d2a4 Mon Sep 17 00:00:00 2001 From: Dennis Potman Date: Wed, 11 May 2022 14:41:41 +0200 Subject: [PATCH 21/27] Fix incorrect memdup src address for array bounds in xtypes wrapper Signed-off-by: Dennis Potman --- src/core/ddsi/src/ddsi_typewrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ddsi/src/ddsi_typewrap.c b/src/core/ddsi/src/ddsi_typewrap.c index 3b87bb63..21cc7521 100644 --- a/src/core/ddsi/src/ddsi_typewrap.c +++ b/src/core/ddsi/src/ddsi_typewrap.c @@ -420,7 +420,7 @@ static void xt_sbounds_to_lbounds (struct DDS_XTypes_LBoundSeq *lb, const struct static void xt_lbounds_dup (struct DDS_XTypes_LBoundSeq *dst, const struct DDS_XTypes_LBoundSeq *src) { dst->_length = src->_length; - dst->_buffer = ddsrt_memdup (&src->_buffer, dst->_length * sizeof (*dst->_buffer)); + dst->_buffer = ddsrt_memdup (src->_buffer, dst->_length * sizeof (*dst->_buffer)); } static void DDS_XTypes_AppliedBuiltinMemberAnnotations_copy (struct DDS_XTypes_AppliedBuiltinMemberAnnotations *dst, const struct DDS_XTypes_AppliedBuiltinMemberAnnotations *src); From 65981fb935e028c3fbb3b0fbafcbebf3013aa59a Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 12 May 2022 13:37:06 +0200 Subject: [PATCH 22/27] Bump version number to 0.9.1 Signed-off-by: Erik Boasson --- CMakeLists.txt | 4 ++-- package.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06648da8..f046b631 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ # SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause # cmake_minimum_required(VERSION 3.10) -project(CycloneDDS VERSION 0.9.0 LANGUAGES C) +project(CycloneDDS VERSION 0.9.1 LANGUAGES C) if(CMAKE_VERSION VERSION_LESS 3.12) # GENERATE_EXPORT_HEADER requires a C++ compiler up to version 3.12 enable_language(CXX) @@ -346,4 +346,4 @@ if(DEFINED ENV{LIB_FUZZING_ENGINE}) add_subdirectory(fuzz) endif() -include(CMakeCPack.cmake) \ No newline at end of file +include(CMakeCPack.cmake) diff --git a/package.xml b/package.xml index 34ea4fbc..8a8b152e 100644 --- a/package.xml +++ b/package.xml @@ -2,7 +2,7 @@ cyclonedds - 0.9.0 + 0.9.1 Eclipse Cyclone DDS is a very performant and robust open-source DDS implementation. Cyclone DDS is developed completely in the open as an Eclipse IoT project. Eclipse Foundation, Inc. Eclipse Public License 2.0 From c3d40357f168f85e48fe1f1ffd912b65fb2cf960 Mon Sep 17 00:00:00 2001 From: Zhou Shengyong Date: Mon, 10 Apr 2023 18:19:22 +0800 Subject: [PATCH 23/27] [FreeRTOS-Plus-TCP] to support cycloneDDS over FreeRTOS-Plus-TCP IP stack 1. CycloneDDS version0.9.1 2. add support FreeRTOS_Plus_TCP stack 3. adaption ddsrt_runtime [Issue] Not Validated [Changes] +TCP socket ddsrt header and source sockaddr ifaddr .init_array section log sink multicast/unicast peer define in xml TLS-Thread_Local_Storage from FreeRTOS SW impl instread of toolchain sock_waitset sock fdset sendmsg/recvmsg for UDP dds_align from 0.10.2 FragmentSize for jumbo and normal [Test Platform] N/A Signed-off-by: Brave Zhou --- .../ddsc/include/dds/ddsc/dds_public_impl.h | 3 + src/core/ddsc/include/dds/export.h | 50 ++ src/core/ddsc/src/dds_builtin.c | 4 + src/core/ddsc/src/dds_domain.c | 25 +- src/core/ddsc/src/dds_init.c | 8 + src/core/ddsc/src/dds_participant.c | 30 + src/core/ddsi/defconfig.c | 9 + .../ddsi/include/dds/ddsi/ddsi_cfgelems.h | 125 ++++- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_locator.h | 2 +- .../include/dds/ddsi/ddsi_serdata_default.h | 18 + src/core/ddsi/include/dds/ddsi/ddsi_udp.h | 4 + src/core/ddsi/include/dds/ddsi/q_log.h | 3 + src/core/ddsi/include/dds/ddsi/q_thread.h | 4 + src/core/ddsi/src/ddsi_cdrstream.c | 14 +- src/core/ddsi/src/ddsi_ipaddr.c | 12 + src/core/ddsi/src/ddsi_tcp.c | 18 +- src/core/ddsi/src/ddsi_tran.c | 2 + src/core/ddsi/src/ddsi_udp.c | 102 +++- src/core/ddsi/src/ddsi_wraddrset.c | 4 + src/core/ddsi/src/q_addrset.c | 2 + src/core/ddsi/src/q_ddsi_discovery.c | 16 + src/core/ddsi/src/q_entity.c | 8 +- src/core/ddsi/src/q_freelist.c | 32 ++ src/core/ddsi/src/q_gc.c | 4 + src/core/ddsi/src/q_init.c | 54 +- src/core/ddsi/src/q_pcap.c | 10 + src/core/ddsi/src/q_receive.c | 67 ++- src/core/ddsi/src/q_sockwaitset_s.c | 522 ++++++++++++++++++ src/core/ddsi/src/q_thread.c | 36 +- src/core/ddsi/src/q_transmit.c | 14 + src/core/ddsi/src/q_xevent.c | 64 ++- src/core/ddsi/src/q_xmsg.c | 11 +- src/ddsrt/include/dds/config.h.in | 11 + src/ddsrt/include/dds/ddsrt/iovec.h | 11 + src/ddsrt/include/dds/ddsrt/log.h | 31 +- src/ddsrt/include/dds/ddsrt/process.h | 12 + src/ddsrt/include/dds/ddsrt/sockets.h | 18 +- .../dds/ddsrt/sockets/freertos_plus_tcp.h | 245 ++++++++ src/ddsrt/include/dds/ddsrt/sockets/posix.h | 7 + src/ddsrt/include/dds/ddsrt/threads.h | 32 ++ src/ddsrt/src/cdtors.c | 16 + src/ddsrt/src/heap/freertos/heap.c | 1 + src/ddsrt/src/ifaddrs.c | 2 + .../freertos_plus_tcp/ifaddrs_plus_tcp.c | 110 ++++ src/ddsrt/src/log.c | 121 +++- src/ddsrt/src/process/freertos/process.c | 5 + src/ddsrt/src/sockets.c | 38 +- src/ddsrt/src/threads/freertos/threads.c | 21 + src/ddsrt/src/time.c | 3 + src/ddsrt/src/time/freertos/time.c | 4 + 51 files changed, 1908 insertions(+), 61 deletions(-) create mode 100755 src/core/ddsc/include/dds/export.h create mode 100755 src/core/ddsi/src/q_sockwaitset_s.c create mode 100755 src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h create mode 100755 src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c diff --git a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h index ea0e7055..291e5d9c 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h +++ b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h @@ -26,6 +26,9 @@ #include #include "dds/export.h" #include "dds/features.h" +#ifdef DDSRT_WITH_FREERTOSTCP +#include "dds/ddsrt/align.h" +#endif #include "dds/ddsc/dds_public_alloc.h" #include "dds/ddsc/dds_opcodes.h" diff --git a/src/core/ddsc/include/dds/export.h b/src/core/ddsc/include/dds/export.h new file mode 100755 index 00000000..30103d12 --- /dev/null +++ b/src/core/ddsc/include/dds/export.h @@ -0,0 +1,50 @@ + +#ifndef DDS_EXPORT_H +#define DDS_EXPORT_H + +#ifdef DDS_STATIC_DEFINE +# define DDS_EXPORT +# define DDS_NO_EXPORT +#else +# ifndef DDS_EXPORT +# ifdef ddsc_EXPORTS + /* We are building this library */ +# define DDS_EXPORT +# else + /* We are using this library */ +# define DDS_EXPORT +# endif +# endif + +# ifndef DDS_NO_EXPORT +# define DDS_NO_EXPORT +# endif +#endif + +#ifndef DDS_DEPRECATED +# define DDS_DEPRECATED +#endif + +#ifndef DDS_DEPRECATED_EXPORT +# define DDS_DEPRECATED_EXPORT DDS_EXPORT DDS_DEPRECATED +#endif + +#ifndef DDS_DEPRECATED_NO_EXPORT +# define DDS_DEPRECATED_NO_EXPORT DDS_NO_EXPORT DDS_DEPRECATED +#endif + +#if 0 /* DEFINE_NO_DEPRECATED */ +# ifndef DDS_NO_DEPRECATED +# define DDS_NO_DEPRECATED +# endif +#endif + +#ifndef DDS_INLINE_EXPORT +# if __MINGW32__ && (!defined(__clang__) || !defined(ddsc_EXPORTS)) +# define DDS_INLINE_EXPORT +# else +# define DDS_INLINE_EXPORT DDS_EXPORT +# endif +#endif + +#endif /* DDS_EXPORT_H */ diff --git a/src/core/ddsc/src/dds_builtin.c b/src/core/ddsc/src/dds_builtin.c index fd2a31da..43f96adb 100644 --- a/src/core/ddsc/src/dds_builtin.c +++ b/src/core/ddsc/src/dds_builtin.c @@ -374,6 +374,8 @@ void dds__builtin_init (struct dds_domain *dom) { dds_qos_t *qos = dds__create_builtin_qos (); + DDS_LOG(DDS_LC_CONFIG, " dds__builtin_init ..."); + dom->btif.arg = dom; dom->btif.builtintopic_get_tkmap_entry = dds__builtin_get_tkmap_entry; dom->btif.builtintopic_is_builtintopic = dds__builtin_is_builtintopic; @@ -415,6 +417,8 @@ void dds__builtin_init (struct dds_domain *dom) dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, dom->builtin_reader_type, qos, builtintopic_whc_new (DSBT_READER, gh)); thread_state_asleep (lookup_thread_state ()); + DDS_LOG(DDS_LC_CONFIG, " builtin_topics writer done"); + dds_delete_qos (qos); /* ddsi_sertype_init initializes the refcount to 1 and dds_sertopic_register_locked increments diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index dfb6b802..81afea50 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -120,6 +120,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i break; } domain->m_id = domain->gv.config.domainId; + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " domain 0X%08x / 0x%08x config init done \n", domain->m_id, domain_id); if (rtps_config_prep (&domain->gv, domain->cfgst) != 0) { @@ -127,6 +128,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_config; } + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_config_prep done \n"); if (rtps_init (&domain->gv) < 0) { @@ -134,6 +136,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_init; } + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_init done! \n"); #ifdef DDS_HAS_SHM // if DDS_HAS_SHM is enabled the iceoryx runtime was created in rtps_init and is ready @@ -151,6 +154,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domain to configured to do so. */ if (domain->gv.config.liveliness_monitoring) { + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start ... \n"); if (dds_global.threadmon_count++ == 0) { /* FIXME: configure settings */ @@ -169,9 +173,11 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i goto fail_threadmon_start; } } + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start! \n"); } dds__builtin_init (domain); + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " dds__builtin_init done! \n"); /* Set additional default participant properties */ @@ -187,10 +193,21 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_start; } + DDS_LOG(DDS_LC_CONFIG, " rtps_start done!"); if (domain->gv.config.liveliness_monitoring) ddsi_threadmon_register_domain (dds_global.threadmon, &domain->gv); dds_entity_init_complete (&domain->m_entity); + + #if 0 // def DDSRT_WITH_FREERTOSTCP + /* CAUTION: NEVER open this slice unless in UT itself. */ + sleep(2U); /* wait thread wrapper */ + DDS_LOG(DDS_LC_CONFIG, " @@@@@@@@@@@@@@@@@@ domain init threads dump"); + /* dump all threads created in domain_init */ + //eth_run_cli("ps"); + sleep(1U); + #endif + return domh; fail_rtps_start: @@ -234,6 +251,8 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o if (dom) { + DDS_LOG (DDS_LC_CONFIG, " find dom %p", dom); + if (!implicit) domh = DDS_RETCODE_PRECONDITION_NOT_MET; else @@ -254,18 +273,22 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o } else { + DDS_LOG (DDS_LC_CONFIG, " create dom ..."); dom = dds_alloc (sizeof (*dom)); if ((domh = dds_domain_init (dom, id, config, implicit)) < 0) - dds_free (dom); + { dds_free (dom); } else { + DDS_LOG (DDS_LC_CONFIG, " dom created, domh = 0x%x ", domh); ddsrt_mutex_lock (&dom->m_entity.m_mutex); ddsrt_avl_insert (&dds_domaintree_def, &dds_global.m_domains, dom); dds_entity_register_child (&dds_global.m_entity, &dom->m_entity); + DDS_LOG (DDS_LC_CONFIG, " register domain to global done "); if (implicit) { dds_entity_add_ref_locked (&dom->m_entity); dds_handle_repin (&dom->m_entity.m_hdllink); + DDS_LOG (DDS_LC_CONFIG, " dom->m_entity.m_hdllink.hdl = 0x%x ", dom->m_entity.m_hdllink.hdl); } domh = dom->m_entity.m_hdllink.hdl; ddsrt_mutex_unlock (&dom->m_entity.m_mutex); diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index e4252e02..4c9154cc 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -52,6 +52,10 @@ dds_cyclonedds_entity dds_global; #define CDDS_STATE_STARTING 1u #define CDDS_STATE_READY 2u #define CDDS_STATE_STOPPING 3u + +#ifdef DDSRT_WITH_FREERTOSTCP +#define MAX_THREAD_NUM 32 +#endif static ddsrt_atomic_uint32_t dds_state = DDSRT_ATOMIC_UINT32_INIT (CDDS_STATE_ZERO); static void common_cleanup (void) @@ -112,7 +116,11 @@ dds_return_t dds_init (void) ddsrt_mutex_init (&dds_global.m_mutex); ddsrt_cond_init (&dds_global.m_cond); ddsi_iid_init (); + #ifdef DDSRT_WITH_FREERTOSTCP + thread_states_init (MAX_THREAD_NUM); + #else thread_states_init (128); + #endif if (dds_handle_server_init () != DDS_RETCODE_OK) { diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index 9cba6a57..c9a977ad 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -91,6 +91,9 @@ const struct dds_entity_deriver dds_entity_deriver_participant = { .refresh_statistics = dds_entity_deriver_dummy_refresh_statistics }; +#ifdef DDSRT_WITH_FREERTOSTCP +char dds_peer[16] = {0}; +#endif dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener) { dds_domain *dom; @@ -99,6 +102,29 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ dds_participant * pp; ddsi_plist_t plist; dds_qos_t *new_qos = NULL; + +#ifdef DDSRT_WITH_FREERTOSTCP + /* Make sure DDS instance is initialized. */ + if ((ret = dds_init ()) < 0) + goto err_dds_init; + + char xml[1024]; + memset(xml, 0, sizeof(xml)); + if (inet_addr(dds_peer) == 0) + { + strncpy(dds_peer, "192.168.11.2", sizeof(dds_peer)); + dds_peer[sizeof(dds_peer) - 1] = '\0'; + } + + snprintf(xml, sizeof(xml) - 1, "\ +\ + \ +\ +", dds_peer); + const char *config = xml; + DDS_WARNING(" participant xml [%s] !", xml); + //DDS_WARNING(" participant peer using [%s] !", dds_peer); +#else const char *config = ""; /* Make sure DDS instance is initialized. */ @@ -106,6 +132,8 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ goto err_dds_init; (void) ddsrt_getenv ("CYCLONEDDS_URI", &config); +#endif + if ((ret = dds_domain_create_internal (&dom, domain, true, config)) < 0) goto err_domain_create; @@ -143,6 +171,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ret = DDS_RETCODE_ERROR; goto err_new_participant; } + DDS_INFO(" built-in participant done !"); pp = dds_alloc (sizeof (*pp)); if ((ret = dds_entity_init (&pp->m_entity, &dom->m_entity, DDS_KIND_PARTICIPANT, false, true, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0) @@ -160,6 +189,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ddsrt_mutex_unlock (&dom->m_entity.m_mutex); dds_entity_init_complete (&pp->m_entity); + /* drop temporary extra ref to domain, dds_init */ dds_entity_unpin_and_drop_ref (&dom->m_entity); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index beae4e51..1f76f41d 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -14,7 +14,11 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->externalMaskString = "0.0.0.0"; cfg->allowMulticast = UINT32_C (2147483648); cfg->multicast_ttl = INT32_C (32); + #ifdef DDSRT_WITH_FREERTOSTCP + cfg->transport_selector = INT32_C (DDSI_TRANS_UDP); + #else cfg->transport_selector = INT32_C (1); + #endif cfg->enableMulticastLoopback = INT32_C (1); cfg->max_msg_size = UINT32_C (14720); cfg->max_rexmit_msg_size = UINT32_C (1456); @@ -58,8 +62,13 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->const_hb_intv_min = INT64_C (5000000); cfg->const_hb_intv_sched_min = INT64_C (20000000); cfg->const_hb_intv_sched_max = INT64_C (8000000000); + #ifdef DDSRT_WITH_FREERTOSTCP + cfg->max_queued_rexmit_bytes = UINT32_C (33554432); /* 524288->32M: > 4K framesize */ + cfg->max_queued_rexmit_msgs = UINT32_C (18000); /* 200->20480: > 4K framesize / fragmen_size */ + #else cfg->max_queued_rexmit_bytes = UINT32_C (524288); cfg->max_queued_rexmit_msgs = UINT32_C (200); + #endif cfg->writer_linger_duration = INT64_C (1000000000); cfg->socket_rcvbuf_size.min.isdefault = 1; cfg->socket_rcvbuf_size.max.isdefault = 1; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h index 5b5b3db8..d1e3e867 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h @@ -15,6 +15,10 @@ #include "dds/features.h" +#ifdef DDSRT_WITH_FREERTOSTCP +#warning " debug rtos tcp stack including " +#include "dds/ddsrt/sockets/freertos_plus_tcp.h" +#endif static struct cfgelem network_interface_attributes[] = { STRING("autodetermine", NULL, 1, "false", @@ -156,7 +160,16 @@ static struct cfgelem general_cfgelems[] = { "translated to an internal address by replacing the network portion of " "the external address with the corresponding portion of the preferred " "network interface address. This option is IPv4-only.

")), - LIST("AllowMulticast", NULL, 1, "default", + LIST("AllowMulticast", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP +/* + * he "spdp" leaves multicast enabled for initial discovery only + * https://github.com/ros2/rmw_cyclonedds/issues/251 + */ + "spdp", +#else + "default", +#endif MEMBER(allowMulticast), FUNCTIONS(0, uf_allow_multicast, 0, pf_allow_multicast), DESCRIPTION( @@ -212,19 +225,34 @@ static struct cfgelem general_cfgelems[] = { "packets, to bypass the local routing tables. This is generally useful " "only when the routing tables cannot be trusted, which is highly " "unusual.

")), - ENUM("UseIPv6", NULL, 1, "default", + ENUM("UseIPv6", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + "false", +#else + "default", +#endif MEMBER(compat_use_ipv6), FUNCTIONS(0, uf_boolean_default, 0, pf_nop), DESCRIPTION("

Deprecated (use Transport instead)

"), VALUES("false","true","default")), - ENUM("Transport", NULL, 1, "default", + ENUM("Transport", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + "udp", +#else + "default", +#endif MEMBER(transport_selector), FUNCTIONS(0, uf_transport_selector, 0, pf_transport_selector), DESCRIPTION( "

This element allows selecting the transport to be used (udp, udp6, " "tcp, tcp6, raweth)

"), VALUES("default","udp","udp6","tcp","tcp6","raweth")), - BOOL("EnableMulticastLoopback", NULL, 1, "true", + BOOL("EnableMulticastLoopback", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + "false", +#else + "true", +#endif MEMBER(enableMulticastLoopback), FUNCTIONS(0, uf_boolean, 0, pf_boolean), DESCRIPTION( @@ -234,7 +262,21 @@ static struct cfgelem general_cfgelems[] = { "communications, but if a node runs only a single Cyclone DDS service " "and does not host any other DDSI-capable programs, it should be set " "to \"false\" for improved performance.

")), - STRING("MaxMessageSize", NULL, 1, "14720 B", + + STRING("MaxMessageSize", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP +/* ddsi_config.max_msg_size and fragment_size will decide how many fragments in single submsg. + * keep this below MTU if STACK not support IP fragments + */ + #ifdef EQOS_TX_JUMBO_ENABLED + "8972 B", + #else + "1456 B", + #endif + +#else + "14720 B", +#endif MEMBER(max_msg_size), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -246,7 +288,16 @@ static struct cfgelem general_cfgelems[] = { "

On some networks it may be necessary to set this item to keep the " "packetsize below the MTU to prevent IP fragmentation.

"), UNIT("memsize")), - STRING("MaxRexmitMessageSize", NULL, 1, "1456 B", + STRING("MaxRexmitMessageSize", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + #ifdef EQOS_TX_JUMBO_ENABLED + "8972 B", + #else + "1464 B", + #endif +#else + "1456 B", +#endif MEMBER(max_rexmit_msg_size), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -258,7 +309,17 @@ static struct cfgelem general_cfgelems[] = { "

On some networks it may be necessary to set this item to keep the " "packetsize below the MTU to prevent IP fragmentation.

"), UNIT("memsize")), - STRING("FragmentSize", NULL, 1, "1344 B", + STRING("FragmentSize", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + #ifdef EQOS_TX_JUMBO_ENABLED + /* ipMAX_UDP_PAYLOAD_LENGTH(8972) > $FragSize + 20(RTPS_HDR) + 12(INFO_TS) + 36(DATA_HDR) + 28(HEART_BEAT) */ + "8864 B", + #else + "1400 B", + #endif +#else + "1344 B", +#endif MEMBER(fragment_size), FUNCTIONS(0, uf_memsize16, 0, pf_memsize16), DESCRIPTION( @@ -938,7 +999,15 @@ static struct cfgelem internal_watermarks_cfgelems[] = { "expressed in bytes. A suspended writer resumes transmitting when its " "Cyclone DDS WHC shrinks to this size.

"), UNIT("memsize")), - STRING("WhcHigh", NULL, 1, "500 kB", + STRING("WhcHigh", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + /* 512K->24M: > 4K RGB888 framesize + * ALSO to be sure seqeunce limitation defined in idl + */ + "24576 kB", +#else + "500 kB", +#endif MEMBER(whc_highwater_mark), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -1282,7 +1351,16 @@ static struct cfgelem internal_cfgelems[] = { "

This element allows configuring the base interval for sending " "writer heartbeats and the bounds within which it can vary.

"), UNIT("duration_inf")), - STRING("MaxQueuedRexmitBytes", NULL, 1, "512 kB", + + STRING("MaxQueuedRexmitBytes", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + /* 512K->24M: > 4K RGB888 framesize + * ALSO to be sure seqeunce limitation defined in idl + */ + "24576 kB", +#else + "512 kB", +#endif MEMBER(max_queued_rexmit_bytes), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -1292,7 +1370,14 @@ static struct cfgelem internal_cfgelems[] = { "NackDelay * AuxiliaryBandwidthLimit. It must be large enough to " "contain the largest sample that may need to be retransmitted.

"), UNIT("memsize")), - INT("MaxQueuedRexmitMessages", NULL, 1, "200", + + INT("MaxQueuedRexmitMessages", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + /* 200->20480: > 4K framesize / fragmen_size */ + "20480", +#else + "200", +#endif MEMBER(max_queued_rexmit_msgs), FUNCTIONS(0, uf_uint, 0, pf_uint), DESCRIPTION( @@ -1804,7 +1889,11 @@ static struct cfgelem shmem_cfgelems[] = { #endif static struct cfgelem discovery_peer_cfgattrs[] = { +#ifdef DDSRT_WITH_FREERTOSTCP + STRING("Address", NULL, 1, "192.168.11.3:7400", // Not working, use XML string +#else STRING("Address", NULL, 1, NULL, +#endif MEMBEROF(ddsi_config_peer_listelem, peer), FUNCTIONS(0, uf_ipv4, ff_free, pf_string), DESCRIPTION( @@ -1829,6 +1918,16 @@ static struct cfgelem discovery_peers_group_cfgelems[] = { }; static struct cfgelem discovery_peers_cfgelems[] = { +#ifdef DDSRT_WITH_FREERTOSTCP + GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, // Not working, use XML string + MEMBER(peers), + FUNCTIONS(if_peer, 0, 0, 0), + DESCRIPTION( + "

This element specifies the base port number (refer to the DDSI 2.1 " + "specification, section 9.6.1, constant PB).

" + )), + +#else GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, MEMBER(peers), FUNCTIONS(if_peer, 0, 0, 0), @@ -1845,6 +1944,7 @@ static struct cfgelem discovery_peers_cfgelems[] = { ), MAXIMUM(0)), /* Group element can occur more than once, but 1 is required because of the way its processed (for now) */ +#endif END_MARKER }; @@ -1900,7 +2000,12 @@ static struct cfgelem discovery_cfgelems[] = { "and fixing the participant index has no adverse effects, it is " "recommended that the second be option be used.

" )), +#ifdef DDSRT_WITH_FREERTOSTCP + /* polling port number to dest peer */ + INT("MaxAutoParticipantIndex", NULL, 1, "2", /* 9 */ +#else INT("MaxAutoParticipantIndex", NULL, 1, "9", +#endif MEMBER(maxAutoParticipantIndex), FUNCTIONS(0, uf_natint, 0, pf_int), DESCRIPTION( diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 6862e1cc..4036b50a 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -310,8 +310,8 @@ struct ddsi_config unsigned delivery_queue_maxsamples; - uint16_t fragment_size; - uint32_t max_msg_size; + uint16_t fragment_size; // default: 1344 + uint32_t max_msg_size; /* default: 14720 how many fragment in single submsg */ uint32_t max_rexmit_msg_size; uint32_t init_transmit_extra_pct; uint32_t max_rexmit_burst_size; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h index 0d6d2631..584a06da 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h @@ -23,7 +23,7 @@ struct ddsi_tran_conn; /* address field in locator maintained in network byte order, the rest in host */ typedef struct { - int32_t kind; + int32_t kind; // NN_LOCATOR_KIND_UDPv4 uint32_t port; unsigned char address[16]; } ddsi_locator_t; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h index b12de943..3cf62747 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h @@ -98,6 +98,24 @@ struct ddsi_serdata_default_unpadded { #define DDSI_SERDATA_DEFAULT_PAD(n) (n) #endif + +#if 0 +/* un-fold to easy to track in SI */ +struct ddsi_serdata_default { + struct ddsi_serdata c; + uint32_t pos; + uint32_t size; + DDSI_SERDATA_DEFAULT_DEBUG_FIELDS + struct ddsi_serdata_default_key key; + struct serdatapool *serpool; + struct ddsi_serdata_default *next; /* in pool->freelist */ + char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))]; + struct CDRHeader hdr; + char data[]; +}; +#endif + + struct ddsi_serdata_default { DDSI_SERDATA_DEFAULT_PREPAD; char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))]; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h index 2d36180e..14ea1252 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h @@ -18,7 +18,11 @@ extern "C" { typedef struct nn_udpv4mcgen_address { /* base IPv4 MC address is ipv4, host bits are bits base .. base+count-1, this machine is bit idx */ +#ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t ipv4; +#else struct in_addr ipv4; +#endif uint8_t base; uint8_t count; uint8_t idx; /* must be last: then sorting will put them consecutively */ diff --git a/src/core/ddsi/include/dds/ddsi/q_log.h b/src/core/ddsi/include/dds/ddsi/q_log.h index 64d3c0f8..cbb9fb03 100644 --- a/src/core/ddsi/include/dds/ddsi/q_log.h +++ b/src/core/ddsi/include/dds/ddsi/q_log.h @@ -24,6 +24,9 @@ extern "C" { #define GVTRACE(...) DDS_CTRACE (&gv->logconfig, __VA_ARGS__) #define GVLOG(cat, ...) DDS_CLOG ((cat), &gv->logconfig, __VA_ARGS__) +#ifdef DDSRT_WITH_FREERTOSTCP +#define GVINFO(...) DDS_CLOG (DDS_LC_INFO, &gv->logconfig, __VA_ARGS__) +#endif #define GVWARNING(...) DDS_CLOG (DDS_LC_WARNING, &gv->logconfig, __VA_ARGS__) #define GVERROR(...) DDS_CLOG (DDS_LC_ERROR, &gv->logconfig, __VA_ARGS__) diff --git a/src/core/ddsi/include/dds/ddsi/q_thread.h b/src/core/ddsi/include/dds/ddsi/q_thread.h index 5d84c11d..fd382ea9 100644 --- a/src/core/ddsi/include/dds/ddsi/q_thread.h +++ b/src/core/ddsi/include/dds/ddsi/q_thread.h @@ -132,7 +132,11 @@ DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1); DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv); DDS_INLINE_EXPORT inline struct thread_state1 *lookup_thread_state (void) { +#ifdef DDSRT_WITH_FREERTOSTCP + struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); +#else struct thread_state1 *ts1 = tsd_thread_state; +#endif if (ts1) return ts1; else diff --git a/src/core/ddsi/src/ddsi_cdrstream.c b/src/core/ddsi/src/ddsi_cdrstream.c index 084a627b..5e485c49 100644 --- a/src/core/ddsi/src/ddsi_cdrstream.c +++ b/src/core/ddsi/src/ddsi_cdrstream.c @@ -861,12 +861,12 @@ static char *dds_stream_reuse_string_bound (dds_istream_t * __restrict is, char so this check is superfluous, but perhaps rejecting such a sample is the wrong thing to do */ if (!alloc) - assert (str != NULL); + { assert (str != NULL); } else if (str == NULL) - str = dds_alloc (size); + { str = dds_alloc (size); } memcpy (str, src, length > size ? size : length); if (length > size) - str[size - 1] = '\0'; + { str[size - 1] = '\0'; } is->m_index += length; return str; } @@ -3821,7 +3821,11 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd case DDS_OP_VAL_4BY: { const union { int32_t s; uint32_t u; float f; } x = { .u = dds_is_get4 (is) }; if (flags & DDS_OP_FLAG_FP) + #ifdef DDSRT_WITH_FREERTOSTCP + return prtf (buf, bufsize, "%f", x.f); + #else return prtf (buf, bufsize, "%g", x.f); + #endif else if (flags & DDS_OP_FLAG_SGN) return prtf (buf, bufsize, "%"PRId32, x.s); else @@ -3830,7 +3834,11 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd case DDS_OP_VAL_8BY: { const union { int64_t s; uint64_t u; double f; } x = { .u = dds_is_get8 (is) }; if (flags & DDS_OP_FLAG_FP) + #ifdef DDSRT_WITH_FREERTOSTCP + return prtf (buf, bufsize, "%f", x.f); + #else return prtf (buf, bufsize, "%g", x.f); + #endif else if (flags & DDS_OP_FLAG_SGN) return prtf (buf, bufsize, "%"PRId64, x.s); else diff --git a/src/core/ddsi/src/ddsi_ipaddr.c b/src/core/ddsi/src/ddsi_ipaddr.c index 5d286ff3..eb086360 100644 --- a/src/core/ddsi/src/ddsi_ipaddr.c +++ b/src/core/ddsi/src/ddsi_ipaddr.c @@ -251,7 +251,11 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_ { const struct sockaddr_in *x = (const struct sockaddr_in *) src; assert (kind == NN_LOCATOR_KIND_UDPv4 || kind == NN_LOCATOR_KIND_TCPv4); + #ifdef DDSRT_WITH_FREERTOSTCP + if (x->sin_addr == htonl (INADDR_ANY)) + #else if (x->sin_addr.s_addr == htonl (INADDR_ANY)) + #endif { dst->kind = NN_LOCATOR_KIND_INVALID; dst->port = NN_LOCATOR_PORT_INVALID; @@ -261,7 +265,11 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_ { dst->port = (x->sin_port == 0) ? NN_LOCATOR_PORT_INVALID : ntohs (x->sin_port); memset (dst->address, 0, 12); + #ifdef DDSRT_WITH_FREERTOSTCP + memcpy (dst->address + 12, &x->sin_addr, 4); + #else memcpy (dst->address + 12, &x->sin_addr.s_addr, 4); + #endif } break; } @@ -310,7 +318,11 @@ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const ddsi_locator_t *s struct sockaddr_in *x = (struct sockaddr_in *) dst; x->sin_family = AF_INET; x->sin_port = (src->port == NN_LOCATOR_PORT_INVALID) ? 0 : htons ((unsigned short) src->port); + #ifdef DDSRT_WITH_FREERTOSTCP + memcpy (&x->sin_addr, src->address + 12, 4); + #else memcpy (&x->sin_addr.s_addr, src->address + 12, 4); + #endif break; } #if DDSRT_HAVE_IPV6 diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index 5dd0c4f4..cb8328de 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -188,7 +188,11 @@ static dds_return_t ddsi_tcp_sock_new (struct ddsi_tran_factory_tcp * const fact { case NN_LOCATOR_KIND_TCPv4: socketname.a4.sin_family = AF_INET; + #ifdef DDSRT_WITH_FREERTOSTCP + socketname.a4.sin_addr = htonl (INADDR_ANY); + #else socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); + #endif socketname.a4.sin_port = htons (port); break; #if DDSRT_HAVE_IPV6 @@ -459,8 +463,13 @@ static bool ddsi_tcp_select (struct ddsi_domaingv const * const gv, ddsrt_socket static int32_t addrfam_to_locator_kind (int af) { +#if DDSRT_HAVE_IPV6 assert (af == AF_INET || af == AF_INET6); return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6; +#else + assert (af == AF_INET); + return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_INVALID; +#endif } static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, ddsi_locator_t *srcloc) @@ -1072,8 +1081,13 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener) switch (addr.a.sa_family) { case AF_INET: - if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY)) - addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + #ifdef DDSRT_WITH_FREERTOSTCP + if (addr.a4.sin_addr == htonl (INADDR_ANY)) + { addr.a4.sin_addr = htonl (INADDR_LOOPBACK); } + #else + if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY)) + { addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); } + #endif break; #if DDSRT_HAVE_IPV6 case AF_INET6: diff --git a/src/core/ddsi/src/ddsi_tran.c b/src/core/ddsi/src/ddsi_tran.c index be1ed3d7..6f5411bd 100644 --- a/src/core/ddsi/src/ddsi_tran.c +++ b/src/core/ddsi/src/ddsi_tran.c @@ -134,7 +134,9 @@ void ddsi_conn_free (ddsi_tran_conn_t conn) for (uint32_t i = 0; i < conn->m_base.gv->n_recv_threads; i++) { if (!conn->m_base.gv->recv_threads[i].ts) + { assert (!ddsrt_atomic_ld32 (&conn->m_base.gv->rtps_keepgoing)); + } else { switch (conn->m_base.gv->recv_threads[i].arg.mode) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 26c59e9e..0bccc7ba 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -88,6 +88,19 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu msghdr.msg_controllen = 0; #endif +#ifdef DDSRT_WITH_FREERTOSTCP +{ + if (conn->m_base.m_base.m_port == 7410) + { + GVTRACE(" @@@@@@ waitset UDP RX on port %u ... ", conn->m_base.m_base.m_port); + } + if (conn->m_base.m_base.m_port == 7411) + { + GVTRACE(" @@@@@@ uc UDP RX on port %u ... ", conn->m_base.m_base.m_port); + } +} +#endif + do { rc = ddsrt_recvmsg (conn->m_sock, &msghdr, 0, &ret); } while (rc == DDS_RETCODE_INTERRUPTED); @@ -95,7 +108,9 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu if (ret > 0) { if (srcloc) - addr_to_loc (conn->m_base.m_factory, srcloc, &src); + { + addr_to_loc (conn->m_base.m_factory, srcloc, &src); + } if (gv->pcap_fp) { @@ -153,6 +168,13 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato #if defined(__sun) && !defined(_XPG4_2) msg.msg_accrights = NULL; msg.msg_accrightslen = 0; +#elif defined DDSRT_WITH_FREERTOSTCP /* got whole payload sz for trans */ + msg.msg_control = NULL; + msg.msg_controllen = 0U; + for (int ii = 0; ii < niov; ii++) + { + msg.msg_controllen += iov[ii].iov_len; + } #else msg.msg_control = NULL; msg.msg_controllen = 0; @@ -163,6 +185,7 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato DDSRT_UNUSED_ARG (flags); #endif #if MSG_NOSIGNAL && !LWIP_SOCKET +#error sendflags |= MSG_NOSIGNAL; #endif do { @@ -266,7 +289,13 @@ static dds_return_t set_dont_route (struct ddsi_domaingv const * const gv, ddsrt return rc; } +#ifdef DDSRT_WITH_FREERTOSTCP +static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, + ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, + const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size) +#else static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size) +#endif { // if (min, max)= and initbuf= then request= and result= // (def, def) < defmin defmin whatever it is @@ -275,9 +304,14 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd // (M, N=M) anything N error if < M // defmin = 1MB for receive buffer, 0B for send buffer + +#ifdef DDSRT_WITH_FREERTOSTCP + const bool always_set_size = true; +#else const bool always_set_size = // whether to call setsockopt unconditionally ((config->min.isdefault && !config->max.isdefault) || (!config->min.isdefault && !config->max.isdefault && config->max.value >= config->min.value)); +#endif const uint32_t socket_min_buf_size = // error if it ends up below this !config->min.isdefault ? config->min.value : 0; const uint32_t socket_req_buf_size = // size to request @@ -289,7 +323,13 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd socklen_t optlen = (socklen_t) sizeof (actsize); dds_return_t rc; +#ifdef DDSRT_WITH_FREERTOSTCP +#warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." + rc = DDS_RETCODE_OK; + actsize = socket_req_buf_size + 1U; /* stub getsockopt a different value */ +#else rc = ddsrt_getsockopt (sock, SOL_SOCKET, socket_option, &actsize, &optlen); +#endif if (rc == DDS_RETCODE_BAD_PARAMETER) { /* not all stacks support getting/setting RCVBUF */ @@ -304,6 +344,13 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd if (always_set_size || actsize < socket_req_buf_size) { + #ifdef DDSRT_WITH_FREERTOSTCP + rc = ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize)); + + #warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." + actsize = socket_req_buf_size; + + #else (void) ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize)); /* We don't check the return code from setsockopt, because some O/Ss tend @@ -316,11 +363,15 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd } if (actsize >= socket_req_buf_size) - GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize); + { + GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize); + } else if (actsize >= socket_min_buf_size) - GVLOG (DDS_LC_CONFIG, + { + GVLOG (DDS_LC_CONFIG, "failed to increase socket %s buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", name, socket_req_buf_size, actsize); + } else { /* If the configuration states it must be >= X, then error out if the @@ -330,9 +381,10 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd name, socket_min_buf_size, actsize); rc = DDS_RETCODE_NOT_ENOUGH_SPACE; } + #endif } - return (rc < 0) ? rc : (actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize; + return (rc < 0) ? rc : ((actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize); } static dds_return_t set_rcvbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const struct ddsi_config_socket_buf_size *config) @@ -374,6 +426,7 @@ static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * c static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, struct nn_interface const * const intf, ddsrt_socket_t sock) { +#ifndef DDSRT_WITH_FREERTOSTCP #if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET if (gv->config.use_multicast_if_mreqn) { @@ -390,6 +443,7 @@ static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const } #else (void) gv; +#endif #endif return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, intf->loc.address + 12, 4); } @@ -466,7 +520,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ { case NN_LOCATOR_KIND_UDPv4: if (bind_to_any) - socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); + #ifdef DDSRT_WITH_FREERTOSTCP + { socketname.a4.sin_addr = htonl (INADDR_ANY); } + #else + { socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); } + #endif break; #if DDSRT_HAVE_IPV6 case NN_LOCATOR_KIND_UDPv6: @@ -509,11 +567,15 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ break; } while (!ddsrt_atomic_cas32 (&fact->receive_buf_size, old, (uint32_t) rc)); } + GVLOG (DDS_LC_CONFIG, " set_rcvbuf done\n"); if (set_sndbuf (gv, sock, &gv->config.socket_sndbuf_size) < 0) goto fail_w_socket; + GVLOG (DDS_LC_CONFIG, " set_sndbuf done\n"); + if (gv->config.dontRoute && set_dont_route (gv, sock, ipv6) != DDS_RETCODE_OK) goto fail_w_socket; + GVLOG (DDS_LC_CONFIG, " set_dont_route done\n"); if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK) { @@ -531,6 +593,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ (rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc)); goto fail_w_socket; } + GVLOG (DDS_LC_CONFIG, " ddsrt_bind to port %u done \n", get_socket_port (gv, sock)); if (set_mc_xmit_options) { @@ -538,6 +601,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ if (rc != DDS_RETCODE_OK) goto fail_w_socket; } + GVLOG (DDS_LC_CONFIG, " set_mc_options_transmit %d done\n", set_mc_xmit_options); #ifdef DDS_HAS_NETWORK_CHANNELS if (qos->m_diffserv != 0 && fact->m_kind == NN_LOCATOR_KIND_UDPv4) @@ -571,7 +635,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ conn->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing; conn->m_base.m_locator_fn = ddsi_udp_conn_locator; +#ifdef DDSRT_WITH_FREERTOSTCP + GVLOG (DDS_LC_CONFIG, "ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port); +#else GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port); +#endif *conn_out = &conn->m_base; return DDS_RETCODE_OK; @@ -605,9 +673,13 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo struct ip_mreq mreq; mreq.imr_multiaddr = mcip.a4.sin_addr; if (interf) - memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); + { memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); } else - mreq.imr_interface.s_addr = htonl (INADDR_ANY); + #ifdef DDSRT_WITH_FREERTOSTCP + { mreq.imr_interface = htonl (INADDR_ANY); } + #else + { mreq.imr_interface.s_addr = htonl (INADDR_ANY); } + #endif rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq)); } return (rc == DDS_RETCODE_OK) ? 0 : -1; @@ -714,15 +786,25 @@ static int ddsi_udp_is_mcaddr (const struct ddsi_tran_factory *tran, const ddsi_ switch (loc->kind) { case NN_LOCATOR_KIND_UDPv4: { +#ifdef DDSRT_WITH_FREERTOSTCP + const in_addr_t *ipv4 = (const in_addr_t *) (loc->address + 12); + DDSRT_WARNING_GNUC_OFF(sign-conversion) + return IN_MULTICAST (ntohl (*ipv4)); +#else const struct in_addr *ipv4 = (const struct in_addr *) (loc->address + 12); DDSRT_WARNING_GNUC_OFF(sign-conversion) return IN_MULTICAST (ntohl (ipv4->s_addr)); +#endif DDSRT_WARNING_GNUC_ON(sign-conversion) } case NN_LOCATOR_KIND_UDPv4MCGEN: { const nn_udpv4mcgen_address_t *mcgen = (const nn_udpv4mcgen_address_t *) loc->address; DDSRT_WARNING_GNUC_OFF(sign-conversion) + #ifdef DDSRT_WITH_FREERTOSTCP + return IN_MULTICAST (ntohl (mcgen->ipv4)); + #else return IN_MULTICAST (ntohl (mcgen->ipv4.s_addr)); + #endif DDSRT_WARNING_GNUC_ON(sign-conversion) } #if DDSRT_HAVE_IPV6 @@ -832,7 +914,11 @@ static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const dds memcpy (&mcgen, loc->address, sizeof (mcgen)); memset (&src, 0, sizeof (src)); src.sin_family = AF_INET; + #ifdef DDSRT_WITH_FREERTOSTCP + memcpy (&src.sin_addr, &mcgen.ipv4, 4); + #else memcpy (&src.sin_addr.s_addr, &mcgen.ipv4, 4); + #endif ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst, sizeof_dst); pos = strlen (dst); assert (pos <= sizeof_dst); @@ -876,9 +962,11 @@ static int ddsi_udp_locator_from_sockaddr (const struct ddsi_tran_factory *tran_ if (tran->m_kind != NN_LOCATOR_KIND_UDPv4) return -1; break; +#if DDSRT_HAVE_IPV6 case AF_INET6: if (tran->m_kind != NN_LOCATOR_KIND_UDPv6) return -1; +#endif break; } ddsi_ipaddr_to_loc (loc, sockaddr, tran->m_kind); diff --git a/src/core/ddsi/src/ddsi_wraddrset.c b/src/core/ddsi/src/ddsi_wraddrset.c index d3430d38..dcca2a15 100644 --- a/src/core/ddsi/src/ddsi_wraddrset.c +++ b/src/core/ddsi/src/ddsi_wraddrset.c @@ -691,7 +691,11 @@ static void wras_add_locator (const struct ddsi_domaingv *gv, struct addrset *ne memcpy (&l1, tmploc.c.address, sizeof (l1)); tmploc.c.kind = NN_LOCATOR_KIND_UDPv4; memset (tmploc.c.address, 0, 12); + #ifdef DDSRT_WITH_FREERTOSTCP + iph = ntohl (l1.ipv4); + #else iph = ntohl (l1.ipv4.s_addr); + #endif for (i = 0; i < nreaders; i++) { cover_info_t ci = cover_get (covered, i, locidx); diff --git a/src/core/ddsi/src/q_addrset.c b/src/core/ddsi/src/q_addrset.c index 25759c80..5e1095e1 100644 --- a/src/core/ddsi/src/q_addrset.c +++ b/src/core/ddsi/src/q_addrset.c @@ -96,6 +96,8 @@ int add_addresses_to_addrset (const struct ddsi_domaingv *gv, struct addrset *as DDSRT_WARNING_MSVC_OFF(4996); char *addrs_copy, *cursor, *a; int retval = -1; + + GVLOG (DDS_LC_CONFIG, " add addrs [%s] @@@@@@@@@@@@", addrs); addrs_copy = ddsrt_strdup (addrs); cursor = addrs_copy; while ((a = ddsrt_strsep (&cursor, ",")) != NULL) diff --git a/src/core/ddsi/src/q_ddsi_discovery.c b/src/core/ddsi/src/q_ddsi_discovery.c index 2e60c34b..c293de6c 100644 --- a/src/core/ddsi/src/q_ddsi_discovery.c +++ b/src/core/ddsi/src/q_ddsi_discovery.c @@ -223,6 +223,20 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv external IP address, this locator will be translated into one in the same subnet as our own local ip and selected. */ assert (gv->n_interfaces == 1); // gv->extmask: the hack is only supported if limited to a single interface + #ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t tmp4 = *((in_addr_t *) (loc.address + 12)); + const in_addr_t ownip = *((in_addr_t *) (gv->interfaces[0].loc.address + 12)); + const in_addr_t extip = *((in_addr_t *) (gv->interfaces[0].extloc.address + 12)); + const in_addr_t extmask = *((in_addr_t *) (gv->extmask.address + 12)); + + if ((tmp4 & extmask) == (extip & extmask)) + { + /* translate network part of the IP address from the external + one to the internal one */ + tmp4 = (tmp4 & ~extmask) | (ownip & extmask); + memcpy (loc.address + 12, &tmp4, 4); + } + #else struct in_addr tmp4 = *((struct in_addr *) (loc.address + 12)); const struct in_addr ownip = *((struct in_addr *) (gv->interfaces[0].loc.address + 12)); const struct in_addr extip = *((struct in_addr *) (gv->interfaces[0].extloc.address + 12)); @@ -235,6 +249,8 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv tmp4.s_addr = (tmp4.s_addr & ~extmask.s_addr) | (ownip.s_addr & extmask.s_addr); memcpy (loc.address + 12, &tmp4, 4); } + #endif + } addrset_from_locatorlists_add_one (gv, &loc, as, &intfs, &direct); diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index f04deeca..d934f86c 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -4346,7 +4346,11 @@ static void joinleave_mcast_helper (struct ddsi_domaingv *gv, ddsi_tran_conn_t c memcpy (&l1, l.address, sizeof (l1)); l.kind = NN_LOCATOR_KIND_UDPv4; memset (l.address, 0, 12); + #ifdef DDSRT_WITH_FREERTOSTCP + iph = ntohl (l1.ipv4); + #else iph = ntohl (l1.ipv4.s_addr); + #endif for (uint32_t i = 1; i < ((uint32_t)1 << l1.count); i++) { uint32_t ipn, iph1 = iph; @@ -5987,9 +5991,9 @@ static int proxy_endpoint_common_init (struct entity_common *e, struct proxy_end int ret; if (is_builtin_entityid (guid->entityid, proxypp->vendor)) - assert ((plist->qos.present & QP_TYPE_NAME) == 0); + { assert ((plist->qos.present & QP_TYPE_NAME) == 0); } else - assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); + { assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); } name = (plist->present & PP_ENTITY_NAME) ? plist->entity_name : ""; entity_common_init (e, proxypp->e.gv, guid, name, kind, tcreate, proxypp->vendor, false); diff --git a/src/core/ddsi/src/q_freelist.c b/src/core/ddsi/src/q_freelist.c index 28ed6ea1..9ce76244 100644 --- a/src/core/ddsi/src/q_freelist.c +++ b/src/core/ddsi/src/q_freelist.c @@ -120,6 +120,11 @@ void nn_freelist_init (struct nn_freelist *fl, uint32_t max, size_t linkoff) fl->count = 0; fl->max = (max == UINT32_MAX) ? max-1 : max; fl->linkoff = linkoff; + +#ifdef DDSRT_WITH_FREERTOSTCP + /* init TLS var */ + ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1)); +#endif } static void *get_next (const struct nn_freelist *fl, const void *e) @@ -160,6 +165,27 @@ void nn_freelist_fini (struct nn_freelist *fl, void (*xfree) (void *)) static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0); +#ifdef DDSRT_WITH_FREERTOSTCP +static int get_freelist_inner_idx (void) +{ + int inner_idx = -1; + + inner_idx = ddsrt_thread_tls_get(DDS_TLS_IDX_FREE, freelist_inner_idx); + + if(inner_idx == -1) + { + static const uint64_t unihashconsts[] = { + UINT64_C (16292676669999574021), + UINT64_C (10242350189706880077), + }; + uintptr_t addr; + uint64_t t = (uint64_t) ((uintptr_t) &addr) + ddsrt_atomic_ld32 (&freelist_inner_idx_off); + inner_idx = (int) (((((uint32_t) t + unihashconsts[0]) * ((uint32_t) (t >> 32) + unihashconsts[1]))) >> (64 - NN_FREELIST_NPAR_LG2)); + } + ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, inner_idx); + return inner_idx; +} +#else static int get_freelist_inner_idx (void) { if (freelist_inner_idx == -1) @@ -174,6 +200,7 @@ static int get_freelist_inner_idx (void) } return freelist_inner_idx; } +#endif static int lock_inner (struct nn_freelist *fl) { @@ -185,7 +212,12 @@ static int lock_inner (struct nn_freelist *fl) { ddsrt_atomic_st32(&fl->cc, 0); ddsrt_atomic_inc32(&freelist_inner_idx_off); + + #ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1)); + #else freelist_inner_idx = -1; + #endif } } return k; diff --git a/src/core/ddsi/src/q_gc.c b/src/core/ddsi/src/q_gc.c index 61819126..7941ceb3 100644 --- a/src/core/ddsi/src/q_gc.c +++ b/src/core/ddsi/src/q_gc.c @@ -204,7 +204,11 @@ struct gcreq_queue *gcreq_queue_new (struct ddsi_domaingv *gv) bool gcreq_queue_start (struct gcreq_queue *q) { +#ifdef DDSRT_WITH_FREERTOSTCP + if (create_thread (&q->ts, q->gv, "dds_gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK) +#else if (create_thread (&q->ts, q->gv, "gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK) +#endif return true; else { diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 0338f7e8..f7f4725d 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -130,6 +130,13 @@ static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint3 } ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc); ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc); + + #ifdef DDSRT_WITH_FREERTOSTCP + /* update portid to up */ + *pdisc = gv->disc_conn_uc->m_base.m_port; + *pdata = gv->data_conn_uc->m_base.m_port; + #endif + return MUSRET_SUCCESS; fail_data: @@ -539,6 +546,7 @@ int rtps_config_prep (struct ddsi_domaingv *gv, struct cfgst *cfgst) DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Invalid port mapping: %s\n", message); goto err_config_late_error; } + DDS_ILOG (DDS_LC_INFO, gv->config.domainId, " @@@@@@@@@@@ port mapping: <%s> \n", message); } /* retry_on_reject_duration default is dependent on late_ack_mode and responsiveness timeout, so fix up */ @@ -1022,20 +1030,23 @@ static int setup_and_start_recv_threads (struct ddsi_domaingv *gv) it before it does anything with it. */ if ((gv->recv_threads[i].arg.rbpool = nn_rbufpool_new (&gv->logconfig, gv->config.rbuf_size, gv->config.rmsg_chunk_size)) == NULL) { - GVERROR ("rtps_init: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_start: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name); goto fail; } + GVLOG(DDS_LC_CONFIG, "rtps_start: alloc rbpool %p for recv_thread[%d] '%s' done \n", + gv->recv_threads[i].arg.rbpool, i, gv->recv_threads[i].name); if (gv->recv_threads[i].arg.mode == RTM_MANY) { if ((gv->recv_threads[i].arg.u.many.ws = os_sockWaitsetNew ()) == NULL) { - GVERROR ("rtps_init: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_start: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name); goto fail; } + GVLOG(DDS_LC_CONFIG, "rtps_start: allocate sock waitset for thread %s done \n", gv->recv_threads[i].name); } if (create_thread (&gv->recv_threads[i].ts, gv, gv->recv_threads[i].name, recv_thread, &gv->recv_threads[i].arg) != DDS_RETCODE_OK) { - GVERROR ("rtps_init: failed to start thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_start: failed to start thread %s\n", gv->recv_threads[i].name); goto fail; } } @@ -1339,6 +1350,7 @@ int rtps_init (struct ddsi_domaingv *gv) gv->listener = NULL; gv->debmon = NULL; +#ifndef DDSRT_WITH_FREERTOS /* Print start time for referencing relative times in the remainder of the DDS_LOG. */ { int sec = (int) (gv->tstart.v / 1000000000); @@ -1347,6 +1359,7 @@ int rtps_init (struct ddsi_domaingv *gv) ddsrt_ctime(gv->tstart.v, str, sizeof(str)); GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str); } +#endif /* Allow configuration to set "deaf_mute" in case we want to start out that way */ gv->deaf = gv->config.initial_deaf; @@ -1362,6 +1375,7 @@ int rtps_init (struct ddsi_domaingv *gv) { case DDSI_TRANS_DEFAULT: assert(0); +#ifdef DDSRT_TRANS_UDP case DDSI_TRANS_UDP: case DDSI_TRANS_UDP6: gv->config.publish_uc_locators = 1; @@ -1370,6 +1384,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_UDP ? "udp" : "udp6"); break; +#endif +#ifdef DDSRT_TRANS_TCP case DDSI_TRANS_TCP: case DDSI_TRANS_TCP6: gv->config.publish_uc_locators = (gv->config.tcp_port != -1); @@ -1381,6 +1397,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_TCP ? "tcp" : "tcp6"); break; +#endif +#ifdef DDSRT_TRANS_RAWETH case DDSI_TRANS_RAWETH: gv->config.publish_uc_locators = 1; gv->config.enable_uc_locators = 0; @@ -1390,6 +1408,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, "raweth"); break; +#endif +#ifdef DDSRT_TRANS_NONE case DDSI_TRANS_NONE: gv->config.publish_uc_locators = 0; gv->config.enable_uc_locators = 0; @@ -1399,6 +1419,7 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, "dummy"); break; +#endif } gv->m_factory->m_enable = true; @@ -1423,12 +1444,12 @@ int rtps_init (struct ddsi_domaingv *gv) { if (!gv->interfaces[i].mc_capable) { - GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name); gv->config.allowMulticast = DDSI_AMC_FALSE; /* ensure discovery can work: firstly, that the process will be reachable on a "well-known" port number, and secondly, that the local interface's IP address gets added to the discovery address set */ gv->config.participantIndex = DDSI_PARTICIPANT_INDEX_AUTO; + GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name); } else if (gv->config.allowMulticast & DDSI_AMC_DEFAULT) { @@ -1438,7 +1459,7 @@ int rtps_init (struct ddsi_domaingv *gv) if (gv->interfaces[i].mc_flaky) { gv->config.allowMulticast = DDSI_AMC_SPDP; - GVLOG (DDS_LC_CONFIG, "presumed flaky multicast, use for SPDP only\n"); + GVLOG (DDS_LC_CONFIG, "presumed flaky multicast(0x%08x), use for SPDP only\n", gv->config.allowMulticast); } else { @@ -1447,6 +1468,12 @@ int rtps_init (struct ddsi_domaingv *gv) } } } +#ifdef DDSRT_WITH_FREERTOSTCP + } + else + { + GVWARNING (" (gv->config.allowMulticast) is false! \n"); +#endif } assert ((gv->config.allowMulticast & DDSI_AMC_DEFAULT) == 0); @@ -1573,8 +1600,12 @@ int rtps_init (struct ddsi_domaingv *gv) memcpy (&gv->ppguid_base.prefix.s[2], digest, sizeof (gv->ppguid_base.prefix.s) - 2); gv->ppguid_base.prefix = nn_ntoh_guid_prefix (gv->ppguid_base.prefix); gv->ppguid_base.entityid.u = NN_ENTITYID_PARTICIPANT; + GVLOG(DDS_LC_CONFIG, " GUID prefix: "PGUIDFMT "vs [%08x %08x %08x]", + PGUID (gv->ppguid_base), + gv->ppguid_base.prefix.u[0], gv->ppguid_base.prefix.u[1], gv->ppguid_base.prefix.u[2]); } + ddsrt_mutex_init (&gv->lock); ddsrt_mutex_init (&gv->spdp_lock); gv->spdp_defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples); @@ -1582,6 +1613,8 @@ int rtps_init (struct ddsi_domaingv *gv) gv->m_tkmap = ddsi_tkmap_new (gv); + GVLOG (DDS_LC_CONFIG, "participantIndex %d \n", gv->config.participantIndex); + if (gv->m_factory->m_connless) { if (gv->config.participantIndex >= 0 || gv->config.participantIndex == DDSI_PARTICIPANT_INDEX_NONE) @@ -1600,6 +1633,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_unicast_sockets; case MUSRET_ERROR: /* something bad happened; assume make_uc_sockets logged the error */ + GVERROR ("rtps_init: other failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", + gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc); goto err_unicast_sockets; } } @@ -1621,8 +1656,10 @@ int rtps_init (struct ddsi_domaingv *gv) gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc); goto err_unicast_sockets; case MUSRET_PORTS_IN_USE: /* Try next one */ + GVERROR ("Failed to create unicast sockets PORTS_IN_USE \n"); break; case MUSRET_ERROR: + GVERROR ("Failed to create unicast sockets ERROR \n"); /* something bad happened; assume make_uc_sockets logged the error */ goto err_unicast_sockets; } @@ -1632,6 +1669,7 @@ int rtps_init (struct ddsi_domaingv *gv) GVERROR ("Failed to find a free participant index for domain %"PRIu32"\n", gv->config.extDomainId.value); goto err_unicast_sockets; } + GVLOG (DDS_LC_INFO,"find a participant %d index for domain %"PRIu32"\n", ppid, gv->config.extDomainId.value); gv->config.participantIndex = ppid; } else @@ -1640,11 +1678,12 @@ int rtps_init (struct ddsi_domaingv *gv) } GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc); } - GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); + GVLOG (DDS_LC_INFO, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); if (gv->config.pcap_file && *gv->config.pcap_file) { gv->pcap_fp = new_pcap_file (gv, gv->config.pcap_file); + GVLOG (DDS_LC_CONFIG, "rtps_init: pcap_file %s done \n", gv->config.pcap_file); if (gv->pcap_fp) { ddsrt_mutex_init (&gv->pcap_lock); @@ -2032,6 +2071,8 @@ int rtps_start (struct ddsi_domaingv *gv) return -1; } } + +#ifdef DDSRT_TRANS_TCP if (gv->config.monitor_port >= 0) { if ((gv->debmon = new_debug_monitor (gv, gv->config.monitor_port)) == NULL) @@ -2041,6 +2082,7 @@ int rtps_start (struct ddsi_domaingv *gv) return -1; } } +#endif return 0; } diff --git a/src/core/ddsi/src/q_pcap.c b/src/core/ddsi/src/q_pcap.c index 3b843f79..bb0115c1 100644 --- a/src/core/ddsi/src/q_pcap.c +++ b/src/core/ddsi/src/q_pcap.c @@ -145,8 +145,13 @@ void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud); u.ipv4_hdr.ttl = 128; + #ifdef DDSRT_WITH_FREERTOSTCP + u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr; + u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr; + #else u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr; u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr.s_addr; + #endif u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x); (void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp); udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port; @@ -178,8 +183,13 @@ void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const str u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud); u.ipv4_hdr.ttl = 255; + #ifdef DDSRT_WITH_FREERTOSTCP + u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr; + u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr; + #else u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr; u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr.s_addr; + #endif u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x); (void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp); udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port; diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index e4898c34..65cd2e8b 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -3177,7 +3177,7 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d else if (hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) { if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) - GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", + GVWARNING ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor); if (DDSI_SC_PEDANTIC_P (gv->config)) malformed_packet_received (gv, msg, NULL, (size_t) sz, hdr->vendorid); @@ -3197,6 +3197,12 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d if (res != NN_RTPS_MSG_STATE_ERROR) { handle_submsg_sequence (ts1, gv, conn, srcloc, ddsrt_time_wallclock (), ddsrt_time_elapsed (), &hdr->guid_prefix, guidprefix, msg, (size_t) sz, msg + RTPS_MESSAGE_HEADER_SIZE, rmsg, res == NN_RTPS_MSG_STATE_ENCODED); +#ifdef DDSRT_WITH_FREERTOSTCP + } + else + { + GVWARNING(" decode_rtps_messages error! \n"); +#endif } } } @@ -3229,7 +3235,7 @@ static bool do_packet (struct thread_state1 * const ts1, struct ddsi_domaingv *g buff = (unsigned char *) NN_RMSG_PAYLOAD (rmsg); hdr = (Header_t*) buff; - if (conn->m_stream) + if (conn->m_stream) /* ONLY for TCP conn */ { MsgLen_t * ml = (MsgLen_t*) (hdr + 1); @@ -3446,13 +3452,16 @@ uint32_t listen_thread (struct ddsi_tran_listener *listener) static int recv_thread_waitset_add_conn (os_sockWaitset ws, ddsi_tran_conn_t conn) { if (conn == NULL) - return 0; + { return 0; } else { struct ddsi_domaingv *gv = conn->m_base.gv; for (uint32_t i = 0; i < gv->n_recv_threads; i++) + { + /* SKIP add thread "recvUC" / gv->data_conn_uc to waitset! */ if (gv->recv_threads[i].arg.mode == RTM_SINGLE && gv->recv_threads[i].arg.u.single.conn == conn) - return 0; + { return 0; } + } return os_sockWaitsetAdd (ws, conn); } } @@ -3495,6 +3504,12 @@ uint32_t recv_thread (void *vrecv_thread_arg) os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL; ddsrt_mtime_t next_thread_cputime = { 0 }; +#ifdef DDSRT_WITH_FREERTOS + char name[64]; + ddsrt_thread_getname (name, sizeof (name)); + DDS_WARNING("recv_thread: called up for thread[%s] \n", name); +#endif + nn_rbufpool_setowner (rbpool, ddsrt_thread_self ()); if (waitset == NULL) { @@ -3515,17 +3530,36 @@ uint32_t recv_thread (void *vrecv_thread_arg) { int rc; if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_uc)) < 0) - DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); + { DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); } + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add disc_conn_uc to waitset ! \n"); } + #endif num_fixed_uc += (unsigned)rc; + if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_uc)) < 0) DDS_FATAL("recv_thread: failed to add data_conn_uc to waitset\n"); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add data_conn_uc to waitset ! \n"); } + #endif num_fixed_uc += (unsigned)rc; + num_fixed += num_fixed_uc; if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_mc)) < 0) DDS_FATAL("recv_thread: failed to add disc_conn_mc to waitset\n"); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add disc_conn_mc to waitset ! \n"); } + #endif num_fixed += (unsigned)rc; + if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_mc)) < 0) DDS_FATAL("recv_thread: failed to add data_conn_mc to waitset\n"); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add data_conn_mc to waitset ! \n"); } + #endif num_fixed += (unsigned)rc; // OpenDDS doesn't respect the locator lists and insists on sending to the @@ -3535,9 +3569,13 @@ uint32_t recv_thread (void *vrecv_thread_arg) // Iceoryx gets added as a pseudo-interface but there's no socket to wait // for input on if (ddsi_conn_handle (gv->xmit_conns[i]) == DDSRT_INVALID_SOCKET) - continue; + { continue; } if ((rc = recv_thread_waitset_add_conn (waitset, gv->xmit_conns[i])) < 0) - DDS_FATAL("recv_thread: failed to add transmit_conn[%d] to waitset\n", i); + DDS_FATAL("recv_thread: failed to add xmit_conn[%d] to waitset\n", i); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add xmit_conn[%d] to waitset ! \n", i); } + #endif num_fixed += (unsigned)rc; } } @@ -3564,7 +3602,7 @@ uint32_t recv_thread (void *vrecv_thread_arg) for (uint32_t i = 0; i < lps.nps; i++) { if (lps.ps[i].m_conn) - os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); + { os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); } } } @@ -3575,13 +3613,18 @@ uint32_t recv_thread (void *vrecv_thread_arg) while ((idx = os_sockWaitsetNextEvent (ctx, &conn)) >= 0) { const ddsi_guid_prefix_t *guid_prefix; - if (((unsigned)idx < num_fixed) || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST) - guid_prefix = NULL; + if (((unsigned)idx < num_fixed) + || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST) + { guid_prefix = NULL; } else - guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; + { guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; } + /* Process message and clean out connection if failed or closed */ - if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) && !conn->m_connless) + if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) + && !conn->m_connless) + { ddsi_conn_free (conn); + } } } } diff --git a/src/core/ddsi/src/q_sockwaitset_s.c b/src/core/ddsi/src/q_sockwaitset_s.c new file mode 100755 index 00000000..323ef36a --- /dev/null +++ b/src/core/ddsi/src/q_sockwaitset_s.c @@ -0,0 +1,522 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/sockets.h" +#include "dds/ddsrt/sync.h" + +#include "dds/ddsi/q_sockwaitset.h" +#include "dds/ddsi/ddsi_config_impl.h" +#include "dds/ddsi/q_log.h" +#include "dds/ddsi/ddsi_tran.h" + +#define WAITSET_DELTA 8 + +#define MODE_KQUEUE 1 +#define MODE_SELECT 2 +#define MODE_WFMEVS 3 + +#if defined __APPLE__ +#define MODE_SEL MODE_KQUEUE +#elif defined WINCE +#define MODE_SEL MODE_WFMEVS +#else +#define MODE_SEL MODE_SELECT /* FreeRTOS always use select */ +#endif + + +#ifdef DDSRT_WITH_FREERTOSTCP +# warning " *** HKR debug include tree " + +#else +#if !_WIN32 && !LWIP_SOCKET + +#if ! __VXWORKS__&& !__QNXNTO__ +#include +#endif /* __VXWORKS__ __QNXNTO__ */ + +#ifndef _WRS_KERNEL +#include +#endif +#ifdef __sun +#include +#include +#include +#endif + +#endif /* !_WIN32 && !LWIP_SOCKET */ +#endif + +typedef struct os_sockWaitsetSet +{ + ddsi_tran_conn_t * conns; /* connections in set */ + ddsrt_socket_t * fds; /* file descriptors in set */ + unsigned sz; /* max number of fds in context */ + unsigned n; /* actual number of fds in context */ +} os_sockWaitsetSet; + +struct os_sockWaitsetCtx +{ + os_sockWaitsetSet set; /* set of connections and descriptors */ + unsigned index; /* cursor for enumerating */ + ddsrt_fd_set_t rdset; /* read file descriptors set */ +}; + +struct os_sockWaitset +{ + ddsrt_socket_t pipe[2]; /* pipe used for triggering */ + ddsrt_mutex_t mutex; /* concurrency guard */ + int fdmax_plus_1; /* value for first parameter of select() */ + os_sockWaitsetSet set; /* set of descriptors handled next */ + struct os_sockWaitsetCtx ctx; /* set of descriptors being handled */ +}; + +#if defined (_WIN32) +static int make_pipe (ddsrt_socket_t fd[2]) +{ + struct sockaddr_in addr; + socklen_t asize = sizeof (addr); + ddsrt_socket_t listener = socket (AF_INET, SOCK_STREAM, 0); + ddsrt_socket_t s1 = socket (AF_INET, SOCK_STREAM, 0); + ddsrt_socket_t s2 = DDSRT_INVALID_SOCKET; + + addr.sin_family = AF_INET; + #ifdef DDSRT_WITH_FREERTOSTCP + addr.sin_addr = htonl (INADDR_LOOPBACK); + #else + addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + #endif + addr.sin_port = 0; + if (bind (listener, (struct sockaddr *)&addr, sizeof (addr)) == -1) + goto fail; + if (getsockname (listener, (struct sockaddr *)&addr, &asize) == -1) + goto fail; + if (listen (listener, 1) == -1) + goto fail; + if (connect (s1, (struct sockaddr *)&addr, sizeof (addr)) == -1) + goto fail; + if ((s2 = accept (listener, 0, 0)) == INVALID_SOCKET) + goto fail; + closesocket (listener); + /* Equivalent to FD_CLOEXEC */ + SetHandleInformation ((HANDLE) s1, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation ((HANDLE) s2, HANDLE_FLAG_INHERIT, 0); + fd[0] = s1; + fd[1] = s2; + return 0; + +fail: + closesocket (listener); + closesocket (s1); + closesocket (s2); + return -1; +} +#elif defined(__VXWORKS__) +static int make_pipe (int pfd[2]) +{ + char pipename[OSPL_PIPENAMESIZE]; + int pipecount = 0; + do { + snprintf ((char*)&pipename, sizeof (pipename), "/pipe/ospl%d", pipecount++); + } while ((result = pipeDevCreate ((char*)&pipename, 1, 1)) == -1 && os_getErrno() == EINVAL); + if (result == -1) + goto fail_pipedev; + if ((pfd[0] = open ((char*)&pipename, O_RDWR, 0644)) == -1) + goto fail_open0; + if ((pfd[1] = open ((char*)&pipename, O_RDWR, 0644)) == -1) + goto fail_open1; + return 0; + +fail_open1: + close (pfd[0]); +fail_open0: + pipeDevDelete (pipename, 0); +fail_pipedev: + return -1; +} +#elif !defined(LWIP_SOCKET) +static int make_pipe (int pfd[2]) +{ + return pipe (pfd); +} +#endif + +static void os_sockWaitsetNewSet (os_sockWaitsetSet * set) +{ + set->fds = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->fds)); + set->conns = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->conns)); + set->sz = WAITSET_DELTA; + set->n = 1; +} + +static void os_sockWaitsetFreeSet (os_sockWaitsetSet * set) +{ + ddsrt_free (set->fds); + ddsrt_free (set->conns); +} + +static void os_sockWaitsetNewCtx (os_sockWaitsetCtx ctx) +{ + os_sockWaitsetNewSet (&ctx->set); + + #ifdef DDSRT_WITH_FREERTOSTCP + ctx->rdset = DDSRT_FD_SET_CRATE(); + DDSRT_FD_ZERO (ctx->rdset); + DDS_WARNING("os_sockWaitsetNewCtx: rdset created! rdset %p \n", ctx->rdset); + #else + FD_ZERO (ctx->rdset); + #endif +} + +static void os_sockWaitsetFreeCtx (os_sockWaitsetCtx ctx) +{ + #ifdef DDSRT_WITH_FREERTOSTCP + DDSRT_FD_SET_DELETE(ctx->rdset); + #endif + os_sockWaitsetFreeSet (&ctx->set); +} + +os_sockWaitset os_sockWaitsetNew (void) +{ + int result; + os_sockWaitset ws = ddsrt_malloc (sizeof (*ws)); + + os_sockWaitsetNewSet (&ws->set); + os_sockWaitsetNewCtx (&ws->ctx); + +#if ! defined (_WIN32) + ws->fdmax_plus_1 = 0; +#else + ws->fdmax_plus_1 = FD_SETSIZE; +#endif + +#if defined(LWIP_SOCKET) + ws->pipe[0] = -1; + ws->pipe[1] = -1; + result = 0; +#elif defined(DDSRT_WITH_FREERTOSTCP) + # warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." + ws->pipe[0] = -1; + ws->pipe[1] = -1; + result = 0; +#else + # error " *** NO makepipe for FreeRTOS " + + result = make_pipe (ws->pipe); +#endif + if (result == -1) + { + os_sockWaitsetFreeCtx (&ws->ctx); + os_sockWaitsetFreeSet (&ws->set); + ddsrt_free (ws); + return NULL; + } + +#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + ws->set.fds[0] = ws->pipe[0]; +#else +#warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." + ws->set.fds[0] = 0; +#endif + ws->set.conns[0] = NULL; + +#if !defined(__VXWORKS__) && !defined(_WIN32) && !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) && !defined(__QNXNTO__) + (void) fcntl (ws->pipe[0], F_SETFD, fcntl (ws->pipe[0], F_GETFD) | FD_CLOEXEC); + (void) fcntl (ws->pipe[1], F_SETFD, fcntl (ws->pipe[1], F_GETFD) | FD_CLOEXEC); +#endif + +#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + FD_SET (ws->set.fds[0], ws->ctx.rdset); +#endif + +#if !defined(_WIN32) && !defined(DDSRT_WITH_FREERTOSTCP) + ws->fdmax_plus_1 = ws->set.fds[0] + 1; +#endif + + ddsrt_mutex_init (&ws->mutex); + + return ws; +} + +static void os_sockWaitsetGrow (os_sockWaitsetSet * set) +{ + set->sz += WAITSET_DELTA; + set->conns = ddsrt_realloc (set->conns, set->sz * sizeof (*set->conns)); + set->fds = ddsrt_realloc (set->fds, set->sz * sizeof (*set->fds)); +} + +void os_sockWaitsetFree (os_sockWaitset ws) +{ +#if defined(__VXWORKS__) && defined(__RTP__) + char nameBuf[OSPL_PIPENAMESIZE]; + ioctl (ws->pipe[0], FIOGETNAME, &nameBuf); +#endif + +#if defined(DDSRT_WITH_FREERTOSTCP) +# warning " *** HKR runtime tree " + (void) ddsrt_close (ws->pipe[0]); + (void) ddsrt_close (ws->pipe[1]); +#else + +#if defined(_WIN32) + closesocket (ws->pipe[0]); + closesocket (ws->pipe[1]); +#elif !defined(LWIP_SOCKET) + (void) close (ws->pipe[0]); + (void) close (ws->pipe[1]); +#endif +#endif + +#if defined(__VXWORKS__) && defined(__RTP__) + pipeDevDelete ((char*) &nameBuf, 0); +#endif + os_sockWaitsetFreeSet (&ws->set); + os_sockWaitsetFreeCtx (&ws->ctx); + ddsrt_mutex_destroy (&ws->mutex); + ddsrt_free (ws); +} + +void os_sockWaitsetTrigger (os_sockWaitset ws) +{ +#if defined(LWIP_SOCKET) + (void)ws; +#elif defined (DDSRT_WITH_FREERTOSTCP) +#warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." + (void)ws; +#else + char buf = 0; + int n; + +#if defined (_WIN32) + n = send (ws->pipe[1], &buf, 1, 0); +#else + n = (int) write (ws->pipe[1], &buf, 1); +#endif + if (n != 1) + { + DDS_WARNING("os_sockWaitsetTrigger: write failed on trigger pipe\n"); + } +#endif +} + +int os_sockWaitsetAdd (os_sockWaitset ws, ddsi_tran_conn_t conn) +{ + ddsrt_socket_t handle = ddsi_conn_handle (conn); + os_sockWaitsetSet * set = &ws->set; + unsigned idx; + int ret; + +#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP) + assert (handle >= 0); + assert (handle < FD_SETSIZE); +#endif + + ddsrt_mutex_lock (&ws->mutex); + for (idx = 0; idx < set->n; idx++) + { + if (set->conns[idx] == conn) + break; + } + if (idx < set->n) + { ret = 0; } + else + { + if (set->n == set->sz) + { os_sockWaitsetGrow (set); } +#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP) + if ((int) handle >= ws->fdmax_plus_1) + ws->fdmax_plus_1 = handle + 1; +#endif + set->conns[set->n] = conn; + set->fds[set->n] = handle; + set->n++; + ret = 1; + } + ddsrt_mutex_unlock (&ws->mutex); + return ret; +} + +void os_sockWaitsetPurge (os_sockWaitset ws, unsigned index) +{ + os_sockWaitsetSet * set = &ws->set; + + ddsrt_mutex_lock (&ws->mutex); + if (index + 1 <= set->n) + { + for (unsigned i = index + 1; i < set->n; i++) + { + set->conns[i] = NULL; + set->fds[i] = 0; + } + set->n = index + 1; + } + ddsrt_mutex_unlock (&ws->mutex); +} + +void os_sockWaitsetRemove (os_sockWaitset ws, ddsi_tran_conn_t conn) +{ + os_sockWaitsetSet * set = &ws->set; + + ddsrt_mutex_lock (&ws->mutex); + for (unsigned i = 0; i < set->n; i++) + { + if (conn == set->conns[i]) + { + set->n--; + if (i != set->n) + { + set->fds[i] = set->fds[set->n]; + set->conns[i] = set->conns[set->n]; + } + break; + } + } + ddsrt_mutex_unlock (&ws->mutex); +} + +os_sockWaitsetCtx os_sockWaitsetWait (os_sockWaitset ws) +{ + unsigned u; +#if !_WIN32 + int fdmax; +#endif + ddsrt_fd_set_t rdset = NULL; + os_sockWaitsetCtx ctx = &ws->ctx; + os_sockWaitsetSet * dst = &ctx->set; + os_sockWaitsetSet * src = &ws->set; + + ddsrt_mutex_lock (&ws->mutex); + +#ifdef DDSRT_WITH_FREERTOSTCP + fdmax = 0; /* For FreeRTOS_TCP stack, fdmax is stub for api compatible */ +#else + #if !_WIN32 + fdmax = ws->fdmax_plus_1; + #endif +#endif + + /* Copy context to working context */ + + while (dst->sz < src->sz) + { + os_sockWaitsetGrow (dst); + } + dst->n = src->n; + + for (u = 0; u < src->n; u++) + { + dst->conns[u] = src->conns[u]; + dst->fds[u] = src->fds[u]; + } + + ddsrt_mutex_unlock (&ws->mutex); + + + /* Copy file descriptors into select read set */ + rdset = ctx->rdset; +#ifdef DDSRT_WITH_FREERTOSTCP + if (rdset == NULL) + { + assert(0); + } + +#endif + + DDSRT_FD_ZERO (rdset); +#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + for (u = 0; u < dst->n; u++) + { + FD_SET (dst->fds[u], rdset); + } +#else + /* fds[0]/conns[0] not using for RTOS */ + for (u = 1; u < dst->n; u++) + { + DDSRT_WARNING_GNUC_OFF(sign-conversion) + DDSRT_FD_SET (dst->fds[u], rdset); + DDSRT_WARNING_GNUC_ON(sign-conversion) + } +#endif /* LWIP_SOCKET */ + + dds_return_t rc; + do + { + rc = ddsrt_select (fdmax, rdset, NULL, NULL, SELECT_TIMEOUT_MS); + if (rc < 0 && rc != DDS_RETCODE_INTERRUPTED && rc != DDS_RETCODE_TRY_AGAIN) + { + DDS_WARNING("os_sockWaitsetWait: select failed, retcode = %"PRId32, rc); + break; + } + } while (rc < 0); + + if (rc > 0) + { + /* set start VALID conn index + * this simply skips the trigger fd, index0 is INV. + */ + ctx->index = 1; + + /* to confirm for DDSRT_WITH_FREERTOSTCP + TODO + TODO + TODO + TODO + TODO + TODO + */ +#if ! defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + if (FD_ISSET (dst->fds[0], rdset)) + { + char buf; + int n1; + #if defined (_WIN32) + n1 = recv (dst->fds[0], &buf, 1, 0); + #else + n1 = (int) read (dst->fds[0], &buf, 1); + #endif + if (n1 != 1) + { + DDS_WARNING("os_sockWaitsetWait: read failed on trigger pipe\n"); + assert (0); + } + } +#endif /* LWIP_SOCKET */ + return ctx; + } + + return NULL; +} + +int os_sockWaitsetNextEvent (os_sockWaitsetCtx ctx, ddsi_tran_conn_t * conn) +{ + while (ctx->index < ctx->set.n) + { + unsigned idx = ctx->index++; + ddsrt_socket_t fd = ctx->set.fds[idx]; +#if ! defined (LWIP_SOCKET) && ! defined(DDSRT_WITH_FREERTOSTCP) + assert(idx > 0); +#endif + + if (DDSRT_FD_ISSET (fd, ctx->rdset)) + { + *conn = ctx->set.conns[idx]; + + return (int) (idx - 1); + } + } + return -1; +} + + diff --git a/src/core/ddsi/src/q_thread.c b/src/core/ddsi/src/q_thread.c index 6de01fa1..3205bc74 100644 --- a/src/core/ddsi/src/q_thread.c +++ b/src/core/ddsi/src/q_thread.c @@ -109,7 +109,12 @@ void thread_states_init (unsigned maxthreads) (not strictly required, but it'll get one eventually anyway, and this makes it rather more clear). */ #ifndef NDEBUG +#ifdef DDSRT_WITH_FREERTOSTCP + struct thread_state1 * const ts0 = (struct thread_state1 * const)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); +#else struct thread_state1 * const ts0 = tsd_thread_state; +#endif + #endif struct thread_state1 * const ts1 = lookup_thread_state_real (); assert (ts0 == NULL || ts0 == ts1); @@ -124,7 +129,12 @@ bool thread_states_fini (void) struct thread_state1 *ts1 = lookup_thread_state (); assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime))); reap_thread_state (ts1, true); + + #ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL); + #else tsd_thread_state = NULL; + #endif /* Some applications threads that, at some point, required a thread state, may still be around. Of those, the cleanup routine is invoked when the thread terminates. This should be rewritten @@ -215,13 +225,22 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self) struct thread_state1 *lookup_thread_state_real (void) { +#ifdef DDSRT_WITH_FREERTOSTCP + struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); +#else struct thread_state1 *ts1 = tsd_thread_state; +#endif + if (ts1 == NULL) { ddsrt_thread_t self = ddsrt_thread_self (); if ((ts1 = find_thread_state (self)) == NULL) ts1 = lazy_create_thread_state (self); +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1); +#else tsd_thread_state = ts1; +#endif } assert (ts1 != NULL); return ts1; @@ -232,9 +251,19 @@ static uint32_t create_thread_wrapper (void *ptr) struct thread_state1 * const ts1 = ptr; struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv); if (gv) - GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ts1->name); + { + #ifndef DDSRT_WITH_FREERTOSTCP + GVTRACE ("started new thread %"PRIdTID": %s \n", ddsrt_gettid (), ts1->name); + #else + GVTRACE ("started new thread %"PRIdTID": %s, thread_t 0x%lx \n", ddsrt_gettid (), ts1->name, ts1->tid.task); + #endif + } assert (ts1->state == THREAD_STATE_INIT); +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1); +#else tsd_thread_state = ts1; +#endif ddsrt_mutex_lock (&thread_states.lock); ts1->state = THREAD_STATE_ALIVE; ddsrt_mutex_unlock (&thread_states.lock); @@ -242,7 +271,12 @@ static uint32_t create_thread_wrapper (void *ptr) ddsrt_mutex_lock (&thread_states.lock); ts1->state = THREAD_STATE_STOPPED; ddsrt_mutex_unlock (&thread_states.lock); +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL); +#else tsd_thread_state = NULL; +#endif + return ret; } diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index 3e07fb55..b1bbd0d3 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -323,18 +323,32 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_ { if (ddsrt_avl_is_empty (&wr->readers)) { +#ifdef DDSRT_WITH_FREERTOSTCP + ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + *hbansreq ? "" : " final", + (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, +#endif whcst->max_seq, writer_read_seq_xmit(wr)); } else { +#ifdef DDSRT_WITH_FREERTOSTCP + ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + *hbansreq ? "" : " final", + (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, +#endif root_rdmatch (wr)->min_seq, root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!", whcst->max_seq, writer_read_seq_xmit(wr)); diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index 62af2967..0b285405 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -531,14 +531,22 @@ struct xeventq * xeventq_new (struct ddsi_domaingv *gv, size_t max_queued_rexmit dds_return_t xeventq_start (struct xeventq *evq, const char *name) { dds_return_t rc; +#ifdef DDSRT_WITH_FREERTOSTCP + char * evqname = "dds_tev"; +#else char * evqname = "tev"; +#endif assert (evq->ts == NULL); if (name) { size_t slen = strlen (name) + 5; evqname = ddsrt_malloc (slen); + #ifdef DDSRT_WITH_FREERTOSTCP + (void) snprintf (evqname, slen, "dds_tev.%s", name); + #else (void) snprintf (evqname, slen, "tev.%s", name); + #endif } evq->terminate = 0; @@ -764,20 +772,36 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt if (ddsrt_avl_is_empty (&wr->readers)) { - GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", +#ifdef DDSRT_WITH_FREERTOSTCP + GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + hbansreq ? "" : " final", + msg ? "sent" : "suppressed", + (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else + GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, +#endif whcst.max_seq, writer_read_seq_xmit (wr)); } else { - GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", +#ifdef DDSRT_WITH_FREERTOSTCP + GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", - (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, + (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else + GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + hbansreq ? "" : " final", + msg ? "sent" : "suppressed", + (t_next.v == DDS_NEVER) ? DDS_NEVER : (double)(t_next.v - tnow.v) / 1e9, +#endif ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq, ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!", whcst.max_seq, writer_read_seq_xmit (wr)); @@ -1028,10 +1052,18 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e else { ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (tnow, DDS_SECS (1)); - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", +#ifdef DDSRT_WITH_FREERTOSTCP + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n", + PGUID (pp->e.guid), + PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, + (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec + ); +#else + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9); +#endif (void) resched_xevent_if_earlier (ev, tnext); } } @@ -1055,10 +1087,18 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e intv = gv->config.spdp_interval; tnext = ddsrt_mtime_add_duration (tnow, intv); - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", + #ifdef DDSRT_WITH_FREERTOSTCP + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n", + PGUID (pp->e.guid), + PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, + (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec + ); + #else + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9); + #endif (void) resched_xevent_if_earlier (ev, tnext); } } @@ -1091,7 +1131,13 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_ tnext.v = tnow.v + intv - DDS_SECS (2); else tnext.v = tnow.v + 4 * intv / 5; - GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); + #ifdef DDSRT_WITH_FREERTOSTCP + GVTRACE ("resched pmd("PGUIDFMT"): %u usec\n", PGUID (pp->e.guid), + (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec + ); + #else + GVTRACE ("resched pmd("PGUIDFMT"): %g s\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); + #endif } (void) resched_xevent_if_earlier (ev, tnext); @@ -1127,6 +1173,12 @@ static void handle_individual_xevent (struct thread_state1 * const ts1, struct x switch (xev->kind) { case XEVK_HEARTBEAT: + #ifdef DDSRT_WITH_FREERTOSTCP + { + static uint32_t hb_cnt = 0U; + DDS_WARNING(" handle_xevk_heartbeat %u ... ", hb_cnt++); + } + #endif handle_xevk_heartbeat (xp, xev, tnow); break; case XEVK_ACKNACK: diff --git a/src/core/ddsi/src/q_xmsg.c b/src/core/ddsi/src/q_xmsg.c index aa5bbc75..1cb12543 100644 --- a/src/core/ddsi/src/q_xmsg.c +++ b/src/core/ddsi/src/q_xmsg.c @@ -121,6 +121,7 @@ struct nn_xmsg { #ifdef IOV_MAX #if IOV_MAX > 0 && IOV_MAX < 256 +#error " you should not be here for DDSRT_WITH_FREERTOSTCP" #define NN_XMSG_MAX_MESSAGE_IOVECS IOV_MAX #endif #endif /* defined IOV_MAX */ @@ -1248,7 +1249,15 @@ static ssize_t nn_xpack_send1 (const ddsi_xlocator_t *loc, void * varg) } /* Possible number of bytes written can be larger * due to security. */ + #ifdef DDSRT_WITH_FREERTOSTCP + if (nbytes < len) + { + GVERROR (" sent len is NOT right! len %u v %u", len, nbytes); + assert (nbytes == -1 || (size_t) nbytes >= len); + } + #else assert (nbytes == -1 || (size_t) nbytes >= len); + #endif } #endif } @@ -1718,7 +1727,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag const uint32_t max_msg_size = rexmit ? xp->gv->config.max_rexmit_msg_size : xp->gv->config.max_msg_size; if (xpo_niov > 0 && sz > max_msg_size) { - GVTRACE (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", + GVINFO (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", (int) niov, sz, max_msg_size, (int) xpo_niov, xpo_sz); xp->msg_len.length = xpo_sz; xp->niov = xpo_niov; diff --git a/src/ddsrt/include/dds/config.h.in b/src/ddsrt/include/dds/config.h.in index 87493ab3..f33ed369 100644 --- a/src/ddsrt/include/dds/config.h.in +++ b/src/ddsrt/include/dds/config.h.in @@ -15,6 +15,17 @@ #cmakedefine DDSRT_WITH_LWIP 1 #cmakedefine DDSRT_WITH_FREERTOS 1 +/* begin: FreeRTOS_Plus_TCP IP stack */ +#cmakedefine DDSRT_WITH_FREERTOSTCP 1 + +#cmakedefine DDSRT_TRANS_UDP 1 +#cmakedefine DDSRT_TRANS_TCP 1 +#cmakedefine DDSRT_TRANS_RAWETH 1 +#cmakedefine DDSRT_TRANS_NONE 1 + +/* end: FreeRTOS_Plus_TCP IP stack */ + + #cmakedefine DDSRT_HAVE_DYNLIB 1 #cmakedefine DDSRT_HAVE_FILESYSTEM 1 #cmakedefine DDSRT_HAVE_NETSTAT 1 diff --git a/src/ddsrt/include/dds/ddsrt/iovec.h b/src/ddsrt/include/dds/ddsrt/iovec.h index cbfa3514..3e9fe845 100644 --- a/src/ddsrt/include/dds/ddsrt/iovec.h +++ b/src/ddsrt/include/dds/ddsrt/iovec.h @@ -26,6 +26,15 @@ typedef unsigned long ddsrt_msg_iovlen_t; #if DDSRT_WITH_LWIP #include + +#elif defined DDSRT_WITH_FREERTOSTCP +#warning "debug rtos tcp stack including " +/* will implement struct io_vec in freertos_plus_tcp.h wrapper header. */ + +struct iovec { + void *iov_base; + size_t iov_len; +}; #else #include #include @@ -36,6 +45,8 @@ typedef size_t ddsrt_iov_len_t; #if defined(__linux) && !LWIP_SOCKET typedef size_t ddsrt_msg_iovlen_t; +#elif defined DDSRT_WITH_FREERTOSTCP +typedef size_t ddsrt_msg_iovlen_t; #else /* POSIX says int (which macOS, FreeBSD, Solaris do) */ typedef int ddsrt_msg_iovlen_t; #endif diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index dabdacb8..cbe31492 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -24,6 +24,9 @@ #include #include +#include "dds/config.h" +#include "dds/features.h" + #include "dds/export.h" #include "dds/ddsrt/attributes.h" @@ -87,8 +90,12 @@ extern "C" { DDS_LC_CONTENT | DDS_LC_SHM) /** @}*/ +#ifdef DDSRT_WITH_FREERTOSTCP +#define DDS_LOG_MASK DDS_LC_ALL +#else #define DDS_LOG_MASK \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO) +#endif #define DDS_TRACE_MASK \ (~DDS_LOG_MASK) @@ -382,9 +389,15 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_LOG(cat, ...) \ ((dds_get_log_mask() & (cat)) ? \ dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) +#else +#define DDS_LOG(cat, fmt, ...) \ + ((dds_get_log_mask() & (cat)) ? \ + dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, fmt, ##__VA_ARGS__) : 0) +#endif /** * @brief Write a log message with a domain id override. @@ -398,10 +411,15 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_ILOG(cat, domid, ...) \ ((dds_get_log_mask() & (cat)) ? \ dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) - +#else +#define DDS_ILOG(cat, domid, fmt, ...) \ + ((dds_get_log_mask() & (cat)) ? \ + dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, fmt " \n", ##__VA_ARGS__) : 0) +#endif /** * @brief Write a log message using a specific config. * @@ -414,9 +432,15 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_CLOG(cat, cfg, ...) \ (((cfg)->c.mask & (cat)) ? \ dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) +#else +#define DDS_CLOG(cat, cfg, fmt, ...) \ + (((cfg)->c.mask & (cat)) ? \ + dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) : 0) +#endif /** Write a log message of type #DDS_LC_INFO into global log. */ #define DDS_INFO(...) \ @@ -428,8 +452,13 @@ dds_log( #define DDS_ERROR(...) \ DDS_LOG(DDS_LC_ERROR, __VA_ARGS__) /** Write a log message of type #DDS_LC_ERROR into global log and abort. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_FATAL(...) \ dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) +#else +#define DDS_FATAL(fmt, ...) \ + dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) +#endif /* MSVC mishandles __VA_ARGS__ while claiming to be conforming -- and even if they have a defensible implement, they still differ from every other diff --git a/src/ddsrt/include/dds/ddsrt/process.h b/src/ddsrt/include/dds/ddsrt/process.h index c074d084..84e75197 100644 --- a/src/ddsrt/include/dds/ddsrt/process.h +++ b/src/ddsrt/include/dds/ddsrt/process.h @@ -55,6 +55,18 @@ extern "C" { DDS_EXPORT ddsrt_pid_t ddsrt_getpid(void); +/** + * @brief Return process name of the calling process. + * + * On linux maps to /proc/self/cmdline's first entry (argv[0]), + * on mac/windows maps to relevant API calls. Falls back to process-{pid} + * on failure. + * + * @returns The process name of the calling process. + */ +DDS_EXPORT char * +ddsrt_getprocessname(void); + #if defined (__cplusplus) } #endif diff --git a/src/ddsrt/include/dds/ddsrt/sockets.h b/src/ddsrt/include/dds/ddsrt/sockets.h index 65b40ed5..4a911c67 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets.h +++ b/src/ddsrt/include/dds/ddsrt/sockets.h @@ -10,10 +10,16 @@ #include "dds/ddsrt/retcode.h" #include "dds/ddsrt/time.h" #include "dds/ddsrt/misc.h" -#if _WIN32 -#include "dds/ddsrt/sockets/windows.h" + +#if defined DDSRT_WITH_FREERTOSTCP + #warning " debug rtos tcp stack including " + #include "dds/ddsrt/sockets/freertos_plus_tcp.h" #else -#include "dds/ddsrt/sockets/posix.h" + #if _WIN32 + #include "dds/ddsrt/sockets/windows.h" + #else + #include "dds/ddsrt/sockets/posix.h" + #endif #endif #if defined (__cplusplus) @@ -187,9 +193,15 @@ ddsrt_setsockreuse( DDS_EXPORT dds_return_t ddsrt_select( int32_t nfds, +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_fd_set_t readfds, + ddsrt_fd_set_t writefds, + ddsrt_fd_set_t errorfds, +#else fd_set *readfds, fd_set *writefds, fd_set *errorfds, +#endif dds_duration_t reltime); #if _WIN32 diff --git a/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h new file mode 100755 index 00000000..c2c01e22 --- /dev/null +++ b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h @@ -0,0 +1,245 @@ +/* + * INTEL CONFIDENTIAL + * + * Copyright (C) 2022 Intel Corporation + * + * This software and the related documents are Intel copyrighted materials, + * and your use of them is governed by the express license under which they + * were provided to you ("License"). Unless the License provides otherwise, + * you may not use, modify, copy, publish, distribute, disclose or transmit + * this software or the related documents without Intel's prior written permission. + * This software and the related documents are provided as is, with no express + * or implied warranties, other than those that are expressly + * stated in the License. + */ + +#ifndef DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H +#define DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H + +#define __need_size_t +#include + +/* This operating system-specific header file defines the SOCK_*, PF_*, + AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr', + `struct msghdr', and `struct linger' types. */ + +#include + +#include +#include +#include +#include + +#include "dds/ddsrt/iovec.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#ifndef ntohl +#define ntohl FreeRTOS_ntohl +#define htol FreeRTOS_htonl + +#define htos FreeRTOS_htons +#define ntohs FreeRTOS_ntohs +#endif + +#define inet_addr FreeRTOS_inet_addr +#define IN_MULTICAST(ip) (xIsIPv4Multicast(ntohl(ip))) + + +/* posix data for FreeRTOS+TCP stack */ +#define DDSRT_HAVE_SSM 0 +#define IFF_UP 0x1 +#define IFF_BROADCAST 0x2 +#define IFF_LOOPBACK 0x8 +#define IFF_POINTOPOINT 0x10 +#define IFF_MULTICAST 0x1000 + +struct msghdr +{ + void *msg_name; + socklen_t msg_namelen; + struct iovec *msg_iov; + int msg_iovlen; + void *msg_control; + socklen_t msg_controllen; + int msg_flags; +}; + +struct timeval +{ + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +typedef struct msghdr ddsrt_msghdr_t; +#define DDSRT_MSGHDR_FLAGS 0 + + +/* adaption to ddsrt socket interface */ +typedef Socket_t ddsrt_socket_t; /* Socket_t ==> FreeRTOS_Socket_t* */ +// typedef SocketSelect_t fd_set; /* SocketSelect_t => struct xSOCKET_SET */ +typedef SocketSet_t ddsrt_fd_set_t; + +#define SELECT_TIMEOUT_MS 1000U /* 200U experienced value from XRCE-client */ + +/* +FD_ZERO() clears a set. +FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set. +FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns. +*/ +static inline void DDSRT_FD_ZERO(ddsrt_fd_set_t set) +{ + (void)set; +} + +static ddsrt_fd_set_t DDSRT_FD_SET_CRATE(void) +{ + SocketSet_t set = FreeRTOS_CreateSocketSet(); + assert(set); + return set; +} + +static void DDSRT_FD_SET_DELETE(ddsrt_fd_set_t set) +{ + assert(set); + FreeRTOS_DeleteSocketSet(set); +} + +/* +#define DDSRT_FD_ISSET(fd, set) FreeRTOS_FD_ISSET(fd, set) +#define DDSRT_FD_SET(fd, set) FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT) +#define DDSRT_FD_CLR(fd, set) FreeRTOS_FD_CLR(fd, set, eSELECT_ALL) +*/ + +static inline int32_t DDSRT_FD_ISSET(ddsrt_socket_t fd, ddsrt_fd_set_t set) +{ + return (int32_t)FreeRTOS_FD_ISSET(fd, set); +} + +/* for FD_SET only be used in CDDS for rdset */ +static inline void DDSRT_FD_SET(ddsrt_socket_t fd, ddsrt_fd_set_t set) +{ + FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT); +} + +static inline void DDSRT_FD_CLR(ddsrt_socket_t fd, ddsrt_fd_set_t set) +{ + FreeRTOS_FD_CLR(fd, set, eSELECT_ALL); +} + +#ifndef sa_family_t + typedef uint8_t sa_family_t; +#endif + + struct sockaddr_storage + { + uint8_t s2_len; + sa_family_t ss_family; + char s2_data1[2]; + uint32_t s2_data2[3]; + }; + +#if 1 + /* for posix compatible sa_family reference inside DDS + * we declare sockaddr a new struct but same W/ freertos_sockaddr + */ + struct sockaddr + { + uint8_t sa_len; + sa_family_t sa_family; + uint16_t sin_port; + uint32_t sin_addr; + }; +#else +#define sockaddr freertos_sockaddr +#endif + +#define sockaddr_in freertos_sockaddr +typedef uint32_t in_addr_t; /* base type for internet address */ + +/* + * Options and types related to multicast membership + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 + typedef struct ip_mreq + { + in_addr_t imr_multiaddr; /* IP multicast address of group */ + in_addr_t imr_interface; /* local IP address of interface */ + } ip_mreq; + // end multicast + +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +/** 255.255.255.255 */ +#define INADDR_NONE ((uint32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define INADDR_LOOPBACK ((uint32_t)0x7f000000UL) +/** 0.0.0.0 */ +#define INADDR_ANY ((uint32_t)0x00000000UL) +/** 255.255.255.255 */ +#define INADDR_BROADCAST ((uint32_t)0xffffffffUL) + +#define AF_INET FREERTOS_AF_INET +#define AF_INET6 FREERTOS_AF_INET6 + +#define IPPROTO_IP 0 +#define IPPROTO_ICMP ipPROTOCOL_ICMP + +#define SOCK_DGRAM FREERTOS_SOCK_DGRAM +#define IPPROTO_UDP FREERTOS_IPPROTO_UDP + +#define SOCK_STREAM FREERTOS_SOCK_STREAM +#define IPPROTO_TCP FREERTOS_IPPROTO_TCP + +#define SOL_SOCKET IPPROTO_IP /* set socket level, always 0 for RTOS */ + +#define SO_REUSEADDR FREERTOS_SO_REUSE_LISTEN_SOCKET +#define SO_RCVTIMEO FREERTOS_SO_RCVTIMEO +#define SO_SNDTIMEO FREERTOS_SO_SNDTIMEO +#define SO_SNDBUF FREERTOS_SO_SNDBUF +#define SO_RCVBUF FREERTOS_SO_RCVBUF + +#define SO_OOB FREERTOS_MSG_OOB +#define SO_PEEK FREERTOS_MSG_PEEK +#define SO_DONTROUTE FREERTOS_MSG_DONTROUTE +#define SO_DONTWAIT FREERTOS_MSG_DONTWAIT + +/* + FreeRTOS_accept() has an optional timeout. The timeout defaults + to ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME, and is modified + using the FREERTOS_SO_RCVTIMEO parameter in a call to FreeRTOS_setsockopt() + + If a timeout occurs before a connection from a remote socket + is accepted then NULL is returned. +*/ +#define ACCEPT_TIMEOUT (NULL) // accpet timeout +#define INVALID_SOCKET (FREERTOS_INVALID_SOCKET) + +/* The following constants should be used for the second parameter of + `shutdown'. */ +#define SHUT_RD FREERTOS_SHUT_RD +#define SHUT_WR FREERTOS_SHUT_WR +#define SHUT_RDWR FREERTOS_SHUT_RDWR + + +#define DDSRT_INVALID_SOCKET (INVALID_SOCKET) +#define PRIdSOCK PRIxPTR + +// #define errno FreeRTOS_errno +#define DDSRT_RET_OK (0) + +#ifndef FD_SETSIZE +#define FD_SETSIZE 8 +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h index e48cc0c2..2c232415 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h @@ -31,6 +31,13 @@ extern "C" { #endif typedef int ddsrt_socket_t; + +#ifdef DDSRT_WITH_FREERTOSTCP +typedef fd_set* ddsrt_fd_set_t; /* compatible with FreeRTOS +TCP */ +#define SELECT_TIMEOUT_MS DDS_INFINITY +#endif + + #define DDSRT_INVALID_SOCKET (-1) #define PRIdSOCK "d" diff --git a/src/ddsrt/include/dds/ddsrt/threads.h b/src/ddsrt/include/dds/ddsrt/threads.h index 6341bf7a..46ac58fb 100644 --- a/src/ddsrt/include/dds/ddsrt/threads.h +++ b/src/ddsrt/include/dds/ddsrt/threads.h @@ -49,7 +49,13 @@ extern "C" { supports Thread-local storage since version 2.0. */ /* VxWorks 7 supports __thread for both GCC and DIAB, older versions may support it as well, but that is not verified. */ + +#ifdef DDSRT_WITH_FREERTOSTCP +#define ddsrt_thread_local +#else #define ddsrt_thread_local __thread +#endif + #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) #define ddsrt_thread_local __thread #else @@ -73,6 +79,32 @@ typedef struct { uint32_t stackSize; } ddsrt_threadattr_t; + +#ifdef DDSRT_WITH_FREERTOS +#if configNUM_THREAD_LOCAL_STORAGE_POINTERS <= 0 +#error " Error, FreeRTOS THREAD_LOCAL_STORAGE support NOT enabled!" +#endif + +/* +add configNUM_THREAD_LOCAL_STORAGE_POINTERS for DDS usage + 22 taskguard and FATfs reserved 0~3 +*/ +#define DDS_TLS_IDX_LOGBUFF 4 +#define DDS_TLS_IDX_FREE 5 +#define DDS_TLS_IDX_STATE 6 +#define DDS_TLS_IDX_CTX 7 + +#define ddsrt_thread_tls_set(d, idx, s) \ + vTaskSetThreadLocalStoragePointer(NULL, idx, (void*)s) + +#define ddsrt_thread_tls_get(idx, s) \ + pvTaskGetThreadLocalStoragePointer(NULL, idx) +#else +#error +#define ddsrt_thread_tls_set(d, idx, s) (d) = (s) +#define ddsrt_thread_tls_get(idx, s) (s) +#endif + /** * @brief Initialize thread attributes to platform defaults. */ diff --git a/src/ddsrt/src/cdtors.c b/src/ddsrt/src/cdtors.c index 5ceca0a8..ad49ab2e 100644 --- a/src/ddsrt/src/cdtors.c +++ b/src/ddsrt/src/cdtors.c @@ -165,6 +165,19 @@ DDSRT_WARNING_CLANG_ON(missing-prototypes) #pragma data_seg() #endif #else /* _WIN32 */ + +#ifdef DDSRT_WITH_FREERTOSTCP +void ddsrt_ctor(void) +{ + ddsrt_init(); +} + +void ddsrt_dtor(void) +{ + ddsrt_fini(); +} + +#else void __attribute__((constructor)) ddsrt_ctor(void); void __attribute__((destructor)) ddsrt_dtor(void); @@ -177,5 +190,8 @@ void __attribute__((destructor)) ddsrt_dtor(void) { ddsrt_fini(); } + +#endif + #endif /* _WIN32 */ diff --git a/src/ddsrt/src/heap/freertos/heap.c b/src/ddsrt/src/heap/freertos/heap.c index ffb3d0fb..89d448bc 100644 --- a/src/ddsrt/src/heap/freertos/heap.c +++ b/src/ddsrt/src/heap/freertos/heap.c @@ -10,6 +10,7 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ #include +#include #if defined(configSUPPORT_DYNAMIC_ALLOCATION) && \ (configSUPPORT_DYNAMIC_ALLOCATION == 0) diff --git a/src/ddsrt/src/ifaddrs.c b/src/ddsrt/src/ifaddrs.c index d50a2e40..8114780d 100644 --- a/src/ddsrt/src/ifaddrs.c +++ b/src/ddsrt/src/ifaddrs.c @@ -19,7 +19,9 @@ ddsrt_freeifaddrs(ddsrt_ifaddrs_t *ifa) while (ifa != NULL) { next = ifa->next; + #ifndef DDSRT_WITH_FREERTOSTCP ddsrt_free(ifa->name); + #endif ddsrt_free(ifa->addr); ddsrt_free(ifa->netmask); ddsrt_free(ifa->broadaddr); diff --git a/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c new file mode 100755 index 00000000..52c17792 --- /dev/null +++ b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c @@ -0,0 +1,110 @@ + +#include +#include + +#include "dds/ddsrt/log.h" +#include "dds/ddsrt/misc.h" +#include "sockets_priv.h" + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/io.h" +#include "dds/ddsrt/ifaddrs.h" +#include "dds/ddsrt/retcode.h" +#include "dds/ddsrt/string.h" + +extern const int *const os_supp_afs; + + +static dds_return_t copyaddr(ddsrt_ifaddrs_t **ifap) +{ + dds_return_t rc = DDS_RETCODE_OK; + ddsrt_ifaddrs_t *ifa; + struct sockaddr sa = {0U}; + + assert(ifap != NULL); + + /* note: local IP shoule be got after STACK up! */ + u32 lip, netmask, bcip; + bcip = ipBROADCAST_IP_ADDRESS; + FreeRTOS_GetAddressConfiguration(&lip, &netmask, NULL, NULL); + + ifa = ddsrt_calloc(1, sizeof(*ifa)); + if(ifa == NULL) + { + rc = DDS_RETCODE_OUT_OF_RESOURCES; + goto __exit; + } + + ifa->addr = ddsrt_calloc(1, sizeof(struct sockaddr)); + ifa->netmask = ddsrt_calloc(1, sizeof(struct sockaddr)); + ifa->broadaddr = ddsrt_calloc(1, sizeof(struct sockaddr)); + if ((ifa->addr == NULL) + || (ifa->netmask == NULL) + || (ifa->broadaddr == NULL)) + { + rc = DDS_RETCODE_OUT_OF_RESOURCES; + goto __exit; + } + + sa.sa_len = sizeof(struct sockaddr); + sa.sa_family = AF_INET; + sa.sin_addr = (lip); /* storage IP, no need. FreeRTOS_htonl */ + memcpy((void*)ifa->addr, &sa, sizeof(struct sockaddr)); + + sa.sin_addr = (netmask); + memcpy((void*)ifa->netmask, &sa, sizeof(struct sockaddr)); + + sa.sin_addr = (bcip); + memcpy((void*)ifa->broadaddr, &sa, sizeof(struct sockaddr)); + + ifa->next = NULL; + ifa->type = DDSRT_IFTYPE_WIRED; + ifa->name = "eqos0"; + ifa->index = 0; + ifa->flags = IFF_UP | IFF_BROADCAST; // | IFF_MULTICAST; + +__exit: + if (rc == DDS_RETCODE_OK) + { + *ifap = ifa; + } + else + { + ddsrt_freeifaddrs(ifa); + *ifap = NULL; + } + + return rc; +} + +dds_return_t ddsrt_getifaddrs(ddsrt_ifaddrs_t **ifap, const int *afs) +{ + dds_return_t rc = DDS_RETCODE_OK; + int use_ip4 = 0; + int use_ip6 = 0; + + assert(ifap != NULL); + + if (afs == NULL) + { + afs = os_supp_afs; + } + + for (int i = 0; afs[i] != DDSRT_AF_TERM; i++) + { + if (afs[i] == AF_INET) + { + use_ip4 = 1; + } +#ifdef DDSRT_HAVE_IPV6 + else if (afs[i] == AF_INET6) + { + use_ip6 = 1; + } +#endif + } + + rc = copyaddr(ifap); + + return rc; +} diff --git a/src/ddsrt/src/log.c b/src/ddsrt/src/log.c index a291c0ca..33d3f29e 100644 --- a/src/ddsrt/src/log.c +++ b/src/ddsrt/src/log.c @@ -38,7 +38,9 @@ typedef struct { FILE *out; } log_sink_t; +#ifndef DDSRT_WITH_FREERTOS static ddsrt_thread_local log_buffer_t log_buffer; +#endif static ddsrt_once_t lock_inited = DDSRT_ONCE_INIT; static ddsrt_rwlock_t lock; @@ -50,13 +52,82 @@ struct ddsrt_log_cfg_impl { DDSRT_STATIC_ASSERT (sizeof (struct ddsrt_log_cfg_impl) <= sizeof (struct ddsrt_log_cfg)); +static const uint8_t * ddslstr[] = { + "DDS_LC_FATAL", + "DDS_LC_ERROR", + "DDS_LC_WARNING", + "DDS_LC_INFO", + "DDS_LC_CONFIG", + "DDS_LC_DISCOVERY", + "DDS_LC_DATA", + "DDS_LC_TRACE", + "DDS_LC_RADMIN", + "DDS_LC_TIMING", + "DDS_LC_TRAFFIC", + "DDS_LC_TOPIC", + "DDS_LC_TCP", + "DDS_LC_PLIST", + "DDS_LC_WHC", + "DDS_LC_THROTTLE", + "DDS_LC_RHC", + "DDS_LC_CONTENT", + "DDS_LC_SHM", + }; + static void default_sink (void *ptr, const dds_log_data_t *data) { + #ifdef DDSRT_WITH_FREERTOSTCP + + (void)ptr; + uint32_t lv; + + uint32_t i; + for (i = 0U; i < sizeof(int) * 8U; i++) + { + if (data->priority <= (1U << i)) + { break; } + } + + switch (data->priority) + { + case DDS_LC_FATAL: + case DDS_LC_ERROR: + lv = IPLOG_LEVEL_ERROR; + pr_error("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + case DDS_LC_WARNING: + lv = IPLOG_LEVEL_WARN; + pr_warn("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + case DDS_LC_CONFIG: + case DDS_LC_INFO: + lv = IPLOG_LEVEL_INFO; + pr_info("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + case DDS_LC_TRACE: + lv = IPLOG_LEVEL_DEBUG; + pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + + case DDS_LC_DISCOVERY: + lv = IPLOG_LEVEL_DEBUG; + pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + + default: + lv = IPLOG_LEVEL_DEBUG; + pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + } + //net_log_print(lv, "[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + + #else if (ptr) { (void) fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr); fflush ((FILE *) ptr); } + #endif } #define LOG (0) @@ -64,7 +135,14 @@ static void default_sink (void *ptr, const dds_log_data_t *data) static struct ddsrt_log_cfg_impl logconfig = { .c = { + #ifdef DDSRT_WITH_FREERTOSTCP + .mask = DDS_LC_ALL + | DDS_LC_DISCOVERY | DDS_LC_TOPIC + | DDS_LC_CONFIG | DDS_LC_INFO | DDS_LC_WARNING + | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL, + #else .mask = DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL, + #endif .tracemask = 0, .domid = UINT32_MAX }, @@ -172,8 +250,19 @@ static size_t print_header (char *str, uint32_t id) { int cnt, off; char *tid, buf[MAX_TID_LEN+1] = { 0 }; + #ifdef DDSRT_WITH_FREERTOSTCP + /* + * for RTOS, printf might not support all format output, + * so add explict len other that this STDIO tricks + * printf("%.*s", 10, str) - output str with cutoff or prefix padding to 10 chars. + */ + static const char fmt_no_id[] = "%06u.%06d [] %.10s:"; + static const char fmt_with_id[] = "%06u.%06d [%"PRIu32"] %.10s:"; + // snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, tid); + #else static const char fmt_no_id[] = "%10u.%06d [] %*.*s:"; static const char fmt_with_id[] = "%10u.%06d [%"PRIu32"] %*.*s:"; + #endif dds_time_t time; unsigned sec; int usec; @@ -187,18 +276,44 @@ static size_t print_header (char *str, uint32_t id) if (id == UINT32_MAX) { off = MAX_ID_LEN; + #ifdef DDSRT_WITH_FREERTOSTCP + /* fix bug, HDR might overwrite log buffer set before. + HDR_LEN - off + //snprintf (str + off, HDR_LEN, "%10u.%06d [] %*.*s:", sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid) + */ + cnt = snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, + tid); + #else cnt = snprintf (str + off, HDR_LEN, fmt_no_id, sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid); + #endif } else { /* low domain ids tend to be most used from what I have seen */ off = 9; if (id >= 10) - for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); + { for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); } + + #ifdef DDSRT_WITH_FREERTOSTCP + cnt = snprintf (str + off, HDR_LEN - off, fmt_with_id, sec, usec, id, tid); + #else cnt = snprintf (str + off, HDR_LEN, fmt_with_id, sec, usec, id, MAX_TID_LEN, MAX_TID_LEN, tid); + #endif } +#ifdef DDSRT_WITH_FREERTOSTCP + /* fix CycloneDDS bug + * for RTOS printf might not support all STDIO format. "%.*s" + */ + assert (off + cnt < HDR_LEN); + for (int i = off + cnt; i < HDR_LEN; i++) + { + str[i] = ' '; /* Replace snprintf null byte by space. */ + } +#else assert (off + cnt == (HDR_LEN - 1)); str[off + cnt] = ' '; /* Replace snprintf null byte by space. */ +#endif + return (size_t) (cnt + 1); } @@ -209,6 +324,10 @@ static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t log_buffer_t *lb; dds_log_data_t data; + #ifdef DDSRT_WITH_FREERTOS + log_buffer_t log_buffer = {0}; + #endif + /* id can be used to override the id in logconfig, so that the global logging configuration can be used for reporting errors while inlcuding a domain id. This simply verifies that the id override is only ever diff --git a/src/ddsrt/src/process/freertos/process.c b/src/ddsrt/src/process/freertos/process.c index b2998885..360d499d 100644 --- a/src/ddsrt/src/process/freertos/process.c +++ b/src/ddsrt/src/process/freertos/process.c @@ -20,3 +20,8 @@ ddsrt_getpid(void) return xTaskGetCurrentTaskHandle(); } +char * +ddsrt_getprocessname(void) +{ + return pcTaskGetName(xTaskGetCurrentTaskHandle()); +} diff --git a/src/ddsrt/src/sockets.c b/src/ddsrt/src/sockets.c index 364be9a8..08bfd800 100644 --- a/src/ddsrt/src/sockets.c +++ b/src/ddsrt/src/sockets.c @@ -19,6 +19,9 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/log.h" +#ifdef DDSRT_WITH_FREERTOSTCP +# warning " *** FreeRTOS-Plus-TCP debug include tree " +#else #if !LWIP_SOCKET # if !defined(_WIN32) # include @@ -29,6 +32,7 @@ # endif /* __linux */ # endif /* _WIN32 */ #endif /* LWIP_SOCKET */ +#endif /* FreeRTOSTCP */ #if defined __APPLE__ #include @@ -119,7 +123,11 @@ ddsrt_sockaddr_isunspecified(const struct sockaddr *__restrict sa) return IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*)sa)->sin6_addr); #endif case AF_INET: - return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0); + #ifdef DDSRT_WITH_FREERTOSTCP + return (((struct sockaddr_in *)sa)->sin_addr == 0); + #else + return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0); + #endif } return false; @@ -137,8 +145,12 @@ ddsrt_sockaddr_isloopback(const struct sockaddr *__restrict sa) &((const struct sockaddr_in6 *)sa)->sin6_addr); #endif /* DDSRT_HAVE_IPV6 */ case AF_INET: + #ifdef DDSRT_WITH_FREERTOSTCP + return (((const struct sockaddr_in *)sa)->sin_addr == htonl(INADDR_LOOPBACK)); + #else return (((const struct sockaddr_in *)sa)->sin_addr.s_addr == htonl(INADDR_LOOPBACK)); + #endif } return false; @@ -160,11 +172,19 @@ ddsrt_sockaddr_insamesubnet( switch (sa1->sa_family) { case AF_INET: { + #ifdef DDSRT_WITH_FREERTOSTCP + eq = ((((struct sockaddr_in *)sa1)->sin_addr & + ((struct sockaddr_in *)mask)->sin_addr) + == + (((struct sockaddr_in *)sa2)->sin_addr & + ((struct sockaddr_in *)mask)->sin_addr)); + #else eq = ((((struct sockaddr_in *)sa1)->sin_addr.s_addr & ((struct sockaddr_in *)mask)->sin_addr.s_addr) == (((struct sockaddr_in *)sa2)->sin_addr.s_addr & ((struct sockaddr_in *)mask)->sin_addr.s_addr)); + #endif } break; #if DDSRT_HAVE_IPV6 case AF_INET6: { @@ -196,14 +216,24 @@ ddsrt_sockaddrfromstr(int af, const char *str, void *sa) switch (af) { case AF_INET: { + #ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t buf; + #else struct in_addr buf; + #endif #if DDSRT_HAVE_INET_PTON if (inet_pton(af, str, &buf) != 1) { return DDS_RETCODE_BAD_PARAMETER; } #else + #ifdef DDSRT_WITH_FREERTOSTCP + buf = inet_addr (str); + if (buf == (in_addr_t)(-1)) + #else buf.s_addr = inet_addr (str); - if (buf.s_addr == (in_addr_t)-1) { + if (buf.s_addr == (in_addr_t)(-1)) + #endif + { return DDS_RETCODE_BAD_PARAMETER; } #endif @@ -247,7 +277,11 @@ DDSRT_WARNING_GNUC_OFF(sign-conversion) AF_INET, &((struct sockaddr_in *)sa)->sin_addr, buf, (uint32_t)size); #else { + #ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr); + #else in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); + #endif snprintf(buf,size,"%u.%u.%u.%u",(x>>24),(x>>16)&0xff,(x>>8)&0xff,x&0xff); ptr = buf; } diff --git a/src/ddsrt/src/threads/freertos/threads.c b/src/ddsrt/src/threads/freertos/threads.c index 206d7d62..9f3be999 100644 --- a/src/ddsrt/src/threads/freertos/threads.c +++ b/src/ddsrt/src/threads/freertos/threads.c @@ -183,7 +183,11 @@ static dds_return_t thread_context_acquire(thread_context_t **ctxptr) { dds_return_t rc = DDS_RETCODE_OK; + #ifdef DDSRT_WITH_FREERTOSTCP + thread_context_t *ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context); + #else thread_context_t *ctx = thread_context; + #endif if (ctx == NULL) { /* Dynamically initialize global thread registry (exactly once). */ @@ -199,7 +203,11 @@ thread_context_acquire(thread_context_t **ctxptr) ctx->task = xTaskGetCurrentTaskHandle(); } ddsrt_mutex_unlock(&thread_registry.mutex); + #ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx); + #else thread_context = ctx; + #endif } else { assert(ctx->func != NULL); assert(ctx->stat == THREAD_RUNNING); @@ -326,7 +334,11 @@ thread_start_routine(void *arg) thread because a reference to the thread's context is stored and synchronization is considerably easier if it's handled there. */ +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx); +#else thread_context = ctx; +#endif ret = ctx->func(ctx->arg); thread_fini(ctx, ret); /* DO NOT DEREFERENCE THREAD CONTEXT ANYMORE! */ @@ -427,6 +439,10 @@ void ddsrt_thread_init(uint32_t reason) { (void)reason; +#ifdef DDSRT_WITH_FREERTOSTCP + /* init TLS var */ + ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, NULL); +#endif if (thread_context_require() != DDS_RETCODE_OK) { assert(0); } @@ -440,7 +456,12 @@ ddsrt_thread_fini(uint32_t reason) (void)reason; /* NO-OP if no context exists since thread-local storage and cleanup handler references are both stored in the thread context. */ + #ifdef DDSRT_WITH_FREERTOSTCP + ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context); + if ( ctx != NULL) { + #else if ((ctx = thread_context) != NULL) { + #endif assert(ctx->func != &non_local_thread); thread_fini(ctx, 0); } diff --git a/src/ddsrt/src/time.c b/src/ddsrt/src/time.c index 9551f0dd..64945fcc 100644 --- a/src/ddsrt/src/time.c +++ b/src/ddsrt/src/time.c @@ -38,6 +38,8 @@ void dds_sleepfor(dds_duration_t n) } #endif +#ifndef DDSRT_WITH_FREERTOS +#warning " ctime in glib, ignore it for FreeRTOS " size_t ddsrt_ctime(dds_time_t n, char *str, size_t size) { @@ -73,6 +75,7 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size) return ddsrt_strlcpy(str, buf, size); } +#endif static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t) { diff --git a/src/ddsrt/src/time/freertos/time.c b/src/ddsrt/src/time/freertos/time.c index 01c367bb..e1e5d5a9 100644 --- a/src/ddsrt/src/time/freertos/time.c +++ b/src/ddsrt/src/time/freertos/time.c @@ -20,6 +20,9 @@ DDS_EXPORT extern inline TickType_t ddsrt_duration_to_ticks_ceil(dds_duration_t dds_time_t dds_time(void) { +#ifdef DDSRT_WITH_FREERTOSTCP + return get_timer_us(0U) * 1000U; +#else struct timespec ts; #if __STDC_VERSION__ >= 201112L @@ -29,6 +32,7 @@ dds_time_t dds_time(void) #endif return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec; +#endif } #define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ) From 9a1014e154b0602d40e75cafef59fdcc8902d000 Mon Sep 17 00:00:00 2001 From: Zhou Shengyong Date: Tue, 11 Apr 2023 12:00:29 +0800 Subject: [PATCH 24/27] Revert "[FreeRTOS-Plus-TCP] to support cycloneDDS over FreeRTOS-Plus-TCP IP stack" This reverts commit c3d40357f168f85e48fe1f1ffd912b65fb2cf960. --- .../ddsc/include/dds/ddsc/dds_public_impl.h | 3 - src/core/ddsc/include/dds/export.h | 50 -- src/core/ddsc/src/dds_builtin.c | 4 - src/core/ddsc/src/dds_domain.c | 25 +- src/core/ddsc/src/dds_init.c | 8 - src/core/ddsc/src/dds_participant.c | 30 - src/core/ddsi/defconfig.c | 9 - .../ddsi/include/dds/ddsi/ddsi_cfgelems.h | 125 +---- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_locator.h | 2 +- .../include/dds/ddsi/ddsi_serdata_default.h | 18 - src/core/ddsi/include/dds/ddsi/ddsi_udp.h | 4 - src/core/ddsi/include/dds/ddsi/q_log.h | 3 - src/core/ddsi/include/dds/ddsi/q_thread.h | 4 - src/core/ddsi/src/ddsi_cdrstream.c | 14 +- src/core/ddsi/src/ddsi_ipaddr.c | 12 - src/core/ddsi/src/ddsi_tcp.c | 18 +- src/core/ddsi/src/ddsi_tran.c | 2 - src/core/ddsi/src/ddsi_udp.c | 102 +--- src/core/ddsi/src/ddsi_wraddrset.c | 4 - src/core/ddsi/src/q_addrset.c | 2 - src/core/ddsi/src/q_ddsi_discovery.c | 16 - src/core/ddsi/src/q_entity.c | 8 +- src/core/ddsi/src/q_freelist.c | 32 -- src/core/ddsi/src/q_gc.c | 4 - src/core/ddsi/src/q_init.c | 54 +- src/core/ddsi/src/q_pcap.c | 10 - src/core/ddsi/src/q_receive.c | 67 +-- src/core/ddsi/src/q_sockwaitset_s.c | 522 ------------------ src/core/ddsi/src/q_thread.c | 36 +- src/core/ddsi/src/q_transmit.c | 14 - src/core/ddsi/src/q_xevent.c | 64 +-- src/core/ddsi/src/q_xmsg.c | 11 +- src/ddsrt/include/dds/config.h.in | 11 - src/ddsrt/include/dds/ddsrt/iovec.h | 11 - src/ddsrt/include/dds/ddsrt/log.h | 31 +- src/ddsrt/include/dds/ddsrt/process.h | 12 - src/ddsrt/include/dds/ddsrt/sockets.h | 18 +- .../dds/ddsrt/sockets/freertos_plus_tcp.h | 245 -------- src/ddsrt/include/dds/ddsrt/sockets/posix.h | 7 - src/ddsrt/include/dds/ddsrt/threads.h | 32 -- src/ddsrt/src/cdtors.c | 16 - src/ddsrt/src/heap/freertos/heap.c | 1 - src/ddsrt/src/ifaddrs.c | 2 - .../freertos_plus_tcp/ifaddrs_plus_tcp.c | 110 ---- src/ddsrt/src/log.c | 121 +--- src/ddsrt/src/process/freertos/process.c | 5 - src/ddsrt/src/sockets.c | 38 +- src/ddsrt/src/threads/freertos/threads.c | 21 - src/ddsrt/src/time.c | 3 - src/ddsrt/src/time/freertos/time.c | 4 - 51 files changed, 61 insertions(+), 1908 deletions(-) delete mode 100755 src/core/ddsc/include/dds/export.h delete mode 100755 src/core/ddsi/src/q_sockwaitset_s.c delete mode 100755 src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h delete mode 100755 src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c diff --git a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h index 291e5d9c..ea0e7055 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h +++ b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h @@ -26,9 +26,6 @@ #include #include "dds/export.h" #include "dds/features.h" -#ifdef DDSRT_WITH_FREERTOSTCP -#include "dds/ddsrt/align.h" -#endif #include "dds/ddsc/dds_public_alloc.h" #include "dds/ddsc/dds_opcodes.h" diff --git a/src/core/ddsc/include/dds/export.h b/src/core/ddsc/include/dds/export.h deleted file mode 100755 index 30103d12..00000000 --- a/src/core/ddsc/include/dds/export.h +++ /dev/null @@ -1,50 +0,0 @@ - -#ifndef DDS_EXPORT_H -#define DDS_EXPORT_H - -#ifdef DDS_STATIC_DEFINE -# define DDS_EXPORT -# define DDS_NO_EXPORT -#else -# ifndef DDS_EXPORT -# ifdef ddsc_EXPORTS - /* We are building this library */ -# define DDS_EXPORT -# else - /* We are using this library */ -# define DDS_EXPORT -# endif -# endif - -# ifndef DDS_NO_EXPORT -# define DDS_NO_EXPORT -# endif -#endif - -#ifndef DDS_DEPRECATED -# define DDS_DEPRECATED -#endif - -#ifndef DDS_DEPRECATED_EXPORT -# define DDS_DEPRECATED_EXPORT DDS_EXPORT DDS_DEPRECATED -#endif - -#ifndef DDS_DEPRECATED_NO_EXPORT -# define DDS_DEPRECATED_NO_EXPORT DDS_NO_EXPORT DDS_DEPRECATED -#endif - -#if 0 /* DEFINE_NO_DEPRECATED */ -# ifndef DDS_NO_DEPRECATED -# define DDS_NO_DEPRECATED -# endif -#endif - -#ifndef DDS_INLINE_EXPORT -# if __MINGW32__ && (!defined(__clang__) || !defined(ddsc_EXPORTS)) -# define DDS_INLINE_EXPORT -# else -# define DDS_INLINE_EXPORT DDS_EXPORT -# endif -#endif - -#endif /* DDS_EXPORT_H */ diff --git a/src/core/ddsc/src/dds_builtin.c b/src/core/ddsc/src/dds_builtin.c index 43f96adb..fd2a31da 100644 --- a/src/core/ddsc/src/dds_builtin.c +++ b/src/core/ddsc/src/dds_builtin.c @@ -374,8 +374,6 @@ void dds__builtin_init (struct dds_domain *dom) { dds_qos_t *qos = dds__create_builtin_qos (); - DDS_LOG(DDS_LC_CONFIG, " dds__builtin_init ..."); - dom->btif.arg = dom; dom->btif.builtintopic_get_tkmap_entry = dds__builtin_get_tkmap_entry; dom->btif.builtintopic_is_builtintopic = dds__builtin_is_builtintopic; @@ -417,8 +415,6 @@ void dds__builtin_init (struct dds_domain *dom) dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, dom->builtin_reader_type, qos, builtintopic_whc_new (DSBT_READER, gh)); thread_state_asleep (lookup_thread_state ()); - DDS_LOG(DDS_LC_CONFIG, " builtin_topics writer done"); - dds_delete_qos (qos); /* ddsi_sertype_init initializes the refcount to 1 and dds_sertopic_register_locked increments diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index 81afea50..dfb6b802 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -120,7 +120,6 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i break; } domain->m_id = domain->gv.config.domainId; - DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " domain 0X%08x / 0x%08x config init done \n", domain->m_id, domain_id); if (rtps_config_prep (&domain->gv, domain->cfgst) != 0) { @@ -128,7 +127,6 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_config; } - DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_config_prep done \n"); if (rtps_init (&domain->gv) < 0) { @@ -136,7 +134,6 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_init; } - DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_init done! \n"); #ifdef DDS_HAS_SHM // if DDS_HAS_SHM is enabled the iceoryx runtime was created in rtps_init and is ready @@ -154,7 +151,6 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domain to configured to do so. */ if (domain->gv.config.liveliness_monitoring) { - DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start ... \n"); if (dds_global.threadmon_count++ == 0) { /* FIXME: configure settings */ @@ -173,11 +169,9 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i goto fail_threadmon_start; } } - DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start! \n"); } dds__builtin_init (domain); - DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " dds__builtin_init done! \n"); /* Set additional default participant properties */ @@ -193,21 +187,10 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_start; } - DDS_LOG(DDS_LC_CONFIG, " rtps_start done!"); if (domain->gv.config.liveliness_monitoring) ddsi_threadmon_register_domain (dds_global.threadmon, &domain->gv); dds_entity_init_complete (&domain->m_entity); - - #if 0 // def DDSRT_WITH_FREERTOSTCP - /* CAUTION: NEVER open this slice unless in UT itself. */ - sleep(2U); /* wait thread wrapper */ - DDS_LOG(DDS_LC_CONFIG, " @@@@@@@@@@@@@@@@@@ domain init threads dump"); - /* dump all threads created in domain_init */ - //eth_run_cli("ps"); - sleep(1U); - #endif - return domh; fail_rtps_start: @@ -251,8 +234,6 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o if (dom) { - DDS_LOG (DDS_LC_CONFIG, " find dom %p", dom); - if (!implicit) domh = DDS_RETCODE_PRECONDITION_NOT_MET; else @@ -273,22 +254,18 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o } else { - DDS_LOG (DDS_LC_CONFIG, " create dom ..."); dom = dds_alloc (sizeof (*dom)); if ((domh = dds_domain_init (dom, id, config, implicit)) < 0) - { dds_free (dom); } + dds_free (dom); else { - DDS_LOG (DDS_LC_CONFIG, " dom created, domh = 0x%x ", domh); ddsrt_mutex_lock (&dom->m_entity.m_mutex); ddsrt_avl_insert (&dds_domaintree_def, &dds_global.m_domains, dom); dds_entity_register_child (&dds_global.m_entity, &dom->m_entity); - DDS_LOG (DDS_LC_CONFIG, " register domain to global done "); if (implicit) { dds_entity_add_ref_locked (&dom->m_entity); dds_handle_repin (&dom->m_entity.m_hdllink); - DDS_LOG (DDS_LC_CONFIG, " dom->m_entity.m_hdllink.hdl = 0x%x ", dom->m_entity.m_hdllink.hdl); } domh = dom->m_entity.m_hdllink.hdl; ddsrt_mutex_unlock (&dom->m_entity.m_mutex); diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index 4c9154cc..e4252e02 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -52,10 +52,6 @@ dds_cyclonedds_entity dds_global; #define CDDS_STATE_STARTING 1u #define CDDS_STATE_READY 2u #define CDDS_STATE_STOPPING 3u - -#ifdef DDSRT_WITH_FREERTOSTCP -#define MAX_THREAD_NUM 32 -#endif static ddsrt_atomic_uint32_t dds_state = DDSRT_ATOMIC_UINT32_INIT (CDDS_STATE_ZERO); static void common_cleanup (void) @@ -116,11 +112,7 @@ dds_return_t dds_init (void) ddsrt_mutex_init (&dds_global.m_mutex); ddsrt_cond_init (&dds_global.m_cond); ddsi_iid_init (); - #ifdef DDSRT_WITH_FREERTOSTCP - thread_states_init (MAX_THREAD_NUM); - #else thread_states_init (128); - #endif if (dds_handle_server_init () != DDS_RETCODE_OK) { diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index c9a977ad..9cba6a57 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -91,9 +91,6 @@ const struct dds_entity_deriver dds_entity_deriver_participant = { .refresh_statistics = dds_entity_deriver_dummy_refresh_statistics }; -#ifdef DDSRT_WITH_FREERTOSTCP -char dds_peer[16] = {0}; -#endif dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener) { dds_domain *dom; @@ -102,29 +99,6 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ dds_participant * pp; ddsi_plist_t plist; dds_qos_t *new_qos = NULL; - -#ifdef DDSRT_WITH_FREERTOSTCP - /* Make sure DDS instance is initialized. */ - if ((ret = dds_init ()) < 0) - goto err_dds_init; - - char xml[1024]; - memset(xml, 0, sizeof(xml)); - if (inet_addr(dds_peer) == 0) - { - strncpy(dds_peer, "192.168.11.2", sizeof(dds_peer)); - dds_peer[sizeof(dds_peer) - 1] = '\0'; - } - - snprintf(xml, sizeof(xml) - 1, "\ -\ - \ -\ -", dds_peer); - const char *config = xml; - DDS_WARNING(" participant xml [%s] !", xml); - //DDS_WARNING(" participant peer using [%s] !", dds_peer); -#else const char *config = ""; /* Make sure DDS instance is initialized. */ @@ -132,8 +106,6 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ goto err_dds_init; (void) ddsrt_getenv ("CYCLONEDDS_URI", &config); -#endif - if ((ret = dds_domain_create_internal (&dom, domain, true, config)) < 0) goto err_domain_create; @@ -171,7 +143,6 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ret = DDS_RETCODE_ERROR; goto err_new_participant; } - DDS_INFO(" built-in participant done !"); pp = dds_alloc (sizeof (*pp)); if ((ret = dds_entity_init (&pp->m_entity, &dom->m_entity, DDS_KIND_PARTICIPANT, false, true, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0) @@ -189,7 +160,6 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ddsrt_mutex_unlock (&dom->m_entity.m_mutex); dds_entity_init_complete (&pp->m_entity); - /* drop temporary extra ref to domain, dds_init */ dds_entity_unpin_and_drop_ref (&dom->m_entity); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index 1f76f41d..beae4e51 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -14,11 +14,7 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->externalMaskString = "0.0.0.0"; cfg->allowMulticast = UINT32_C (2147483648); cfg->multicast_ttl = INT32_C (32); - #ifdef DDSRT_WITH_FREERTOSTCP - cfg->transport_selector = INT32_C (DDSI_TRANS_UDP); - #else cfg->transport_selector = INT32_C (1); - #endif cfg->enableMulticastLoopback = INT32_C (1); cfg->max_msg_size = UINT32_C (14720); cfg->max_rexmit_msg_size = UINT32_C (1456); @@ -62,13 +58,8 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->const_hb_intv_min = INT64_C (5000000); cfg->const_hb_intv_sched_min = INT64_C (20000000); cfg->const_hb_intv_sched_max = INT64_C (8000000000); - #ifdef DDSRT_WITH_FREERTOSTCP - cfg->max_queued_rexmit_bytes = UINT32_C (33554432); /* 524288->32M: > 4K framesize */ - cfg->max_queued_rexmit_msgs = UINT32_C (18000); /* 200->20480: > 4K framesize / fragmen_size */ - #else cfg->max_queued_rexmit_bytes = UINT32_C (524288); cfg->max_queued_rexmit_msgs = UINT32_C (200); - #endif cfg->writer_linger_duration = INT64_C (1000000000); cfg->socket_rcvbuf_size.min.isdefault = 1; cfg->socket_rcvbuf_size.max.isdefault = 1; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h index d1e3e867..5b5b3db8 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h @@ -15,10 +15,6 @@ #include "dds/features.h" -#ifdef DDSRT_WITH_FREERTOSTCP -#warning " debug rtos tcp stack including " -#include "dds/ddsrt/sockets/freertos_plus_tcp.h" -#endif static struct cfgelem network_interface_attributes[] = { STRING("autodetermine", NULL, 1, "false", @@ -160,16 +156,7 @@ static struct cfgelem general_cfgelems[] = { "translated to an internal address by replacing the network portion of " "the external address with the corresponding portion of the preferred " "network interface address. This option is IPv4-only.

")), - LIST("AllowMulticast", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP -/* - * he "spdp" leaves multicast enabled for initial discovery only - * https://github.com/ros2/rmw_cyclonedds/issues/251 - */ - "spdp", -#else - "default", -#endif + LIST("AllowMulticast", NULL, 1, "default", MEMBER(allowMulticast), FUNCTIONS(0, uf_allow_multicast, 0, pf_allow_multicast), DESCRIPTION( @@ -225,34 +212,19 @@ static struct cfgelem general_cfgelems[] = { "packets, to bypass the local routing tables. This is generally useful " "only when the routing tables cannot be trusted, which is highly " "unusual.

")), - ENUM("UseIPv6", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - "false", -#else - "default", -#endif + ENUM("UseIPv6", NULL, 1, "default", MEMBER(compat_use_ipv6), FUNCTIONS(0, uf_boolean_default, 0, pf_nop), DESCRIPTION("

Deprecated (use Transport instead)

"), VALUES("false","true","default")), - ENUM("Transport", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - "udp", -#else - "default", -#endif + ENUM("Transport", NULL, 1, "default", MEMBER(transport_selector), FUNCTIONS(0, uf_transport_selector, 0, pf_transport_selector), DESCRIPTION( "

This element allows selecting the transport to be used (udp, udp6, " "tcp, tcp6, raweth)

"), VALUES("default","udp","udp6","tcp","tcp6","raweth")), - BOOL("EnableMulticastLoopback", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - "false", -#else - "true", -#endif + BOOL("EnableMulticastLoopback", NULL, 1, "true", MEMBER(enableMulticastLoopback), FUNCTIONS(0, uf_boolean, 0, pf_boolean), DESCRIPTION( @@ -262,21 +234,7 @@ static struct cfgelem general_cfgelems[] = { "communications, but if a node runs only a single Cyclone DDS service " "and does not host any other DDSI-capable programs, it should be set " "to \"false\" for improved performance.

")), - - STRING("MaxMessageSize", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP -/* ddsi_config.max_msg_size and fragment_size will decide how many fragments in single submsg. - * keep this below MTU if STACK not support IP fragments - */ - #ifdef EQOS_TX_JUMBO_ENABLED - "8972 B", - #else - "1456 B", - #endif - -#else - "14720 B", -#endif + STRING("MaxMessageSize", NULL, 1, "14720 B", MEMBER(max_msg_size), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -288,16 +246,7 @@ static struct cfgelem general_cfgelems[] = { "

On some networks it may be necessary to set this item to keep the " "packetsize below the MTU to prevent IP fragmentation.

"), UNIT("memsize")), - STRING("MaxRexmitMessageSize", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - #ifdef EQOS_TX_JUMBO_ENABLED - "8972 B", - #else - "1464 B", - #endif -#else - "1456 B", -#endif + STRING("MaxRexmitMessageSize", NULL, 1, "1456 B", MEMBER(max_rexmit_msg_size), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -309,17 +258,7 @@ static struct cfgelem general_cfgelems[] = { "

On some networks it may be necessary to set this item to keep the " "packetsize below the MTU to prevent IP fragmentation.

"), UNIT("memsize")), - STRING("FragmentSize", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - #ifdef EQOS_TX_JUMBO_ENABLED - /* ipMAX_UDP_PAYLOAD_LENGTH(8972) > $FragSize + 20(RTPS_HDR) + 12(INFO_TS) + 36(DATA_HDR) + 28(HEART_BEAT) */ - "8864 B", - #else - "1400 B", - #endif -#else - "1344 B", -#endif + STRING("FragmentSize", NULL, 1, "1344 B", MEMBER(fragment_size), FUNCTIONS(0, uf_memsize16, 0, pf_memsize16), DESCRIPTION( @@ -999,15 +938,7 @@ static struct cfgelem internal_watermarks_cfgelems[] = { "expressed in bytes. A suspended writer resumes transmitting when its " "Cyclone DDS WHC shrinks to this size.

"), UNIT("memsize")), - STRING("WhcHigh", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - /* 512K->24M: > 4K RGB888 framesize - * ALSO to be sure seqeunce limitation defined in idl - */ - "24576 kB", -#else - "500 kB", -#endif + STRING("WhcHigh", NULL, 1, "500 kB", MEMBER(whc_highwater_mark), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -1351,16 +1282,7 @@ static struct cfgelem internal_cfgelems[] = { "

This element allows configuring the base interval for sending " "writer heartbeats and the bounds within which it can vary.

"), UNIT("duration_inf")), - - STRING("MaxQueuedRexmitBytes", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - /* 512K->24M: > 4K RGB888 framesize - * ALSO to be sure seqeunce limitation defined in idl - */ - "24576 kB", -#else - "512 kB", -#endif + STRING("MaxQueuedRexmitBytes", NULL, 1, "512 kB", MEMBER(max_queued_rexmit_bytes), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -1370,14 +1292,7 @@ static struct cfgelem internal_cfgelems[] = { "NackDelay * AuxiliaryBandwidthLimit. It must be large enough to " "contain the largest sample that may need to be retransmitted.

"), UNIT("memsize")), - - INT("MaxQueuedRexmitMessages", NULL, 1, -#ifdef DDSRT_WITH_FREERTOSTCP - /* 200->20480: > 4K framesize / fragmen_size */ - "20480", -#else - "200", -#endif + INT("MaxQueuedRexmitMessages", NULL, 1, "200", MEMBER(max_queued_rexmit_msgs), FUNCTIONS(0, uf_uint, 0, pf_uint), DESCRIPTION( @@ -1889,11 +1804,7 @@ static struct cfgelem shmem_cfgelems[] = { #endif static struct cfgelem discovery_peer_cfgattrs[] = { -#ifdef DDSRT_WITH_FREERTOSTCP - STRING("Address", NULL, 1, "192.168.11.3:7400", // Not working, use XML string -#else STRING("Address", NULL, 1, NULL, -#endif MEMBEROF(ddsi_config_peer_listelem, peer), FUNCTIONS(0, uf_ipv4, ff_free, pf_string), DESCRIPTION( @@ -1918,16 +1829,6 @@ static struct cfgelem discovery_peers_group_cfgelems[] = { }; static struct cfgelem discovery_peers_cfgelems[] = { -#ifdef DDSRT_WITH_FREERTOSTCP - GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, // Not working, use XML string - MEMBER(peers), - FUNCTIONS(if_peer, 0, 0, 0), - DESCRIPTION( - "

This element specifies the base port number (refer to the DDSI 2.1 " - "specification, section 9.6.1, constant PB).

" - )), - -#else GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, MEMBER(peers), FUNCTIONS(if_peer, 0, 0, 0), @@ -1944,7 +1845,6 @@ static struct cfgelem discovery_peers_cfgelems[] = { ), MAXIMUM(0)), /* Group element can occur more than once, but 1 is required because of the way its processed (for now) */ -#endif END_MARKER }; @@ -2000,12 +1900,7 @@ static struct cfgelem discovery_cfgelems[] = { "and fixing the participant index has no adverse effects, it is " "recommended that the second be option be used.

" )), -#ifdef DDSRT_WITH_FREERTOSTCP - /* polling port number to dest peer */ - INT("MaxAutoParticipantIndex", NULL, 1, "2", /* 9 */ -#else INT("MaxAutoParticipantIndex", NULL, 1, "9", -#endif MEMBER(maxAutoParticipantIndex), FUNCTIONS(0, uf_natint, 0, pf_int), DESCRIPTION( diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 4036b50a..6862e1cc 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -310,8 +310,8 @@ struct ddsi_config unsigned delivery_queue_maxsamples; - uint16_t fragment_size; // default: 1344 - uint32_t max_msg_size; /* default: 14720 how many fragment in single submsg */ + uint16_t fragment_size; + uint32_t max_msg_size; uint32_t max_rexmit_msg_size; uint32_t init_transmit_extra_pct; uint32_t max_rexmit_burst_size; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h index 584a06da..0d6d2631 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h @@ -23,7 +23,7 @@ struct ddsi_tran_conn; /* address field in locator maintained in network byte order, the rest in host */ typedef struct { - int32_t kind; // NN_LOCATOR_KIND_UDPv4 + int32_t kind; uint32_t port; unsigned char address[16]; } ddsi_locator_t; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h index 3cf62747..b12de943 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h @@ -98,24 +98,6 @@ struct ddsi_serdata_default_unpadded { #define DDSI_SERDATA_DEFAULT_PAD(n) (n) #endif - -#if 0 -/* un-fold to easy to track in SI */ -struct ddsi_serdata_default { - struct ddsi_serdata c; - uint32_t pos; - uint32_t size; - DDSI_SERDATA_DEFAULT_DEBUG_FIELDS - struct ddsi_serdata_default_key key; - struct serdatapool *serpool; - struct ddsi_serdata_default *next; /* in pool->freelist */ - char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))]; - struct CDRHeader hdr; - char data[]; -}; -#endif - - struct ddsi_serdata_default { DDSI_SERDATA_DEFAULT_PREPAD; char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))]; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h index 14ea1252..2d36180e 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h @@ -18,11 +18,7 @@ extern "C" { typedef struct nn_udpv4mcgen_address { /* base IPv4 MC address is ipv4, host bits are bits base .. base+count-1, this machine is bit idx */ -#ifdef DDSRT_WITH_FREERTOSTCP - in_addr_t ipv4; -#else struct in_addr ipv4; -#endif uint8_t base; uint8_t count; uint8_t idx; /* must be last: then sorting will put them consecutively */ diff --git a/src/core/ddsi/include/dds/ddsi/q_log.h b/src/core/ddsi/include/dds/ddsi/q_log.h index cbb9fb03..64d3c0f8 100644 --- a/src/core/ddsi/include/dds/ddsi/q_log.h +++ b/src/core/ddsi/include/dds/ddsi/q_log.h @@ -24,9 +24,6 @@ extern "C" { #define GVTRACE(...) DDS_CTRACE (&gv->logconfig, __VA_ARGS__) #define GVLOG(cat, ...) DDS_CLOG ((cat), &gv->logconfig, __VA_ARGS__) -#ifdef DDSRT_WITH_FREERTOSTCP -#define GVINFO(...) DDS_CLOG (DDS_LC_INFO, &gv->logconfig, __VA_ARGS__) -#endif #define GVWARNING(...) DDS_CLOG (DDS_LC_WARNING, &gv->logconfig, __VA_ARGS__) #define GVERROR(...) DDS_CLOG (DDS_LC_ERROR, &gv->logconfig, __VA_ARGS__) diff --git a/src/core/ddsi/include/dds/ddsi/q_thread.h b/src/core/ddsi/include/dds/ddsi/q_thread.h index fd382ea9..5d84c11d 100644 --- a/src/core/ddsi/include/dds/ddsi/q_thread.h +++ b/src/core/ddsi/include/dds/ddsi/q_thread.h @@ -132,11 +132,7 @@ DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1); DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv); DDS_INLINE_EXPORT inline struct thread_state1 *lookup_thread_state (void) { -#ifdef DDSRT_WITH_FREERTOSTCP - struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); -#else struct thread_state1 *ts1 = tsd_thread_state; -#endif if (ts1) return ts1; else diff --git a/src/core/ddsi/src/ddsi_cdrstream.c b/src/core/ddsi/src/ddsi_cdrstream.c index 5e485c49..084a627b 100644 --- a/src/core/ddsi/src/ddsi_cdrstream.c +++ b/src/core/ddsi/src/ddsi_cdrstream.c @@ -861,12 +861,12 @@ static char *dds_stream_reuse_string_bound (dds_istream_t * __restrict is, char so this check is superfluous, but perhaps rejecting such a sample is the wrong thing to do */ if (!alloc) - { assert (str != NULL); } + assert (str != NULL); else if (str == NULL) - { str = dds_alloc (size); } + str = dds_alloc (size); memcpy (str, src, length > size ? size : length); if (length > size) - { str[size - 1] = '\0'; } + str[size - 1] = '\0'; is->m_index += length; return str; } @@ -3821,11 +3821,7 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd case DDS_OP_VAL_4BY: { const union { int32_t s; uint32_t u; float f; } x = { .u = dds_is_get4 (is) }; if (flags & DDS_OP_FLAG_FP) - #ifdef DDSRT_WITH_FREERTOSTCP - return prtf (buf, bufsize, "%f", x.f); - #else return prtf (buf, bufsize, "%g", x.f); - #endif else if (flags & DDS_OP_FLAG_SGN) return prtf (buf, bufsize, "%"PRId32, x.s); else @@ -3834,11 +3830,7 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd case DDS_OP_VAL_8BY: { const union { int64_t s; uint64_t u; double f; } x = { .u = dds_is_get8 (is) }; if (flags & DDS_OP_FLAG_FP) - #ifdef DDSRT_WITH_FREERTOSTCP - return prtf (buf, bufsize, "%f", x.f); - #else return prtf (buf, bufsize, "%g", x.f); - #endif else if (flags & DDS_OP_FLAG_SGN) return prtf (buf, bufsize, "%"PRId64, x.s); else diff --git a/src/core/ddsi/src/ddsi_ipaddr.c b/src/core/ddsi/src/ddsi_ipaddr.c index eb086360..5d286ff3 100644 --- a/src/core/ddsi/src/ddsi_ipaddr.c +++ b/src/core/ddsi/src/ddsi_ipaddr.c @@ -251,11 +251,7 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_ { const struct sockaddr_in *x = (const struct sockaddr_in *) src; assert (kind == NN_LOCATOR_KIND_UDPv4 || kind == NN_LOCATOR_KIND_TCPv4); - #ifdef DDSRT_WITH_FREERTOSTCP - if (x->sin_addr == htonl (INADDR_ANY)) - #else if (x->sin_addr.s_addr == htonl (INADDR_ANY)) - #endif { dst->kind = NN_LOCATOR_KIND_INVALID; dst->port = NN_LOCATOR_PORT_INVALID; @@ -265,11 +261,7 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_ { dst->port = (x->sin_port == 0) ? NN_LOCATOR_PORT_INVALID : ntohs (x->sin_port); memset (dst->address, 0, 12); - #ifdef DDSRT_WITH_FREERTOSTCP - memcpy (dst->address + 12, &x->sin_addr, 4); - #else memcpy (dst->address + 12, &x->sin_addr.s_addr, 4); - #endif } break; } @@ -318,11 +310,7 @@ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const ddsi_locator_t *s struct sockaddr_in *x = (struct sockaddr_in *) dst; x->sin_family = AF_INET; x->sin_port = (src->port == NN_LOCATOR_PORT_INVALID) ? 0 : htons ((unsigned short) src->port); - #ifdef DDSRT_WITH_FREERTOSTCP - memcpy (&x->sin_addr, src->address + 12, 4); - #else memcpy (&x->sin_addr.s_addr, src->address + 12, 4); - #endif break; } #if DDSRT_HAVE_IPV6 diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index cb8328de..5dd0c4f4 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -188,11 +188,7 @@ static dds_return_t ddsi_tcp_sock_new (struct ddsi_tran_factory_tcp * const fact { case NN_LOCATOR_KIND_TCPv4: socketname.a4.sin_family = AF_INET; - #ifdef DDSRT_WITH_FREERTOSTCP - socketname.a4.sin_addr = htonl (INADDR_ANY); - #else socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); - #endif socketname.a4.sin_port = htons (port); break; #if DDSRT_HAVE_IPV6 @@ -463,13 +459,8 @@ static bool ddsi_tcp_select (struct ddsi_domaingv const * const gv, ddsrt_socket static int32_t addrfam_to_locator_kind (int af) { -#if DDSRT_HAVE_IPV6 assert (af == AF_INET || af == AF_INET6); return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6; -#else - assert (af == AF_INET); - return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_INVALID; -#endif } static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, ddsi_locator_t *srcloc) @@ -1081,13 +1072,8 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener) switch (addr.a.sa_family) { case AF_INET: - #ifdef DDSRT_WITH_FREERTOSTCP - if (addr.a4.sin_addr == htonl (INADDR_ANY)) - { addr.a4.sin_addr = htonl (INADDR_LOOPBACK); } - #else - if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY)) - { addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); } - #endif + if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY)) + addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); break; #if DDSRT_HAVE_IPV6 case AF_INET6: diff --git a/src/core/ddsi/src/ddsi_tran.c b/src/core/ddsi/src/ddsi_tran.c index 6f5411bd..be1ed3d7 100644 --- a/src/core/ddsi/src/ddsi_tran.c +++ b/src/core/ddsi/src/ddsi_tran.c @@ -134,9 +134,7 @@ void ddsi_conn_free (ddsi_tran_conn_t conn) for (uint32_t i = 0; i < conn->m_base.gv->n_recv_threads; i++) { if (!conn->m_base.gv->recv_threads[i].ts) - { assert (!ddsrt_atomic_ld32 (&conn->m_base.gv->rtps_keepgoing)); - } else { switch (conn->m_base.gv->recv_threads[i].arg.mode) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 0bccc7ba..26c59e9e 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -88,19 +88,6 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu msghdr.msg_controllen = 0; #endif -#ifdef DDSRT_WITH_FREERTOSTCP -{ - if (conn->m_base.m_base.m_port == 7410) - { - GVTRACE(" @@@@@@ waitset UDP RX on port %u ... ", conn->m_base.m_base.m_port); - } - if (conn->m_base.m_base.m_port == 7411) - { - GVTRACE(" @@@@@@ uc UDP RX on port %u ... ", conn->m_base.m_base.m_port); - } -} -#endif - do { rc = ddsrt_recvmsg (conn->m_sock, &msghdr, 0, &ret); } while (rc == DDS_RETCODE_INTERRUPTED); @@ -108,9 +95,7 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu if (ret > 0) { if (srcloc) - { - addr_to_loc (conn->m_base.m_factory, srcloc, &src); - } + addr_to_loc (conn->m_base.m_factory, srcloc, &src); if (gv->pcap_fp) { @@ -168,13 +153,6 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato #if defined(__sun) && !defined(_XPG4_2) msg.msg_accrights = NULL; msg.msg_accrightslen = 0; -#elif defined DDSRT_WITH_FREERTOSTCP /* got whole payload sz for trans */ - msg.msg_control = NULL; - msg.msg_controllen = 0U; - for (int ii = 0; ii < niov; ii++) - { - msg.msg_controllen += iov[ii].iov_len; - } #else msg.msg_control = NULL; msg.msg_controllen = 0; @@ -185,7 +163,6 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato DDSRT_UNUSED_ARG (flags); #endif #if MSG_NOSIGNAL && !LWIP_SOCKET -#error sendflags |= MSG_NOSIGNAL; #endif do { @@ -289,13 +266,7 @@ static dds_return_t set_dont_route (struct ddsi_domaingv const * const gv, ddsrt return rc; } -#ifdef DDSRT_WITH_FREERTOSTCP -static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, - ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, - const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size) -#else static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size) -#endif { // if (min, max)= and initbuf= then request= and result= // (def, def) < defmin defmin whatever it is @@ -304,14 +275,9 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd // (M, N=M) anything N error if < M // defmin = 1MB for receive buffer, 0B for send buffer - -#ifdef DDSRT_WITH_FREERTOSTCP - const bool always_set_size = true; -#else const bool always_set_size = // whether to call setsockopt unconditionally ((config->min.isdefault && !config->max.isdefault) || (!config->min.isdefault && !config->max.isdefault && config->max.value >= config->min.value)); -#endif const uint32_t socket_min_buf_size = // error if it ends up below this !config->min.isdefault ? config->min.value : 0; const uint32_t socket_req_buf_size = // size to request @@ -323,13 +289,7 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd socklen_t optlen = (socklen_t) sizeof (actsize); dds_return_t rc; -#ifdef DDSRT_WITH_FREERTOSTCP -#warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." - rc = DDS_RETCODE_OK; - actsize = socket_req_buf_size + 1U; /* stub getsockopt a different value */ -#else rc = ddsrt_getsockopt (sock, SOL_SOCKET, socket_option, &actsize, &optlen); -#endif if (rc == DDS_RETCODE_BAD_PARAMETER) { /* not all stacks support getting/setting RCVBUF */ @@ -344,13 +304,6 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd if (always_set_size || actsize < socket_req_buf_size) { - #ifdef DDSRT_WITH_FREERTOSTCP - rc = ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize)); - - #warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." - actsize = socket_req_buf_size; - - #else (void) ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize)); /* We don't check the return code from setsockopt, because some O/Ss tend @@ -363,15 +316,11 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd } if (actsize >= socket_req_buf_size) - { - GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize); - } + GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize); else if (actsize >= socket_min_buf_size) - { - GVLOG (DDS_LC_CONFIG, + GVLOG (DDS_LC_CONFIG, "failed to increase socket %s buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", name, socket_req_buf_size, actsize); - } else { /* If the configuration states it must be >= X, then error out if the @@ -381,10 +330,9 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd name, socket_min_buf_size, actsize); rc = DDS_RETCODE_NOT_ENOUGH_SPACE; } - #endif } - return (rc < 0) ? rc : ((actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize); + return (rc < 0) ? rc : (actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize; } static dds_return_t set_rcvbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const struct ddsi_config_socket_buf_size *config) @@ -426,7 +374,6 @@ static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * c static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, struct nn_interface const * const intf, ddsrt_socket_t sock) { -#ifndef DDSRT_WITH_FREERTOSTCP #if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET if (gv->config.use_multicast_if_mreqn) { @@ -443,7 +390,6 @@ static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const } #else (void) gv; -#endif #endif return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, intf->loc.address + 12, 4); } @@ -520,11 +466,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ { case NN_LOCATOR_KIND_UDPv4: if (bind_to_any) - #ifdef DDSRT_WITH_FREERTOSTCP - { socketname.a4.sin_addr = htonl (INADDR_ANY); } - #else - { socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); } - #endif + socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); break; #if DDSRT_HAVE_IPV6 case NN_LOCATOR_KIND_UDPv6: @@ -567,15 +509,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ break; } while (!ddsrt_atomic_cas32 (&fact->receive_buf_size, old, (uint32_t) rc)); } - GVLOG (DDS_LC_CONFIG, " set_rcvbuf done\n"); if (set_sndbuf (gv, sock, &gv->config.socket_sndbuf_size) < 0) goto fail_w_socket; - GVLOG (DDS_LC_CONFIG, " set_sndbuf done\n"); - if (gv->config.dontRoute && set_dont_route (gv, sock, ipv6) != DDS_RETCODE_OK) goto fail_w_socket; - GVLOG (DDS_LC_CONFIG, " set_dont_route done\n"); if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK) { @@ -593,7 +531,6 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ (rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc)); goto fail_w_socket; } - GVLOG (DDS_LC_CONFIG, " ddsrt_bind to port %u done \n", get_socket_port (gv, sock)); if (set_mc_xmit_options) { @@ -601,7 +538,6 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ if (rc != DDS_RETCODE_OK) goto fail_w_socket; } - GVLOG (DDS_LC_CONFIG, " set_mc_options_transmit %d done\n", set_mc_xmit_options); #ifdef DDS_HAS_NETWORK_CHANNELS if (qos->m_diffserv != 0 && fact->m_kind == NN_LOCATOR_KIND_UDPv4) @@ -635,11 +571,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ conn->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing; conn->m_base.m_locator_fn = ddsi_udp_conn_locator; -#ifdef DDSRT_WITH_FREERTOSTCP - GVLOG (DDS_LC_CONFIG, "ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port); -#else GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port); -#endif *conn_out = &conn->m_base; return DDS_RETCODE_OK; @@ -673,13 +605,9 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo struct ip_mreq mreq; mreq.imr_multiaddr = mcip.a4.sin_addr; if (interf) - { memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); } + memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); else - #ifdef DDSRT_WITH_FREERTOSTCP - { mreq.imr_interface = htonl (INADDR_ANY); } - #else - { mreq.imr_interface.s_addr = htonl (INADDR_ANY); } - #endif + mreq.imr_interface.s_addr = htonl (INADDR_ANY); rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq)); } return (rc == DDS_RETCODE_OK) ? 0 : -1; @@ -786,25 +714,15 @@ static int ddsi_udp_is_mcaddr (const struct ddsi_tran_factory *tran, const ddsi_ switch (loc->kind) { case NN_LOCATOR_KIND_UDPv4: { -#ifdef DDSRT_WITH_FREERTOSTCP - const in_addr_t *ipv4 = (const in_addr_t *) (loc->address + 12); - DDSRT_WARNING_GNUC_OFF(sign-conversion) - return IN_MULTICAST (ntohl (*ipv4)); -#else const struct in_addr *ipv4 = (const struct in_addr *) (loc->address + 12); DDSRT_WARNING_GNUC_OFF(sign-conversion) return IN_MULTICAST (ntohl (ipv4->s_addr)); -#endif DDSRT_WARNING_GNUC_ON(sign-conversion) } case NN_LOCATOR_KIND_UDPv4MCGEN: { const nn_udpv4mcgen_address_t *mcgen = (const nn_udpv4mcgen_address_t *) loc->address; DDSRT_WARNING_GNUC_OFF(sign-conversion) - #ifdef DDSRT_WITH_FREERTOSTCP - return IN_MULTICAST (ntohl (mcgen->ipv4)); - #else return IN_MULTICAST (ntohl (mcgen->ipv4.s_addr)); - #endif DDSRT_WARNING_GNUC_ON(sign-conversion) } #if DDSRT_HAVE_IPV6 @@ -914,11 +832,7 @@ static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const dds memcpy (&mcgen, loc->address, sizeof (mcgen)); memset (&src, 0, sizeof (src)); src.sin_family = AF_INET; - #ifdef DDSRT_WITH_FREERTOSTCP - memcpy (&src.sin_addr, &mcgen.ipv4, 4); - #else memcpy (&src.sin_addr.s_addr, &mcgen.ipv4, 4); - #endif ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst, sizeof_dst); pos = strlen (dst); assert (pos <= sizeof_dst); @@ -962,11 +876,9 @@ static int ddsi_udp_locator_from_sockaddr (const struct ddsi_tran_factory *tran_ if (tran->m_kind != NN_LOCATOR_KIND_UDPv4) return -1; break; -#if DDSRT_HAVE_IPV6 case AF_INET6: if (tran->m_kind != NN_LOCATOR_KIND_UDPv6) return -1; -#endif break; } ddsi_ipaddr_to_loc (loc, sockaddr, tran->m_kind); diff --git a/src/core/ddsi/src/ddsi_wraddrset.c b/src/core/ddsi/src/ddsi_wraddrset.c index dcca2a15..d3430d38 100644 --- a/src/core/ddsi/src/ddsi_wraddrset.c +++ b/src/core/ddsi/src/ddsi_wraddrset.c @@ -691,11 +691,7 @@ static void wras_add_locator (const struct ddsi_domaingv *gv, struct addrset *ne memcpy (&l1, tmploc.c.address, sizeof (l1)); tmploc.c.kind = NN_LOCATOR_KIND_UDPv4; memset (tmploc.c.address, 0, 12); - #ifdef DDSRT_WITH_FREERTOSTCP - iph = ntohl (l1.ipv4); - #else iph = ntohl (l1.ipv4.s_addr); - #endif for (i = 0; i < nreaders; i++) { cover_info_t ci = cover_get (covered, i, locidx); diff --git a/src/core/ddsi/src/q_addrset.c b/src/core/ddsi/src/q_addrset.c index 5e1095e1..25759c80 100644 --- a/src/core/ddsi/src/q_addrset.c +++ b/src/core/ddsi/src/q_addrset.c @@ -96,8 +96,6 @@ int add_addresses_to_addrset (const struct ddsi_domaingv *gv, struct addrset *as DDSRT_WARNING_MSVC_OFF(4996); char *addrs_copy, *cursor, *a; int retval = -1; - - GVLOG (DDS_LC_CONFIG, " add addrs [%s] @@@@@@@@@@@@", addrs); addrs_copy = ddsrt_strdup (addrs); cursor = addrs_copy; while ((a = ddsrt_strsep (&cursor, ",")) != NULL) diff --git a/src/core/ddsi/src/q_ddsi_discovery.c b/src/core/ddsi/src/q_ddsi_discovery.c index c293de6c..2e60c34b 100644 --- a/src/core/ddsi/src/q_ddsi_discovery.c +++ b/src/core/ddsi/src/q_ddsi_discovery.c @@ -223,20 +223,6 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv external IP address, this locator will be translated into one in the same subnet as our own local ip and selected. */ assert (gv->n_interfaces == 1); // gv->extmask: the hack is only supported if limited to a single interface - #ifdef DDSRT_WITH_FREERTOSTCP - in_addr_t tmp4 = *((in_addr_t *) (loc.address + 12)); - const in_addr_t ownip = *((in_addr_t *) (gv->interfaces[0].loc.address + 12)); - const in_addr_t extip = *((in_addr_t *) (gv->interfaces[0].extloc.address + 12)); - const in_addr_t extmask = *((in_addr_t *) (gv->extmask.address + 12)); - - if ((tmp4 & extmask) == (extip & extmask)) - { - /* translate network part of the IP address from the external - one to the internal one */ - tmp4 = (tmp4 & ~extmask) | (ownip & extmask); - memcpy (loc.address + 12, &tmp4, 4); - } - #else struct in_addr tmp4 = *((struct in_addr *) (loc.address + 12)); const struct in_addr ownip = *((struct in_addr *) (gv->interfaces[0].loc.address + 12)); const struct in_addr extip = *((struct in_addr *) (gv->interfaces[0].extloc.address + 12)); @@ -249,8 +235,6 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv tmp4.s_addr = (tmp4.s_addr & ~extmask.s_addr) | (ownip.s_addr & extmask.s_addr); memcpy (loc.address + 12, &tmp4, 4); } - #endif - } addrset_from_locatorlists_add_one (gv, &loc, as, &intfs, &direct); diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index d934f86c..f04deeca 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -4346,11 +4346,7 @@ static void joinleave_mcast_helper (struct ddsi_domaingv *gv, ddsi_tran_conn_t c memcpy (&l1, l.address, sizeof (l1)); l.kind = NN_LOCATOR_KIND_UDPv4; memset (l.address, 0, 12); - #ifdef DDSRT_WITH_FREERTOSTCP - iph = ntohl (l1.ipv4); - #else iph = ntohl (l1.ipv4.s_addr); - #endif for (uint32_t i = 1; i < ((uint32_t)1 << l1.count); i++) { uint32_t ipn, iph1 = iph; @@ -5991,9 +5987,9 @@ static int proxy_endpoint_common_init (struct entity_common *e, struct proxy_end int ret; if (is_builtin_entityid (guid->entityid, proxypp->vendor)) - { assert ((plist->qos.present & QP_TYPE_NAME) == 0); } + assert ((plist->qos.present & QP_TYPE_NAME) == 0); else - { assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); } + assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); name = (plist->present & PP_ENTITY_NAME) ? plist->entity_name : ""; entity_common_init (e, proxypp->e.gv, guid, name, kind, tcreate, proxypp->vendor, false); diff --git a/src/core/ddsi/src/q_freelist.c b/src/core/ddsi/src/q_freelist.c index 9ce76244..28ed6ea1 100644 --- a/src/core/ddsi/src/q_freelist.c +++ b/src/core/ddsi/src/q_freelist.c @@ -120,11 +120,6 @@ void nn_freelist_init (struct nn_freelist *fl, uint32_t max, size_t linkoff) fl->count = 0; fl->max = (max == UINT32_MAX) ? max-1 : max; fl->linkoff = linkoff; - -#ifdef DDSRT_WITH_FREERTOSTCP - /* init TLS var */ - ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1)); -#endif } static void *get_next (const struct nn_freelist *fl, const void *e) @@ -165,27 +160,6 @@ void nn_freelist_fini (struct nn_freelist *fl, void (*xfree) (void *)) static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0); -#ifdef DDSRT_WITH_FREERTOSTCP -static int get_freelist_inner_idx (void) -{ - int inner_idx = -1; - - inner_idx = ddsrt_thread_tls_get(DDS_TLS_IDX_FREE, freelist_inner_idx); - - if(inner_idx == -1) - { - static const uint64_t unihashconsts[] = { - UINT64_C (16292676669999574021), - UINT64_C (10242350189706880077), - }; - uintptr_t addr; - uint64_t t = (uint64_t) ((uintptr_t) &addr) + ddsrt_atomic_ld32 (&freelist_inner_idx_off); - inner_idx = (int) (((((uint32_t) t + unihashconsts[0]) * ((uint32_t) (t >> 32) + unihashconsts[1]))) >> (64 - NN_FREELIST_NPAR_LG2)); - } - ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, inner_idx); - return inner_idx; -} -#else static int get_freelist_inner_idx (void) { if (freelist_inner_idx == -1) @@ -200,7 +174,6 @@ static int get_freelist_inner_idx (void) } return freelist_inner_idx; } -#endif static int lock_inner (struct nn_freelist *fl) { @@ -212,12 +185,7 @@ static int lock_inner (struct nn_freelist *fl) { ddsrt_atomic_st32(&fl->cc, 0); ddsrt_atomic_inc32(&freelist_inner_idx_off); - - #ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1)); - #else freelist_inner_idx = -1; - #endif } } return k; diff --git a/src/core/ddsi/src/q_gc.c b/src/core/ddsi/src/q_gc.c index 7941ceb3..61819126 100644 --- a/src/core/ddsi/src/q_gc.c +++ b/src/core/ddsi/src/q_gc.c @@ -204,11 +204,7 @@ struct gcreq_queue *gcreq_queue_new (struct ddsi_domaingv *gv) bool gcreq_queue_start (struct gcreq_queue *q) { -#ifdef DDSRT_WITH_FREERTOSTCP - if (create_thread (&q->ts, q->gv, "dds_gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK) -#else if (create_thread (&q->ts, q->gv, "gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK) -#endif return true; else { diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index f7f4725d..0338f7e8 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -130,13 +130,6 @@ static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint3 } ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc); ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc); - - #ifdef DDSRT_WITH_FREERTOSTCP - /* update portid to up */ - *pdisc = gv->disc_conn_uc->m_base.m_port; - *pdata = gv->data_conn_uc->m_base.m_port; - #endif - return MUSRET_SUCCESS; fail_data: @@ -546,7 +539,6 @@ int rtps_config_prep (struct ddsi_domaingv *gv, struct cfgst *cfgst) DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Invalid port mapping: %s\n", message); goto err_config_late_error; } - DDS_ILOG (DDS_LC_INFO, gv->config.domainId, " @@@@@@@@@@@ port mapping: <%s> \n", message); } /* retry_on_reject_duration default is dependent on late_ack_mode and responsiveness timeout, so fix up */ @@ -1030,23 +1022,20 @@ static int setup_and_start_recv_threads (struct ddsi_domaingv *gv) it before it does anything with it. */ if ((gv->recv_threads[i].arg.rbpool = nn_rbufpool_new (&gv->logconfig, gv->config.rbuf_size, gv->config.rmsg_chunk_size)) == NULL) { - GVERROR ("rtps_start: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_init: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name); goto fail; } - GVLOG(DDS_LC_CONFIG, "rtps_start: alloc rbpool %p for recv_thread[%d] '%s' done \n", - gv->recv_threads[i].arg.rbpool, i, gv->recv_threads[i].name); if (gv->recv_threads[i].arg.mode == RTM_MANY) { if ((gv->recv_threads[i].arg.u.many.ws = os_sockWaitsetNew ()) == NULL) { - GVERROR ("rtps_start: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_init: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name); goto fail; } - GVLOG(DDS_LC_CONFIG, "rtps_start: allocate sock waitset for thread %s done \n", gv->recv_threads[i].name); } if (create_thread (&gv->recv_threads[i].ts, gv, gv->recv_threads[i].name, recv_thread, &gv->recv_threads[i].arg) != DDS_RETCODE_OK) { - GVERROR ("rtps_start: failed to start thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_init: failed to start thread %s\n", gv->recv_threads[i].name); goto fail; } } @@ -1350,7 +1339,6 @@ int rtps_init (struct ddsi_domaingv *gv) gv->listener = NULL; gv->debmon = NULL; -#ifndef DDSRT_WITH_FREERTOS /* Print start time for referencing relative times in the remainder of the DDS_LOG. */ { int sec = (int) (gv->tstart.v / 1000000000); @@ -1359,7 +1347,6 @@ int rtps_init (struct ddsi_domaingv *gv) ddsrt_ctime(gv->tstart.v, str, sizeof(str)); GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str); } -#endif /* Allow configuration to set "deaf_mute" in case we want to start out that way */ gv->deaf = gv->config.initial_deaf; @@ -1375,7 +1362,6 @@ int rtps_init (struct ddsi_domaingv *gv) { case DDSI_TRANS_DEFAULT: assert(0); -#ifdef DDSRT_TRANS_UDP case DDSI_TRANS_UDP: case DDSI_TRANS_UDP6: gv->config.publish_uc_locators = 1; @@ -1384,8 +1370,6 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_UDP ? "udp" : "udp6"); break; -#endif -#ifdef DDSRT_TRANS_TCP case DDSI_TRANS_TCP: case DDSI_TRANS_TCP6: gv->config.publish_uc_locators = (gv->config.tcp_port != -1); @@ -1397,8 +1381,6 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_TCP ? "tcp" : "tcp6"); break; -#endif -#ifdef DDSRT_TRANS_RAWETH case DDSI_TRANS_RAWETH: gv->config.publish_uc_locators = 1; gv->config.enable_uc_locators = 0; @@ -1408,8 +1390,6 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, "raweth"); break; -#endif -#ifdef DDSRT_TRANS_NONE case DDSI_TRANS_NONE: gv->config.publish_uc_locators = 0; gv->config.enable_uc_locators = 0; @@ -1419,7 +1399,6 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, "dummy"); break; -#endif } gv->m_factory->m_enable = true; @@ -1444,12 +1423,12 @@ int rtps_init (struct ddsi_domaingv *gv) { if (!gv->interfaces[i].mc_capable) { + GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name); gv->config.allowMulticast = DDSI_AMC_FALSE; /* ensure discovery can work: firstly, that the process will be reachable on a "well-known" port number, and secondly, that the local interface's IP address gets added to the discovery address set */ gv->config.participantIndex = DDSI_PARTICIPANT_INDEX_AUTO; - GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name); } else if (gv->config.allowMulticast & DDSI_AMC_DEFAULT) { @@ -1459,7 +1438,7 @@ int rtps_init (struct ddsi_domaingv *gv) if (gv->interfaces[i].mc_flaky) { gv->config.allowMulticast = DDSI_AMC_SPDP; - GVLOG (DDS_LC_CONFIG, "presumed flaky multicast(0x%08x), use for SPDP only\n", gv->config.allowMulticast); + GVLOG (DDS_LC_CONFIG, "presumed flaky multicast, use for SPDP only\n"); } else { @@ -1468,12 +1447,6 @@ int rtps_init (struct ddsi_domaingv *gv) } } } -#ifdef DDSRT_WITH_FREERTOSTCP - } - else - { - GVWARNING (" (gv->config.allowMulticast) is false! \n"); -#endif } assert ((gv->config.allowMulticast & DDSI_AMC_DEFAULT) == 0); @@ -1600,12 +1573,8 @@ int rtps_init (struct ddsi_domaingv *gv) memcpy (&gv->ppguid_base.prefix.s[2], digest, sizeof (gv->ppguid_base.prefix.s) - 2); gv->ppguid_base.prefix = nn_ntoh_guid_prefix (gv->ppguid_base.prefix); gv->ppguid_base.entityid.u = NN_ENTITYID_PARTICIPANT; - GVLOG(DDS_LC_CONFIG, " GUID prefix: "PGUIDFMT "vs [%08x %08x %08x]", - PGUID (gv->ppguid_base), - gv->ppguid_base.prefix.u[0], gv->ppguid_base.prefix.u[1], gv->ppguid_base.prefix.u[2]); } - ddsrt_mutex_init (&gv->lock); ddsrt_mutex_init (&gv->spdp_lock); gv->spdp_defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples); @@ -1613,8 +1582,6 @@ int rtps_init (struct ddsi_domaingv *gv) gv->m_tkmap = ddsi_tkmap_new (gv); - GVLOG (DDS_LC_CONFIG, "participantIndex %d \n", gv->config.participantIndex); - if (gv->m_factory->m_connless) { if (gv->config.participantIndex >= 0 || gv->config.participantIndex == DDSI_PARTICIPANT_INDEX_NONE) @@ -1633,8 +1600,6 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_unicast_sockets; case MUSRET_ERROR: /* something bad happened; assume make_uc_sockets logged the error */ - GVERROR ("rtps_init: other failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", - gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc); goto err_unicast_sockets; } } @@ -1656,10 +1621,8 @@ int rtps_init (struct ddsi_domaingv *gv) gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc); goto err_unicast_sockets; case MUSRET_PORTS_IN_USE: /* Try next one */ - GVERROR ("Failed to create unicast sockets PORTS_IN_USE \n"); break; case MUSRET_ERROR: - GVERROR ("Failed to create unicast sockets ERROR \n"); /* something bad happened; assume make_uc_sockets logged the error */ goto err_unicast_sockets; } @@ -1669,7 +1632,6 @@ int rtps_init (struct ddsi_domaingv *gv) GVERROR ("Failed to find a free participant index for domain %"PRIu32"\n", gv->config.extDomainId.value); goto err_unicast_sockets; } - GVLOG (DDS_LC_INFO,"find a participant %d index for domain %"PRIu32"\n", ppid, gv->config.extDomainId.value); gv->config.participantIndex = ppid; } else @@ -1678,12 +1640,11 @@ int rtps_init (struct ddsi_domaingv *gv) } GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc); } - GVLOG (DDS_LC_INFO, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); + GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); if (gv->config.pcap_file && *gv->config.pcap_file) { gv->pcap_fp = new_pcap_file (gv, gv->config.pcap_file); - GVLOG (DDS_LC_CONFIG, "rtps_init: pcap_file %s done \n", gv->config.pcap_file); if (gv->pcap_fp) { ddsrt_mutex_init (&gv->pcap_lock); @@ -2071,8 +2032,6 @@ int rtps_start (struct ddsi_domaingv *gv) return -1; } } - -#ifdef DDSRT_TRANS_TCP if (gv->config.monitor_port >= 0) { if ((gv->debmon = new_debug_monitor (gv, gv->config.monitor_port)) == NULL) @@ -2082,7 +2041,6 @@ int rtps_start (struct ddsi_domaingv *gv) return -1; } } -#endif return 0; } diff --git a/src/core/ddsi/src/q_pcap.c b/src/core/ddsi/src/q_pcap.c index bb0115c1..3b843f79 100644 --- a/src/core/ddsi/src/q_pcap.c +++ b/src/core/ddsi/src/q_pcap.c @@ -145,13 +145,8 @@ void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud); u.ipv4_hdr.ttl = 128; - #ifdef DDSRT_WITH_FREERTOSTCP - u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr; - u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr; - #else u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr; u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr.s_addr; - #endif u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x); (void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp); udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port; @@ -183,13 +178,8 @@ void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const str u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud); u.ipv4_hdr.ttl = 255; - #ifdef DDSRT_WITH_FREERTOSTCP - u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr; - u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr; - #else u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr; u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr.s_addr; - #endif u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x); (void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp); udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port; diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index 65cd2e8b..e4898c34 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -3177,7 +3177,7 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d else if (hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) { if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) - GVWARNING ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", + GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor); if (DDSI_SC_PEDANTIC_P (gv->config)) malformed_packet_received (gv, msg, NULL, (size_t) sz, hdr->vendorid); @@ -3197,12 +3197,6 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d if (res != NN_RTPS_MSG_STATE_ERROR) { handle_submsg_sequence (ts1, gv, conn, srcloc, ddsrt_time_wallclock (), ddsrt_time_elapsed (), &hdr->guid_prefix, guidprefix, msg, (size_t) sz, msg + RTPS_MESSAGE_HEADER_SIZE, rmsg, res == NN_RTPS_MSG_STATE_ENCODED); -#ifdef DDSRT_WITH_FREERTOSTCP - } - else - { - GVWARNING(" decode_rtps_messages error! \n"); -#endif } } } @@ -3235,7 +3229,7 @@ static bool do_packet (struct thread_state1 * const ts1, struct ddsi_domaingv *g buff = (unsigned char *) NN_RMSG_PAYLOAD (rmsg); hdr = (Header_t*) buff; - if (conn->m_stream) /* ONLY for TCP conn */ + if (conn->m_stream) { MsgLen_t * ml = (MsgLen_t*) (hdr + 1); @@ -3452,16 +3446,13 @@ uint32_t listen_thread (struct ddsi_tran_listener *listener) static int recv_thread_waitset_add_conn (os_sockWaitset ws, ddsi_tran_conn_t conn) { if (conn == NULL) - { return 0; } + return 0; else { struct ddsi_domaingv *gv = conn->m_base.gv; for (uint32_t i = 0; i < gv->n_recv_threads; i++) - { - /* SKIP add thread "recvUC" / gv->data_conn_uc to waitset! */ if (gv->recv_threads[i].arg.mode == RTM_SINGLE && gv->recv_threads[i].arg.u.single.conn == conn) - { return 0; } - } + return 0; return os_sockWaitsetAdd (ws, conn); } } @@ -3504,12 +3495,6 @@ uint32_t recv_thread (void *vrecv_thread_arg) os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL; ddsrt_mtime_t next_thread_cputime = { 0 }; -#ifdef DDSRT_WITH_FREERTOS - char name[64]; - ddsrt_thread_getname (name, sizeof (name)); - DDS_WARNING("recv_thread: called up for thread[%s] \n", name); -#endif - nn_rbufpool_setowner (rbpool, ddsrt_thread_self ()); if (waitset == NULL) { @@ -3530,36 +3515,17 @@ uint32_t recv_thread (void *vrecv_thread_arg) { int rc; if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_uc)) < 0) - { DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); } - #ifdef DDSRT_WITH_FREERTOSTCP - if (rc > 0) - { DDS_INFO("recv_thread: add disc_conn_uc to waitset ! \n"); } - #endif + DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); num_fixed_uc += (unsigned)rc; - if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_uc)) < 0) DDS_FATAL("recv_thread: failed to add data_conn_uc to waitset\n"); - #ifdef DDSRT_WITH_FREERTOSTCP - if (rc > 0) - { DDS_INFO("recv_thread: add data_conn_uc to waitset ! \n"); } - #endif num_fixed_uc += (unsigned)rc; - num_fixed += num_fixed_uc; if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_mc)) < 0) DDS_FATAL("recv_thread: failed to add disc_conn_mc to waitset\n"); - #ifdef DDSRT_WITH_FREERTOSTCP - if (rc > 0) - { DDS_INFO("recv_thread: add disc_conn_mc to waitset ! \n"); } - #endif num_fixed += (unsigned)rc; - if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_mc)) < 0) DDS_FATAL("recv_thread: failed to add data_conn_mc to waitset\n"); - #ifdef DDSRT_WITH_FREERTOSTCP - if (rc > 0) - { DDS_INFO("recv_thread: add data_conn_mc to waitset ! \n"); } - #endif num_fixed += (unsigned)rc; // OpenDDS doesn't respect the locator lists and insists on sending to the @@ -3569,13 +3535,9 @@ uint32_t recv_thread (void *vrecv_thread_arg) // Iceoryx gets added as a pseudo-interface but there's no socket to wait // for input on if (ddsi_conn_handle (gv->xmit_conns[i]) == DDSRT_INVALID_SOCKET) - { continue; } + continue; if ((rc = recv_thread_waitset_add_conn (waitset, gv->xmit_conns[i])) < 0) - DDS_FATAL("recv_thread: failed to add xmit_conn[%d] to waitset\n", i); - #ifdef DDSRT_WITH_FREERTOSTCP - if (rc > 0) - { DDS_INFO("recv_thread: add xmit_conn[%d] to waitset ! \n", i); } - #endif + DDS_FATAL("recv_thread: failed to add transmit_conn[%d] to waitset\n", i); num_fixed += (unsigned)rc; } } @@ -3602,7 +3564,7 @@ uint32_t recv_thread (void *vrecv_thread_arg) for (uint32_t i = 0; i < lps.nps; i++) { if (lps.ps[i].m_conn) - { os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); } + os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); } } @@ -3613,18 +3575,13 @@ uint32_t recv_thread (void *vrecv_thread_arg) while ((idx = os_sockWaitsetNextEvent (ctx, &conn)) >= 0) { const ddsi_guid_prefix_t *guid_prefix; - if (((unsigned)idx < num_fixed) - || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST) - { guid_prefix = NULL; } + if (((unsigned)idx < num_fixed) || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST) + guid_prefix = NULL; else - { guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; } - + guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; /* Process message and clean out connection if failed or closed */ - if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) - && !conn->m_connless) - { + if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) && !conn->m_connless) ddsi_conn_free (conn); - } } } } diff --git a/src/core/ddsi/src/q_sockwaitset_s.c b/src/core/ddsi/src/q_sockwaitset_s.c deleted file mode 100755 index 323ef36a..00000000 --- a/src/core/ddsi/src/q_sockwaitset_s.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License - * v. 1.0 which is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause - */ -#include -#include -#include - -#include "dds/ddsrt/heap.h" -#include "dds/ddsrt/sockets.h" -#include "dds/ddsrt/sync.h" - -#include "dds/ddsi/q_sockwaitset.h" -#include "dds/ddsi/ddsi_config_impl.h" -#include "dds/ddsi/q_log.h" -#include "dds/ddsi/ddsi_tran.h" - -#define WAITSET_DELTA 8 - -#define MODE_KQUEUE 1 -#define MODE_SELECT 2 -#define MODE_WFMEVS 3 - -#if defined __APPLE__ -#define MODE_SEL MODE_KQUEUE -#elif defined WINCE -#define MODE_SEL MODE_WFMEVS -#else -#define MODE_SEL MODE_SELECT /* FreeRTOS always use select */ -#endif - - -#ifdef DDSRT_WITH_FREERTOSTCP -# warning " *** HKR debug include tree " - -#else -#if !_WIN32 && !LWIP_SOCKET - -#if ! __VXWORKS__&& !__QNXNTO__ -#include -#endif /* __VXWORKS__ __QNXNTO__ */ - -#ifndef _WRS_KERNEL -#include -#endif -#ifdef __sun -#include -#include -#include -#endif - -#endif /* !_WIN32 && !LWIP_SOCKET */ -#endif - -typedef struct os_sockWaitsetSet -{ - ddsi_tran_conn_t * conns; /* connections in set */ - ddsrt_socket_t * fds; /* file descriptors in set */ - unsigned sz; /* max number of fds in context */ - unsigned n; /* actual number of fds in context */ -} os_sockWaitsetSet; - -struct os_sockWaitsetCtx -{ - os_sockWaitsetSet set; /* set of connections and descriptors */ - unsigned index; /* cursor for enumerating */ - ddsrt_fd_set_t rdset; /* read file descriptors set */ -}; - -struct os_sockWaitset -{ - ddsrt_socket_t pipe[2]; /* pipe used for triggering */ - ddsrt_mutex_t mutex; /* concurrency guard */ - int fdmax_plus_1; /* value for first parameter of select() */ - os_sockWaitsetSet set; /* set of descriptors handled next */ - struct os_sockWaitsetCtx ctx; /* set of descriptors being handled */ -}; - -#if defined (_WIN32) -static int make_pipe (ddsrt_socket_t fd[2]) -{ - struct sockaddr_in addr; - socklen_t asize = sizeof (addr); - ddsrt_socket_t listener = socket (AF_INET, SOCK_STREAM, 0); - ddsrt_socket_t s1 = socket (AF_INET, SOCK_STREAM, 0); - ddsrt_socket_t s2 = DDSRT_INVALID_SOCKET; - - addr.sin_family = AF_INET; - #ifdef DDSRT_WITH_FREERTOSTCP - addr.sin_addr = htonl (INADDR_LOOPBACK); - #else - addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - #endif - addr.sin_port = 0; - if (bind (listener, (struct sockaddr *)&addr, sizeof (addr)) == -1) - goto fail; - if (getsockname (listener, (struct sockaddr *)&addr, &asize) == -1) - goto fail; - if (listen (listener, 1) == -1) - goto fail; - if (connect (s1, (struct sockaddr *)&addr, sizeof (addr)) == -1) - goto fail; - if ((s2 = accept (listener, 0, 0)) == INVALID_SOCKET) - goto fail; - closesocket (listener); - /* Equivalent to FD_CLOEXEC */ - SetHandleInformation ((HANDLE) s1, HANDLE_FLAG_INHERIT, 0); - SetHandleInformation ((HANDLE) s2, HANDLE_FLAG_INHERIT, 0); - fd[0] = s1; - fd[1] = s2; - return 0; - -fail: - closesocket (listener); - closesocket (s1); - closesocket (s2); - return -1; -} -#elif defined(__VXWORKS__) -static int make_pipe (int pfd[2]) -{ - char pipename[OSPL_PIPENAMESIZE]; - int pipecount = 0; - do { - snprintf ((char*)&pipename, sizeof (pipename), "/pipe/ospl%d", pipecount++); - } while ((result = pipeDevCreate ((char*)&pipename, 1, 1)) == -1 && os_getErrno() == EINVAL); - if (result == -1) - goto fail_pipedev; - if ((pfd[0] = open ((char*)&pipename, O_RDWR, 0644)) == -1) - goto fail_open0; - if ((pfd[1] = open ((char*)&pipename, O_RDWR, 0644)) == -1) - goto fail_open1; - return 0; - -fail_open1: - close (pfd[0]); -fail_open0: - pipeDevDelete (pipename, 0); -fail_pipedev: - return -1; -} -#elif !defined(LWIP_SOCKET) -static int make_pipe (int pfd[2]) -{ - return pipe (pfd); -} -#endif - -static void os_sockWaitsetNewSet (os_sockWaitsetSet * set) -{ - set->fds = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->fds)); - set->conns = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->conns)); - set->sz = WAITSET_DELTA; - set->n = 1; -} - -static void os_sockWaitsetFreeSet (os_sockWaitsetSet * set) -{ - ddsrt_free (set->fds); - ddsrt_free (set->conns); -} - -static void os_sockWaitsetNewCtx (os_sockWaitsetCtx ctx) -{ - os_sockWaitsetNewSet (&ctx->set); - - #ifdef DDSRT_WITH_FREERTOSTCP - ctx->rdset = DDSRT_FD_SET_CRATE(); - DDSRT_FD_ZERO (ctx->rdset); - DDS_WARNING("os_sockWaitsetNewCtx: rdset created! rdset %p \n", ctx->rdset); - #else - FD_ZERO (ctx->rdset); - #endif -} - -static void os_sockWaitsetFreeCtx (os_sockWaitsetCtx ctx) -{ - #ifdef DDSRT_WITH_FREERTOSTCP - DDSRT_FD_SET_DELETE(ctx->rdset); - #endif - os_sockWaitsetFreeSet (&ctx->set); -} - -os_sockWaitset os_sockWaitsetNew (void) -{ - int result; - os_sockWaitset ws = ddsrt_malloc (sizeof (*ws)); - - os_sockWaitsetNewSet (&ws->set); - os_sockWaitsetNewCtx (&ws->ctx); - -#if ! defined (_WIN32) - ws->fdmax_plus_1 = 0; -#else - ws->fdmax_plus_1 = FD_SETSIZE; -#endif - -#if defined(LWIP_SOCKET) - ws->pipe[0] = -1; - ws->pipe[1] = -1; - result = 0; -#elif defined(DDSRT_WITH_FREERTOSTCP) - # warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." - ws->pipe[0] = -1; - ws->pipe[1] = -1; - result = 0; -#else - # error " *** NO makepipe for FreeRTOS " - - result = make_pipe (ws->pipe); -#endif - if (result == -1) - { - os_sockWaitsetFreeCtx (&ws->ctx); - os_sockWaitsetFreeSet (&ws->set); - ddsrt_free (ws); - return NULL; - } - -#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) - ws->set.fds[0] = ws->pipe[0]; -#else -#warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." - ws->set.fds[0] = 0; -#endif - ws->set.conns[0] = NULL; - -#if !defined(__VXWORKS__) && !defined(_WIN32) && !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) && !defined(__QNXNTO__) - (void) fcntl (ws->pipe[0], F_SETFD, fcntl (ws->pipe[0], F_GETFD) | FD_CLOEXEC); - (void) fcntl (ws->pipe[1], F_SETFD, fcntl (ws->pipe[1], F_GETFD) | FD_CLOEXEC); -#endif - -#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) - FD_SET (ws->set.fds[0], ws->ctx.rdset); -#endif - -#if !defined(_WIN32) && !defined(DDSRT_WITH_FREERTOSTCP) - ws->fdmax_plus_1 = ws->set.fds[0] + 1; -#endif - - ddsrt_mutex_init (&ws->mutex); - - return ws; -} - -static void os_sockWaitsetGrow (os_sockWaitsetSet * set) -{ - set->sz += WAITSET_DELTA; - set->conns = ddsrt_realloc (set->conns, set->sz * sizeof (*set->conns)); - set->fds = ddsrt_realloc (set->fds, set->sz * sizeof (*set->fds)); -} - -void os_sockWaitsetFree (os_sockWaitset ws) -{ -#if defined(__VXWORKS__) && defined(__RTP__) - char nameBuf[OSPL_PIPENAMESIZE]; - ioctl (ws->pipe[0], FIOGETNAME, &nameBuf); -#endif - -#if defined(DDSRT_WITH_FREERTOSTCP) -# warning " *** HKR runtime tree " - (void) ddsrt_close (ws->pipe[0]); - (void) ddsrt_close (ws->pipe[1]); -#else - -#if defined(_WIN32) - closesocket (ws->pipe[0]); - closesocket (ws->pipe[1]); -#elif !defined(LWIP_SOCKET) - (void) close (ws->pipe[0]); - (void) close (ws->pipe[1]); -#endif -#endif - -#if defined(__VXWORKS__) && defined(__RTP__) - pipeDevDelete ((char*) &nameBuf, 0); -#endif - os_sockWaitsetFreeSet (&ws->set); - os_sockWaitsetFreeCtx (&ws->ctx); - ddsrt_mutex_destroy (&ws->mutex); - ddsrt_free (ws); -} - -void os_sockWaitsetTrigger (os_sockWaitset ws) -{ -#if defined(LWIP_SOCKET) - (void)ws; -#elif defined (DDSRT_WITH_FREERTOSTCP) -#warning " *** HKR FreeRTOS_Plus_TCP runtime wrapper ..." - (void)ws; -#else - char buf = 0; - int n; - -#if defined (_WIN32) - n = send (ws->pipe[1], &buf, 1, 0); -#else - n = (int) write (ws->pipe[1], &buf, 1); -#endif - if (n != 1) - { - DDS_WARNING("os_sockWaitsetTrigger: write failed on trigger pipe\n"); - } -#endif -} - -int os_sockWaitsetAdd (os_sockWaitset ws, ddsi_tran_conn_t conn) -{ - ddsrt_socket_t handle = ddsi_conn_handle (conn); - os_sockWaitsetSet * set = &ws->set; - unsigned idx; - int ret; - -#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP) - assert (handle >= 0); - assert (handle < FD_SETSIZE); -#endif - - ddsrt_mutex_lock (&ws->mutex); - for (idx = 0; idx < set->n; idx++) - { - if (set->conns[idx] == conn) - break; - } - if (idx < set->n) - { ret = 0; } - else - { - if (set->n == set->sz) - { os_sockWaitsetGrow (set); } -#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP) - if ((int) handle >= ws->fdmax_plus_1) - ws->fdmax_plus_1 = handle + 1; -#endif - set->conns[set->n] = conn; - set->fds[set->n] = handle; - set->n++; - ret = 1; - } - ddsrt_mutex_unlock (&ws->mutex); - return ret; -} - -void os_sockWaitsetPurge (os_sockWaitset ws, unsigned index) -{ - os_sockWaitsetSet * set = &ws->set; - - ddsrt_mutex_lock (&ws->mutex); - if (index + 1 <= set->n) - { - for (unsigned i = index + 1; i < set->n; i++) - { - set->conns[i] = NULL; - set->fds[i] = 0; - } - set->n = index + 1; - } - ddsrt_mutex_unlock (&ws->mutex); -} - -void os_sockWaitsetRemove (os_sockWaitset ws, ddsi_tran_conn_t conn) -{ - os_sockWaitsetSet * set = &ws->set; - - ddsrt_mutex_lock (&ws->mutex); - for (unsigned i = 0; i < set->n; i++) - { - if (conn == set->conns[i]) - { - set->n--; - if (i != set->n) - { - set->fds[i] = set->fds[set->n]; - set->conns[i] = set->conns[set->n]; - } - break; - } - } - ddsrt_mutex_unlock (&ws->mutex); -} - -os_sockWaitsetCtx os_sockWaitsetWait (os_sockWaitset ws) -{ - unsigned u; -#if !_WIN32 - int fdmax; -#endif - ddsrt_fd_set_t rdset = NULL; - os_sockWaitsetCtx ctx = &ws->ctx; - os_sockWaitsetSet * dst = &ctx->set; - os_sockWaitsetSet * src = &ws->set; - - ddsrt_mutex_lock (&ws->mutex); - -#ifdef DDSRT_WITH_FREERTOSTCP - fdmax = 0; /* For FreeRTOS_TCP stack, fdmax is stub for api compatible */ -#else - #if !_WIN32 - fdmax = ws->fdmax_plus_1; - #endif -#endif - - /* Copy context to working context */ - - while (dst->sz < src->sz) - { - os_sockWaitsetGrow (dst); - } - dst->n = src->n; - - for (u = 0; u < src->n; u++) - { - dst->conns[u] = src->conns[u]; - dst->fds[u] = src->fds[u]; - } - - ddsrt_mutex_unlock (&ws->mutex); - - - /* Copy file descriptors into select read set */ - rdset = ctx->rdset; -#ifdef DDSRT_WITH_FREERTOSTCP - if (rdset == NULL) - { - assert(0); - } - -#endif - - DDSRT_FD_ZERO (rdset); -#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) - for (u = 0; u < dst->n; u++) - { - FD_SET (dst->fds[u], rdset); - } -#else - /* fds[0]/conns[0] not using for RTOS */ - for (u = 1; u < dst->n; u++) - { - DDSRT_WARNING_GNUC_OFF(sign-conversion) - DDSRT_FD_SET (dst->fds[u], rdset); - DDSRT_WARNING_GNUC_ON(sign-conversion) - } -#endif /* LWIP_SOCKET */ - - dds_return_t rc; - do - { - rc = ddsrt_select (fdmax, rdset, NULL, NULL, SELECT_TIMEOUT_MS); - if (rc < 0 && rc != DDS_RETCODE_INTERRUPTED && rc != DDS_RETCODE_TRY_AGAIN) - { - DDS_WARNING("os_sockWaitsetWait: select failed, retcode = %"PRId32, rc); - break; - } - } while (rc < 0); - - if (rc > 0) - { - /* set start VALID conn index - * this simply skips the trigger fd, index0 is INV. - */ - ctx->index = 1; - - /* to confirm for DDSRT_WITH_FREERTOSTCP - TODO - TODO - TODO - TODO - TODO - TODO - */ -#if ! defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) - if (FD_ISSET (dst->fds[0], rdset)) - { - char buf; - int n1; - #if defined (_WIN32) - n1 = recv (dst->fds[0], &buf, 1, 0); - #else - n1 = (int) read (dst->fds[0], &buf, 1); - #endif - if (n1 != 1) - { - DDS_WARNING("os_sockWaitsetWait: read failed on trigger pipe\n"); - assert (0); - } - } -#endif /* LWIP_SOCKET */ - return ctx; - } - - return NULL; -} - -int os_sockWaitsetNextEvent (os_sockWaitsetCtx ctx, ddsi_tran_conn_t * conn) -{ - while (ctx->index < ctx->set.n) - { - unsigned idx = ctx->index++; - ddsrt_socket_t fd = ctx->set.fds[idx]; -#if ! defined (LWIP_SOCKET) && ! defined(DDSRT_WITH_FREERTOSTCP) - assert(idx > 0); -#endif - - if (DDSRT_FD_ISSET (fd, ctx->rdset)) - { - *conn = ctx->set.conns[idx]; - - return (int) (idx - 1); - } - } - return -1; -} - - diff --git a/src/core/ddsi/src/q_thread.c b/src/core/ddsi/src/q_thread.c index 3205bc74..6de01fa1 100644 --- a/src/core/ddsi/src/q_thread.c +++ b/src/core/ddsi/src/q_thread.c @@ -109,12 +109,7 @@ void thread_states_init (unsigned maxthreads) (not strictly required, but it'll get one eventually anyway, and this makes it rather more clear). */ #ifndef NDEBUG -#ifdef DDSRT_WITH_FREERTOSTCP - struct thread_state1 * const ts0 = (struct thread_state1 * const)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); -#else struct thread_state1 * const ts0 = tsd_thread_state; -#endif - #endif struct thread_state1 * const ts1 = lookup_thread_state_real (); assert (ts0 == NULL || ts0 == ts1); @@ -129,12 +124,7 @@ bool thread_states_fini (void) struct thread_state1 *ts1 = lookup_thread_state (); assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime))); reap_thread_state (ts1, true); - - #ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL); - #else tsd_thread_state = NULL; - #endif /* Some applications threads that, at some point, required a thread state, may still be around. Of those, the cleanup routine is invoked when the thread terminates. This should be rewritten @@ -225,22 +215,13 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self) struct thread_state1 *lookup_thread_state_real (void) { -#ifdef DDSRT_WITH_FREERTOSTCP - struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); -#else struct thread_state1 *ts1 = tsd_thread_state; -#endif - if (ts1 == NULL) { ddsrt_thread_t self = ddsrt_thread_self (); if ((ts1 = find_thread_state (self)) == NULL) ts1 = lazy_create_thread_state (self); -#ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1); -#else tsd_thread_state = ts1; -#endif } assert (ts1 != NULL); return ts1; @@ -251,19 +232,9 @@ static uint32_t create_thread_wrapper (void *ptr) struct thread_state1 * const ts1 = ptr; struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv); if (gv) - { - #ifndef DDSRT_WITH_FREERTOSTCP - GVTRACE ("started new thread %"PRIdTID": %s \n", ddsrt_gettid (), ts1->name); - #else - GVTRACE ("started new thread %"PRIdTID": %s, thread_t 0x%lx \n", ddsrt_gettid (), ts1->name, ts1->tid.task); - #endif - } + GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ts1->name); assert (ts1->state == THREAD_STATE_INIT); -#ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1); -#else tsd_thread_state = ts1; -#endif ddsrt_mutex_lock (&thread_states.lock); ts1->state = THREAD_STATE_ALIVE; ddsrt_mutex_unlock (&thread_states.lock); @@ -271,12 +242,7 @@ static uint32_t create_thread_wrapper (void *ptr) ddsrt_mutex_lock (&thread_states.lock); ts1->state = THREAD_STATE_STOPPED; ddsrt_mutex_unlock (&thread_states.lock); -#ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL); -#else tsd_thread_state = NULL; -#endif - return ret; } diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index b1bbd0d3..3e07fb55 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -323,32 +323,18 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_ { if (ddsrt_avl_is_empty (&wr->readers)) { -#ifdef DDSRT_WITH_FREERTOSTCP - ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", - PGUID (wr->e.guid), - *hbansreq ? "" : " final", - (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec -#else ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, -#endif whcst->max_seq, writer_read_seq_xmit(wr)); } else { -#ifdef DDSRT_WITH_FREERTOSTCP - ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", - PGUID (wr->e.guid), - *hbansreq ? "" : " final", - (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec -#else ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, -#endif root_rdmatch (wr)->min_seq, root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!", whcst->max_seq, writer_read_seq_xmit(wr)); diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index 0b285405..62af2967 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -531,22 +531,14 @@ struct xeventq * xeventq_new (struct ddsi_domaingv *gv, size_t max_queued_rexmit dds_return_t xeventq_start (struct xeventq *evq, const char *name) { dds_return_t rc; -#ifdef DDSRT_WITH_FREERTOSTCP - char * evqname = "dds_tev"; -#else char * evqname = "tev"; -#endif assert (evq->ts == NULL); if (name) { size_t slen = strlen (name) + 5; evqname = ddsrt_malloc (slen); - #ifdef DDSRT_WITH_FREERTOSTCP - (void) snprintf (evqname, slen, "dds_tev.%s", name); - #else (void) snprintf (evqname, slen, "tev.%s", name); - #endif } evq->terminate = 0; @@ -772,36 +764,20 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt if (ddsrt_avl_is_empty (&wr->readers)) { -#ifdef DDSRT_WITH_FREERTOSTCP - GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", - PGUID (wr->e.guid), - hbansreq ? "" : " final", - msg ? "sent" : "suppressed", - (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec -#else - GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", + GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, -#endif whcst.max_seq, writer_read_seq_xmit (wr)); } else { -#ifdef DDSRT_WITH_FREERTOSTCP - GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", - PGUID (wr->e.guid), - hbansreq ? "" : " final", - msg ? "sent" : "suppressed", - (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec -#else - GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", + GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", - (t_next.v == DDS_NEVER) ? DDS_NEVER : (double)(t_next.v - tnow.v) / 1e9, -#endif + (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq, ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!", whcst.max_seq, writer_read_seq_xmit (wr)); @@ -1052,18 +1028,10 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e else { ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (tnow, DDS_SECS (1)); -#ifdef DDSRT_WITH_FREERTOSTCP - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n", - PGUID (pp->e.guid), - PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, - (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec - ); -#else - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n", + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9); -#endif (void) resched_xevent_if_earlier (ev, tnext); } } @@ -1087,18 +1055,10 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e intv = gv->config.spdp_interval; tnext = ddsrt_mtime_add_duration (tnow, intv); - #ifdef DDSRT_WITH_FREERTOSTCP - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n", - PGUID (pp->e.guid), - PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, - (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec - ); - #else - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n", + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9); - #endif (void) resched_xevent_if_earlier (ev, tnext); } } @@ -1131,13 +1091,7 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_ tnext.v = tnow.v + intv - DDS_SECS (2); else tnext.v = tnow.v + 4 * intv / 5; - #ifdef DDSRT_WITH_FREERTOSTCP - GVTRACE ("resched pmd("PGUIDFMT"): %u usec\n", PGUID (pp->e.guid), - (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec - ); - #else - GVTRACE ("resched pmd("PGUIDFMT"): %g s\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); - #endif + GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); } (void) resched_xevent_if_earlier (ev, tnext); @@ -1173,12 +1127,6 @@ static void handle_individual_xevent (struct thread_state1 * const ts1, struct x switch (xev->kind) { case XEVK_HEARTBEAT: - #ifdef DDSRT_WITH_FREERTOSTCP - { - static uint32_t hb_cnt = 0U; - DDS_WARNING(" handle_xevk_heartbeat %u ... ", hb_cnt++); - } - #endif handle_xevk_heartbeat (xp, xev, tnow); break; case XEVK_ACKNACK: diff --git a/src/core/ddsi/src/q_xmsg.c b/src/core/ddsi/src/q_xmsg.c index 1cb12543..aa5bbc75 100644 --- a/src/core/ddsi/src/q_xmsg.c +++ b/src/core/ddsi/src/q_xmsg.c @@ -121,7 +121,6 @@ struct nn_xmsg { #ifdef IOV_MAX #if IOV_MAX > 0 && IOV_MAX < 256 -#error " you should not be here for DDSRT_WITH_FREERTOSTCP" #define NN_XMSG_MAX_MESSAGE_IOVECS IOV_MAX #endif #endif /* defined IOV_MAX */ @@ -1249,15 +1248,7 @@ static ssize_t nn_xpack_send1 (const ddsi_xlocator_t *loc, void * varg) } /* Possible number of bytes written can be larger * due to security. */ - #ifdef DDSRT_WITH_FREERTOSTCP - if (nbytes < len) - { - GVERROR (" sent len is NOT right! len %u v %u", len, nbytes); - assert (nbytes == -1 || (size_t) nbytes >= len); - } - #else assert (nbytes == -1 || (size_t) nbytes >= len); - #endif } #endif } @@ -1727,7 +1718,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag const uint32_t max_msg_size = rexmit ? xp->gv->config.max_rexmit_msg_size : xp->gv->config.max_msg_size; if (xpo_niov > 0 && sz > max_msg_size) { - GVINFO (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", + GVTRACE (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", (int) niov, sz, max_msg_size, (int) xpo_niov, xpo_sz); xp->msg_len.length = xpo_sz; xp->niov = xpo_niov; diff --git a/src/ddsrt/include/dds/config.h.in b/src/ddsrt/include/dds/config.h.in index f33ed369..87493ab3 100644 --- a/src/ddsrt/include/dds/config.h.in +++ b/src/ddsrt/include/dds/config.h.in @@ -15,17 +15,6 @@ #cmakedefine DDSRT_WITH_LWIP 1 #cmakedefine DDSRT_WITH_FREERTOS 1 -/* begin: FreeRTOS_Plus_TCP IP stack */ -#cmakedefine DDSRT_WITH_FREERTOSTCP 1 - -#cmakedefine DDSRT_TRANS_UDP 1 -#cmakedefine DDSRT_TRANS_TCP 1 -#cmakedefine DDSRT_TRANS_RAWETH 1 -#cmakedefine DDSRT_TRANS_NONE 1 - -/* end: FreeRTOS_Plus_TCP IP stack */ - - #cmakedefine DDSRT_HAVE_DYNLIB 1 #cmakedefine DDSRT_HAVE_FILESYSTEM 1 #cmakedefine DDSRT_HAVE_NETSTAT 1 diff --git a/src/ddsrt/include/dds/ddsrt/iovec.h b/src/ddsrt/include/dds/ddsrt/iovec.h index 3e9fe845..cbfa3514 100644 --- a/src/ddsrt/include/dds/ddsrt/iovec.h +++ b/src/ddsrt/include/dds/ddsrt/iovec.h @@ -26,15 +26,6 @@ typedef unsigned long ddsrt_msg_iovlen_t; #if DDSRT_WITH_LWIP #include - -#elif defined DDSRT_WITH_FREERTOSTCP -#warning "debug rtos tcp stack including " -/* will implement struct io_vec in freertos_plus_tcp.h wrapper header. */ - -struct iovec { - void *iov_base; - size_t iov_len; -}; #else #include #include @@ -45,8 +36,6 @@ typedef size_t ddsrt_iov_len_t; #if defined(__linux) && !LWIP_SOCKET typedef size_t ddsrt_msg_iovlen_t; -#elif defined DDSRT_WITH_FREERTOSTCP -typedef size_t ddsrt_msg_iovlen_t; #else /* POSIX says int (which macOS, FreeBSD, Solaris do) */ typedef int ddsrt_msg_iovlen_t; #endif diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index cbe31492..dabdacb8 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -24,9 +24,6 @@ #include #include -#include "dds/config.h" -#include "dds/features.h" - #include "dds/export.h" #include "dds/ddsrt/attributes.h" @@ -90,12 +87,8 @@ extern "C" { DDS_LC_CONTENT | DDS_LC_SHM) /** @}*/ -#ifdef DDSRT_WITH_FREERTOSTCP -#define DDS_LOG_MASK DDS_LC_ALL -#else #define DDS_LOG_MASK \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO) -#endif #define DDS_TRACE_MASK \ (~DDS_LOG_MASK) @@ -389,15 +382,9 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ -#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_LOG(cat, ...) \ ((dds_get_log_mask() & (cat)) ? \ dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) -#else -#define DDS_LOG(cat, fmt, ...) \ - ((dds_get_log_mask() & (cat)) ? \ - dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, fmt, ##__VA_ARGS__) : 0) -#endif /** * @brief Write a log message with a domain id override. @@ -411,15 +398,10 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ -#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_ILOG(cat, domid, ...) \ ((dds_get_log_mask() & (cat)) ? \ dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) -#else -#define DDS_ILOG(cat, domid, fmt, ...) \ - ((dds_get_log_mask() & (cat)) ? \ - dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, fmt " \n", ##__VA_ARGS__) : 0) -#endif + /** * @brief Write a log message using a specific config. * @@ -432,15 +414,9 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ -#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_CLOG(cat, cfg, ...) \ (((cfg)->c.mask & (cat)) ? \ dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) -#else -#define DDS_CLOG(cat, cfg, fmt, ...) \ - (((cfg)->c.mask & (cat)) ? \ - dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) : 0) -#endif /** Write a log message of type #DDS_LC_INFO into global log. */ #define DDS_INFO(...) \ @@ -452,13 +428,8 @@ dds_log( #define DDS_ERROR(...) \ DDS_LOG(DDS_LC_ERROR, __VA_ARGS__) /** Write a log message of type #DDS_LC_ERROR into global log and abort. */ -#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_FATAL(...) \ dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) -#else -#define DDS_FATAL(fmt, ...) \ - dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) -#endif /* MSVC mishandles __VA_ARGS__ while claiming to be conforming -- and even if they have a defensible implement, they still differ from every other diff --git a/src/ddsrt/include/dds/ddsrt/process.h b/src/ddsrt/include/dds/ddsrt/process.h index 84e75197..c074d084 100644 --- a/src/ddsrt/include/dds/ddsrt/process.h +++ b/src/ddsrt/include/dds/ddsrt/process.h @@ -55,18 +55,6 @@ extern "C" { DDS_EXPORT ddsrt_pid_t ddsrt_getpid(void); -/** - * @brief Return process name of the calling process. - * - * On linux maps to /proc/self/cmdline's first entry (argv[0]), - * on mac/windows maps to relevant API calls. Falls back to process-{pid} - * on failure. - * - * @returns The process name of the calling process. - */ -DDS_EXPORT char * -ddsrt_getprocessname(void); - #if defined (__cplusplus) } #endif diff --git a/src/ddsrt/include/dds/ddsrt/sockets.h b/src/ddsrt/include/dds/ddsrt/sockets.h index 4a911c67..65b40ed5 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets.h +++ b/src/ddsrt/include/dds/ddsrt/sockets.h @@ -10,16 +10,10 @@ #include "dds/ddsrt/retcode.h" #include "dds/ddsrt/time.h" #include "dds/ddsrt/misc.h" - -#if defined DDSRT_WITH_FREERTOSTCP - #warning " debug rtos tcp stack including " - #include "dds/ddsrt/sockets/freertos_plus_tcp.h" +#if _WIN32 +#include "dds/ddsrt/sockets/windows.h" #else - #if _WIN32 - #include "dds/ddsrt/sockets/windows.h" - #else - #include "dds/ddsrt/sockets/posix.h" - #endif +#include "dds/ddsrt/sockets/posix.h" #endif #if defined (__cplusplus) @@ -193,15 +187,9 @@ ddsrt_setsockreuse( DDS_EXPORT dds_return_t ddsrt_select( int32_t nfds, -#ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_fd_set_t readfds, - ddsrt_fd_set_t writefds, - ddsrt_fd_set_t errorfds, -#else fd_set *readfds, fd_set *writefds, fd_set *errorfds, -#endif dds_duration_t reltime); #if _WIN32 diff --git a/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h deleted file mode 100755 index c2c01e22..00000000 --- a/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * INTEL CONFIDENTIAL - * - * Copyright (C) 2022 Intel Corporation - * - * This software and the related documents are Intel copyrighted materials, - * and your use of them is governed by the express license under which they - * were provided to you ("License"). Unless the License provides otherwise, - * you may not use, modify, copy, publish, distribute, disclose or transmit - * this software or the related documents without Intel's prior written permission. - * This software and the related documents are provided as is, with no express - * or implied warranties, other than those that are expressly - * stated in the License. - */ - -#ifndef DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H -#define DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H - -#define __need_size_t -#include - -/* This operating system-specific header file defines the SOCK_*, PF_*, - AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr', - `struct msghdr', and `struct linger' types. */ - -#include - -#include -#include -#include -#include - -#include "dds/ddsrt/iovec.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#ifndef ntohl -#define ntohl FreeRTOS_ntohl -#define htol FreeRTOS_htonl - -#define htos FreeRTOS_htons -#define ntohs FreeRTOS_ntohs -#endif - -#define inet_addr FreeRTOS_inet_addr -#define IN_MULTICAST(ip) (xIsIPv4Multicast(ntohl(ip))) - - -/* posix data for FreeRTOS+TCP stack */ -#define DDSRT_HAVE_SSM 0 -#define IFF_UP 0x1 -#define IFF_BROADCAST 0x2 -#define IFF_LOOPBACK 0x8 -#define IFF_POINTOPOINT 0x10 -#define IFF_MULTICAST 0x1000 - -struct msghdr -{ - void *msg_name; - socklen_t msg_namelen; - struct iovec *msg_iov; - int msg_iovlen; - void *msg_control; - socklen_t msg_controllen; - int msg_flags; -}; - -struct timeval -{ - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; - -typedef struct msghdr ddsrt_msghdr_t; -#define DDSRT_MSGHDR_FLAGS 0 - - -/* adaption to ddsrt socket interface */ -typedef Socket_t ddsrt_socket_t; /* Socket_t ==> FreeRTOS_Socket_t* */ -// typedef SocketSelect_t fd_set; /* SocketSelect_t => struct xSOCKET_SET */ -typedef SocketSet_t ddsrt_fd_set_t; - -#define SELECT_TIMEOUT_MS 1000U /* 200U experienced value from XRCE-client */ - -/* -FD_ZERO() clears a set. -FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set. -FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns. -*/ -static inline void DDSRT_FD_ZERO(ddsrt_fd_set_t set) -{ - (void)set; -} - -static ddsrt_fd_set_t DDSRT_FD_SET_CRATE(void) -{ - SocketSet_t set = FreeRTOS_CreateSocketSet(); - assert(set); - return set; -} - -static void DDSRT_FD_SET_DELETE(ddsrt_fd_set_t set) -{ - assert(set); - FreeRTOS_DeleteSocketSet(set); -} - -/* -#define DDSRT_FD_ISSET(fd, set) FreeRTOS_FD_ISSET(fd, set) -#define DDSRT_FD_SET(fd, set) FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT) -#define DDSRT_FD_CLR(fd, set) FreeRTOS_FD_CLR(fd, set, eSELECT_ALL) -*/ - -static inline int32_t DDSRT_FD_ISSET(ddsrt_socket_t fd, ddsrt_fd_set_t set) -{ - return (int32_t)FreeRTOS_FD_ISSET(fd, set); -} - -/* for FD_SET only be used in CDDS for rdset */ -static inline void DDSRT_FD_SET(ddsrt_socket_t fd, ddsrt_fd_set_t set) -{ - FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT); -} - -static inline void DDSRT_FD_CLR(ddsrt_socket_t fd, ddsrt_fd_set_t set) -{ - FreeRTOS_FD_CLR(fd, set, eSELECT_ALL); -} - -#ifndef sa_family_t - typedef uint8_t sa_family_t; -#endif - - struct sockaddr_storage - { - uint8_t s2_len; - sa_family_t ss_family; - char s2_data1[2]; - uint32_t s2_data2[3]; - }; - -#if 1 - /* for posix compatible sa_family reference inside DDS - * we declare sockaddr a new struct but same W/ freertos_sockaddr - */ - struct sockaddr - { - uint8_t sa_len; - sa_family_t sa_family; - uint16_t sin_port; - uint32_t sin_addr; - }; -#else -#define sockaddr freertos_sockaddr -#endif - -#define sockaddr_in freertos_sockaddr -typedef uint32_t in_addr_t; /* base type for internet address */ - -/* - * Options and types related to multicast membership - */ -#define IP_ADD_MEMBERSHIP 3 -#define IP_DROP_MEMBERSHIP 4 - typedef struct ip_mreq - { - in_addr_t imr_multiaddr; /* IP multicast address of group */ - in_addr_t imr_interface; /* local IP address of interface */ - } ip_mreq; - // end multicast - -#define IP_MULTICAST_TTL 5 -#define IP_MULTICAST_IF 6 -#define IP_MULTICAST_LOOP 7 - -/** 255.255.255.255 */ -#define INADDR_NONE ((uint32_t)0xffffffffUL) -/** 127.0.0.1 */ -#define INADDR_LOOPBACK ((uint32_t)0x7f000000UL) -/** 0.0.0.0 */ -#define INADDR_ANY ((uint32_t)0x00000000UL) -/** 255.255.255.255 */ -#define INADDR_BROADCAST ((uint32_t)0xffffffffUL) - -#define AF_INET FREERTOS_AF_INET -#define AF_INET6 FREERTOS_AF_INET6 - -#define IPPROTO_IP 0 -#define IPPROTO_ICMP ipPROTOCOL_ICMP - -#define SOCK_DGRAM FREERTOS_SOCK_DGRAM -#define IPPROTO_UDP FREERTOS_IPPROTO_UDP - -#define SOCK_STREAM FREERTOS_SOCK_STREAM -#define IPPROTO_TCP FREERTOS_IPPROTO_TCP - -#define SOL_SOCKET IPPROTO_IP /* set socket level, always 0 for RTOS */ - -#define SO_REUSEADDR FREERTOS_SO_REUSE_LISTEN_SOCKET -#define SO_RCVTIMEO FREERTOS_SO_RCVTIMEO -#define SO_SNDTIMEO FREERTOS_SO_SNDTIMEO -#define SO_SNDBUF FREERTOS_SO_SNDBUF -#define SO_RCVBUF FREERTOS_SO_RCVBUF - -#define SO_OOB FREERTOS_MSG_OOB -#define SO_PEEK FREERTOS_MSG_PEEK -#define SO_DONTROUTE FREERTOS_MSG_DONTROUTE -#define SO_DONTWAIT FREERTOS_MSG_DONTWAIT - -/* - FreeRTOS_accept() has an optional timeout. The timeout defaults - to ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME, and is modified - using the FREERTOS_SO_RCVTIMEO parameter in a call to FreeRTOS_setsockopt() - - If a timeout occurs before a connection from a remote socket - is accepted then NULL is returned. -*/ -#define ACCEPT_TIMEOUT (NULL) // accpet timeout -#define INVALID_SOCKET (FREERTOS_INVALID_SOCKET) - -/* The following constants should be used for the second parameter of - `shutdown'. */ -#define SHUT_RD FREERTOS_SHUT_RD -#define SHUT_WR FREERTOS_SHUT_WR -#define SHUT_RDWR FREERTOS_SHUT_RDWR - - -#define DDSRT_INVALID_SOCKET (INVALID_SOCKET) -#define PRIdSOCK PRIxPTR - -// #define errno FreeRTOS_errno -#define DDSRT_RET_OK (0) - -#ifndef FD_SETSIZE -#define FD_SETSIZE 8 -#endif - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h index 2c232415..e48cc0c2 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h @@ -31,13 +31,6 @@ extern "C" { #endif typedef int ddsrt_socket_t; - -#ifdef DDSRT_WITH_FREERTOSTCP -typedef fd_set* ddsrt_fd_set_t; /* compatible with FreeRTOS +TCP */ -#define SELECT_TIMEOUT_MS DDS_INFINITY -#endif - - #define DDSRT_INVALID_SOCKET (-1) #define PRIdSOCK "d" diff --git a/src/ddsrt/include/dds/ddsrt/threads.h b/src/ddsrt/include/dds/ddsrt/threads.h index 46ac58fb..6341bf7a 100644 --- a/src/ddsrt/include/dds/ddsrt/threads.h +++ b/src/ddsrt/include/dds/ddsrt/threads.h @@ -49,13 +49,7 @@ extern "C" { supports Thread-local storage since version 2.0. */ /* VxWorks 7 supports __thread for both GCC and DIAB, older versions may support it as well, but that is not verified. */ - -#ifdef DDSRT_WITH_FREERTOSTCP -#define ddsrt_thread_local -#else #define ddsrt_thread_local __thread -#endif - #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) #define ddsrt_thread_local __thread #else @@ -79,32 +73,6 @@ typedef struct { uint32_t stackSize; } ddsrt_threadattr_t; - -#ifdef DDSRT_WITH_FREERTOS -#if configNUM_THREAD_LOCAL_STORAGE_POINTERS <= 0 -#error " Error, FreeRTOS THREAD_LOCAL_STORAGE support NOT enabled!" -#endif - -/* -add configNUM_THREAD_LOCAL_STORAGE_POINTERS for DDS usage - 22 taskguard and FATfs reserved 0~3 -*/ -#define DDS_TLS_IDX_LOGBUFF 4 -#define DDS_TLS_IDX_FREE 5 -#define DDS_TLS_IDX_STATE 6 -#define DDS_TLS_IDX_CTX 7 - -#define ddsrt_thread_tls_set(d, idx, s) \ - vTaskSetThreadLocalStoragePointer(NULL, idx, (void*)s) - -#define ddsrt_thread_tls_get(idx, s) \ - pvTaskGetThreadLocalStoragePointer(NULL, idx) -#else -#error -#define ddsrt_thread_tls_set(d, idx, s) (d) = (s) -#define ddsrt_thread_tls_get(idx, s) (s) -#endif - /** * @brief Initialize thread attributes to platform defaults. */ diff --git a/src/ddsrt/src/cdtors.c b/src/ddsrt/src/cdtors.c index ad49ab2e..5ceca0a8 100644 --- a/src/ddsrt/src/cdtors.c +++ b/src/ddsrt/src/cdtors.c @@ -165,19 +165,6 @@ DDSRT_WARNING_CLANG_ON(missing-prototypes) #pragma data_seg() #endif #else /* _WIN32 */ - -#ifdef DDSRT_WITH_FREERTOSTCP -void ddsrt_ctor(void) -{ - ddsrt_init(); -} - -void ddsrt_dtor(void) -{ - ddsrt_fini(); -} - -#else void __attribute__((constructor)) ddsrt_ctor(void); void __attribute__((destructor)) ddsrt_dtor(void); @@ -190,8 +177,5 @@ void __attribute__((destructor)) ddsrt_dtor(void) { ddsrt_fini(); } - -#endif - #endif /* _WIN32 */ diff --git a/src/ddsrt/src/heap/freertos/heap.c b/src/ddsrt/src/heap/freertos/heap.c index 89d448bc..ffb3d0fb 100644 --- a/src/ddsrt/src/heap/freertos/heap.c +++ b/src/ddsrt/src/heap/freertos/heap.c @@ -10,7 +10,6 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ #include -#include #if defined(configSUPPORT_DYNAMIC_ALLOCATION) && \ (configSUPPORT_DYNAMIC_ALLOCATION == 0) diff --git a/src/ddsrt/src/ifaddrs.c b/src/ddsrt/src/ifaddrs.c index 8114780d..d50a2e40 100644 --- a/src/ddsrt/src/ifaddrs.c +++ b/src/ddsrt/src/ifaddrs.c @@ -19,9 +19,7 @@ ddsrt_freeifaddrs(ddsrt_ifaddrs_t *ifa) while (ifa != NULL) { next = ifa->next; - #ifndef DDSRT_WITH_FREERTOSTCP ddsrt_free(ifa->name); - #endif ddsrt_free(ifa->addr); ddsrt_free(ifa->netmask); ddsrt_free(ifa->broadaddr); diff --git a/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c deleted file mode 100755 index 52c17792..00000000 --- a/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c +++ /dev/null @@ -1,110 +0,0 @@ - -#include -#include - -#include "dds/ddsrt/log.h" -#include "dds/ddsrt/misc.h" -#include "sockets_priv.h" - -#include "dds/ddsrt/heap.h" -#include "dds/ddsrt/io.h" -#include "dds/ddsrt/ifaddrs.h" -#include "dds/ddsrt/retcode.h" -#include "dds/ddsrt/string.h" - -extern const int *const os_supp_afs; - - -static dds_return_t copyaddr(ddsrt_ifaddrs_t **ifap) -{ - dds_return_t rc = DDS_RETCODE_OK; - ddsrt_ifaddrs_t *ifa; - struct sockaddr sa = {0U}; - - assert(ifap != NULL); - - /* note: local IP shoule be got after STACK up! */ - u32 lip, netmask, bcip; - bcip = ipBROADCAST_IP_ADDRESS; - FreeRTOS_GetAddressConfiguration(&lip, &netmask, NULL, NULL); - - ifa = ddsrt_calloc(1, sizeof(*ifa)); - if(ifa == NULL) - { - rc = DDS_RETCODE_OUT_OF_RESOURCES; - goto __exit; - } - - ifa->addr = ddsrt_calloc(1, sizeof(struct sockaddr)); - ifa->netmask = ddsrt_calloc(1, sizeof(struct sockaddr)); - ifa->broadaddr = ddsrt_calloc(1, sizeof(struct sockaddr)); - if ((ifa->addr == NULL) - || (ifa->netmask == NULL) - || (ifa->broadaddr == NULL)) - { - rc = DDS_RETCODE_OUT_OF_RESOURCES; - goto __exit; - } - - sa.sa_len = sizeof(struct sockaddr); - sa.sa_family = AF_INET; - sa.sin_addr = (lip); /* storage IP, no need. FreeRTOS_htonl */ - memcpy((void*)ifa->addr, &sa, sizeof(struct sockaddr)); - - sa.sin_addr = (netmask); - memcpy((void*)ifa->netmask, &sa, sizeof(struct sockaddr)); - - sa.sin_addr = (bcip); - memcpy((void*)ifa->broadaddr, &sa, sizeof(struct sockaddr)); - - ifa->next = NULL; - ifa->type = DDSRT_IFTYPE_WIRED; - ifa->name = "eqos0"; - ifa->index = 0; - ifa->flags = IFF_UP | IFF_BROADCAST; // | IFF_MULTICAST; - -__exit: - if (rc == DDS_RETCODE_OK) - { - *ifap = ifa; - } - else - { - ddsrt_freeifaddrs(ifa); - *ifap = NULL; - } - - return rc; -} - -dds_return_t ddsrt_getifaddrs(ddsrt_ifaddrs_t **ifap, const int *afs) -{ - dds_return_t rc = DDS_RETCODE_OK; - int use_ip4 = 0; - int use_ip6 = 0; - - assert(ifap != NULL); - - if (afs == NULL) - { - afs = os_supp_afs; - } - - for (int i = 0; afs[i] != DDSRT_AF_TERM; i++) - { - if (afs[i] == AF_INET) - { - use_ip4 = 1; - } -#ifdef DDSRT_HAVE_IPV6 - else if (afs[i] == AF_INET6) - { - use_ip6 = 1; - } -#endif - } - - rc = copyaddr(ifap); - - return rc; -} diff --git a/src/ddsrt/src/log.c b/src/ddsrt/src/log.c index 33d3f29e..a291c0ca 100644 --- a/src/ddsrt/src/log.c +++ b/src/ddsrt/src/log.c @@ -38,9 +38,7 @@ typedef struct { FILE *out; } log_sink_t; -#ifndef DDSRT_WITH_FREERTOS static ddsrt_thread_local log_buffer_t log_buffer; -#endif static ddsrt_once_t lock_inited = DDSRT_ONCE_INIT; static ddsrt_rwlock_t lock; @@ -52,82 +50,13 @@ struct ddsrt_log_cfg_impl { DDSRT_STATIC_ASSERT (sizeof (struct ddsrt_log_cfg_impl) <= sizeof (struct ddsrt_log_cfg)); -static const uint8_t * ddslstr[] = { - "DDS_LC_FATAL", - "DDS_LC_ERROR", - "DDS_LC_WARNING", - "DDS_LC_INFO", - "DDS_LC_CONFIG", - "DDS_LC_DISCOVERY", - "DDS_LC_DATA", - "DDS_LC_TRACE", - "DDS_LC_RADMIN", - "DDS_LC_TIMING", - "DDS_LC_TRAFFIC", - "DDS_LC_TOPIC", - "DDS_LC_TCP", - "DDS_LC_PLIST", - "DDS_LC_WHC", - "DDS_LC_THROTTLE", - "DDS_LC_RHC", - "DDS_LC_CONTENT", - "DDS_LC_SHM", - }; - static void default_sink (void *ptr, const dds_log_data_t *data) { - #ifdef DDSRT_WITH_FREERTOSTCP - - (void)ptr; - uint32_t lv; - - uint32_t i; - for (i = 0U; i < sizeof(int) * 8U; i++) - { - if (data->priority <= (1U << i)) - { break; } - } - - switch (data->priority) - { - case DDS_LC_FATAL: - case DDS_LC_ERROR: - lv = IPLOG_LEVEL_ERROR; - pr_error("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - break; - case DDS_LC_WARNING: - lv = IPLOG_LEVEL_WARN; - pr_warn("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - break; - case DDS_LC_CONFIG: - case DDS_LC_INFO: - lv = IPLOG_LEVEL_INFO; - pr_info("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - break; - case DDS_LC_TRACE: - lv = IPLOG_LEVEL_DEBUG; - pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - break; - - case DDS_LC_DISCOVERY: - lv = IPLOG_LEVEL_DEBUG; - pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - break; - - default: - lv = IPLOG_LEVEL_DEBUG; - pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - break; - } - //net_log_print(lv, "[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); - - #else if (ptr) { (void) fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr); fflush ((FILE *) ptr); } - #endif } #define LOG (0) @@ -135,14 +64,7 @@ static void default_sink (void *ptr, const dds_log_data_t *data) static struct ddsrt_log_cfg_impl logconfig = { .c = { - #ifdef DDSRT_WITH_FREERTOSTCP - .mask = DDS_LC_ALL - | DDS_LC_DISCOVERY | DDS_LC_TOPIC - | DDS_LC_CONFIG | DDS_LC_INFO | DDS_LC_WARNING - | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL, - #else .mask = DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL, - #endif .tracemask = 0, .domid = UINT32_MAX }, @@ -250,19 +172,8 @@ static size_t print_header (char *str, uint32_t id) { int cnt, off; char *tid, buf[MAX_TID_LEN+1] = { 0 }; - #ifdef DDSRT_WITH_FREERTOSTCP - /* - * for RTOS, printf might not support all format output, - * so add explict len other that this STDIO tricks - * printf("%.*s", 10, str) - output str with cutoff or prefix padding to 10 chars. - */ - static const char fmt_no_id[] = "%06u.%06d [] %.10s:"; - static const char fmt_with_id[] = "%06u.%06d [%"PRIu32"] %.10s:"; - // snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, tid); - #else static const char fmt_no_id[] = "%10u.%06d [] %*.*s:"; static const char fmt_with_id[] = "%10u.%06d [%"PRIu32"] %*.*s:"; - #endif dds_time_t time; unsigned sec; int usec; @@ -276,44 +187,18 @@ static size_t print_header (char *str, uint32_t id) if (id == UINT32_MAX) { off = MAX_ID_LEN; - #ifdef DDSRT_WITH_FREERTOSTCP - /* fix bug, HDR might overwrite log buffer set before. - HDR_LEN - off - //snprintf (str + off, HDR_LEN, "%10u.%06d [] %*.*s:", sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid) - */ - cnt = snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, - tid); - #else cnt = snprintf (str + off, HDR_LEN, fmt_no_id, sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid); - #endif } else { /* low domain ids tend to be most used from what I have seen */ off = 9; if (id >= 10) - { for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); } - - #ifdef DDSRT_WITH_FREERTOSTCP - cnt = snprintf (str + off, HDR_LEN - off, fmt_with_id, sec, usec, id, tid); - #else + for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); cnt = snprintf (str + off, HDR_LEN, fmt_with_id, sec, usec, id, MAX_TID_LEN, MAX_TID_LEN, tid); - #endif } -#ifdef DDSRT_WITH_FREERTOSTCP - /* fix CycloneDDS bug - * for RTOS printf might not support all STDIO format. "%.*s" - */ - assert (off + cnt < HDR_LEN); - for (int i = off + cnt; i < HDR_LEN; i++) - { - str[i] = ' '; /* Replace snprintf null byte by space. */ - } -#else assert (off + cnt == (HDR_LEN - 1)); str[off + cnt] = ' '; /* Replace snprintf null byte by space. */ -#endif - return (size_t) (cnt + 1); } @@ -324,10 +209,6 @@ static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t log_buffer_t *lb; dds_log_data_t data; - #ifdef DDSRT_WITH_FREERTOS - log_buffer_t log_buffer = {0}; - #endif - /* id can be used to override the id in logconfig, so that the global logging configuration can be used for reporting errors while inlcuding a domain id. This simply verifies that the id override is only ever diff --git a/src/ddsrt/src/process/freertos/process.c b/src/ddsrt/src/process/freertos/process.c index 360d499d..b2998885 100644 --- a/src/ddsrt/src/process/freertos/process.c +++ b/src/ddsrt/src/process/freertos/process.c @@ -20,8 +20,3 @@ ddsrt_getpid(void) return xTaskGetCurrentTaskHandle(); } -char * -ddsrt_getprocessname(void) -{ - return pcTaskGetName(xTaskGetCurrentTaskHandle()); -} diff --git a/src/ddsrt/src/sockets.c b/src/ddsrt/src/sockets.c index 08bfd800..364be9a8 100644 --- a/src/ddsrt/src/sockets.c +++ b/src/ddsrt/src/sockets.c @@ -19,9 +19,6 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/log.h" -#ifdef DDSRT_WITH_FREERTOSTCP -# warning " *** FreeRTOS-Plus-TCP debug include tree " -#else #if !LWIP_SOCKET # if !defined(_WIN32) # include @@ -32,7 +29,6 @@ # endif /* __linux */ # endif /* _WIN32 */ #endif /* LWIP_SOCKET */ -#endif /* FreeRTOSTCP */ #if defined __APPLE__ #include @@ -123,11 +119,7 @@ ddsrt_sockaddr_isunspecified(const struct sockaddr *__restrict sa) return IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*)sa)->sin6_addr); #endif case AF_INET: - #ifdef DDSRT_WITH_FREERTOSTCP - return (((struct sockaddr_in *)sa)->sin_addr == 0); - #else - return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0); - #endif + return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0); } return false; @@ -145,12 +137,8 @@ ddsrt_sockaddr_isloopback(const struct sockaddr *__restrict sa) &((const struct sockaddr_in6 *)sa)->sin6_addr); #endif /* DDSRT_HAVE_IPV6 */ case AF_INET: - #ifdef DDSRT_WITH_FREERTOSTCP - return (((const struct sockaddr_in *)sa)->sin_addr == htonl(INADDR_LOOPBACK)); - #else return (((const struct sockaddr_in *)sa)->sin_addr.s_addr == htonl(INADDR_LOOPBACK)); - #endif } return false; @@ -172,19 +160,11 @@ ddsrt_sockaddr_insamesubnet( switch (sa1->sa_family) { case AF_INET: { - #ifdef DDSRT_WITH_FREERTOSTCP - eq = ((((struct sockaddr_in *)sa1)->sin_addr & - ((struct sockaddr_in *)mask)->sin_addr) - == - (((struct sockaddr_in *)sa2)->sin_addr & - ((struct sockaddr_in *)mask)->sin_addr)); - #else eq = ((((struct sockaddr_in *)sa1)->sin_addr.s_addr & ((struct sockaddr_in *)mask)->sin_addr.s_addr) == (((struct sockaddr_in *)sa2)->sin_addr.s_addr & ((struct sockaddr_in *)mask)->sin_addr.s_addr)); - #endif } break; #if DDSRT_HAVE_IPV6 case AF_INET6: { @@ -216,24 +196,14 @@ ddsrt_sockaddrfromstr(int af, const char *str, void *sa) switch (af) { case AF_INET: { - #ifdef DDSRT_WITH_FREERTOSTCP - in_addr_t buf; - #else struct in_addr buf; - #endif #if DDSRT_HAVE_INET_PTON if (inet_pton(af, str, &buf) != 1) { return DDS_RETCODE_BAD_PARAMETER; } #else - #ifdef DDSRT_WITH_FREERTOSTCP - buf = inet_addr (str); - if (buf == (in_addr_t)(-1)) - #else buf.s_addr = inet_addr (str); - if (buf.s_addr == (in_addr_t)(-1)) - #endif - { + if (buf.s_addr == (in_addr_t)-1) { return DDS_RETCODE_BAD_PARAMETER; } #endif @@ -277,11 +247,7 @@ DDSRT_WARNING_GNUC_OFF(sign-conversion) AF_INET, &((struct sockaddr_in *)sa)->sin_addr, buf, (uint32_t)size); #else { - #ifdef DDSRT_WITH_FREERTOSTCP - in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr); - #else in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); - #endif snprintf(buf,size,"%u.%u.%u.%u",(x>>24),(x>>16)&0xff,(x>>8)&0xff,x&0xff); ptr = buf; } diff --git a/src/ddsrt/src/threads/freertos/threads.c b/src/ddsrt/src/threads/freertos/threads.c index 9f3be999..206d7d62 100644 --- a/src/ddsrt/src/threads/freertos/threads.c +++ b/src/ddsrt/src/threads/freertos/threads.c @@ -183,11 +183,7 @@ static dds_return_t thread_context_acquire(thread_context_t **ctxptr) { dds_return_t rc = DDS_RETCODE_OK; - #ifdef DDSRT_WITH_FREERTOSTCP - thread_context_t *ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context); - #else thread_context_t *ctx = thread_context; - #endif if (ctx == NULL) { /* Dynamically initialize global thread registry (exactly once). */ @@ -203,11 +199,7 @@ thread_context_acquire(thread_context_t **ctxptr) ctx->task = xTaskGetCurrentTaskHandle(); } ddsrt_mutex_unlock(&thread_registry.mutex); - #ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx); - #else thread_context = ctx; - #endif } else { assert(ctx->func != NULL); assert(ctx->stat == THREAD_RUNNING); @@ -334,11 +326,7 @@ thread_start_routine(void *arg) thread because a reference to the thread's context is stored and synchronization is considerably easier if it's handled there. */ -#ifdef DDSRT_WITH_FREERTOSTCP - ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx); -#else thread_context = ctx; -#endif ret = ctx->func(ctx->arg); thread_fini(ctx, ret); /* DO NOT DEREFERENCE THREAD CONTEXT ANYMORE! */ @@ -439,10 +427,6 @@ void ddsrt_thread_init(uint32_t reason) { (void)reason; -#ifdef DDSRT_WITH_FREERTOSTCP - /* init TLS var */ - ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, NULL); -#endif if (thread_context_require() != DDS_RETCODE_OK) { assert(0); } @@ -456,12 +440,7 @@ ddsrt_thread_fini(uint32_t reason) (void)reason; /* NO-OP if no context exists since thread-local storage and cleanup handler references are both stored in the thread context. */ - #ifdef DDSRT_WITH_FREERTOSTCP - ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context); - if ( ctx != NULL) { - #else if ((ctx = thread_context) != NULL) { - #endif assert(ctx->func != &non_local_thread); thread_fini(ctx, 0); } diff --git a/src/ddsrt/src/time.c b/src/ddsrt/src/time.c index 64945fcc..9551f0dd 100644 --- a/src/ddsrt/src/time.c +++ b/src/ddsrt/src/time.c @@ -38,8 +38,6 @@ void dds_sleepfor(dds_duration_t n) } #endif -#ifndef DDSRT_WITH_FREERTOS -#warning " ctime in glib, ignore it for FreeRTOS " size_t ddsrt_ctime(dds_time_t n, char *str, size_t size) { @@ -75,7 +73,6 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size) return ddsrt_strlcpy(str, buf, size); } -#endif static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t) { diff --git a/src/ddsrt/src/time/freertos/time.c b/src/ddsrt/src/time/freertos/time.c index e1e5d5a9..01c367bb 100644 --- a/src/ddsrt/src/time/freertos/time.c +++ b/src/ddsrt/src/time/freertos/time.c @@ -20,9 +20,6 @@ DDS_EXPORT extern inline TickType_t ddsrt_duration_to_ticks_ceil(dds_duration_t dds_time_t dds_time(void) { -#ifdef DDSRT_WITH_FREERTOSTCP - return get_timer_us(0U) * 1000U; -#else struct timespec ts; #if __STDC_VERSION__ >= 201112L @@ -32,7 +29,6 @@ dds_time_t dds_time(void) #endif return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec; -#endif } #define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ) From 864b89be3f784235391db5f22d0dff82b8411594 Mon Sep 17 00:00:00 2001 From: Zhou Shengyong Date: Tue, 11 Apr 2023 12:05:29 +0800 Subject: [PATCH 25/27] [FreeRTOS-Plus-TCP]to support cycloneDDS over FreeRTOS-Plus-TCP IP stack CycloneDDS looks have support on FreeRTOS+LWIP Stack, however lacking FreeRTOS-Plus-TCP Stack support This change managed to add +TCP support * base CycloneDDS version0.9.1 * ddsrt socket / thread ... [Changes] +TCP socket ddsrt header and source sockaddr ifaddr .init_array section log sink multicast/unicast peer define in xml TLS-Thread_Local_Storage from FreeRTOS SW impl instread of toolchain sock_waitset sock fdset sendmsg/recvmsg for UDP dds_align from 0.10.2 FragmentSize for jumbo and normal [Issue] Not Validated [Test Platform] N/A Signed-off-by: Brave Zhou --- .../ddsc/include/dds/ddsc/dds_public_impl.h | 3 + src/core/ddsc/include/dds/export.h | 50 ++ src/core/ddsc/src/dds_builtin.c | 4 + src/core/ddsc/src/dds_domain.c | 25 +- src/core/ddsc/src/dds_init.c | 8 + src/core/ddsc/src/dds_participant.c | 30 + src/core/ddsi/defconfig.c | 9 + .../ddsi/include/dds/ddsi/ddsi_cfgelems.h | 125 ++++- src/core/ddsi/include/dds/ddsi/ddsi_config.h | 4 +- src/core/ddsi/include/dds/ddsi/ddsi_locator.h | 2 +- .../include/dds/ddsi/ddsi_serdata_default.h | 18 + src/core/ddsi/include/dds/ddsi/ddsi_udp.h | 4 + src/core/ddsi/include/dds/ddsi/q_log.h | 3 + src/core/ddsi/include/dds/ddsi/q_thread.h | 4 + src/core/ddsi/src/ddsi_cdrstream.c | 14 +- src/core/ddsi/src/ddsi_ipaddr.c | 12 + src/core/ddsi/src/ddsi_tcp.c | 18 +- src/core/ddsi/src/ddsi_tran.c | 2 + src/core/ddsi/src/ddsi_udp.c | 102 +++- src/core/ddsi/src/ddsi_wraddrset.c | 4 + src/core/ddsi/src/q_addrset.c | 2 + src/core/ddsi/src/q_ddsi_discovery.c | 16 + src/core/ddsi/src/q_entity.c | 8 +- src/core/ddsi/src/q_freelist.c | 32 ++ src/core/ddsi/src/q_gc.c | 4 + src/core/ddsi/src/q_init.c | 54 +- src/core/ddsi/src/q_pcap.c | 10 + src/core/ddsi/src/q_receive.c | 67 ++- src/core/ddsi/src/q_sockwaitset_s.c | 522 ++++++++++++++++++ src/core/ddsi/src/q_thread.c | 36 +- src/core/ddsi/src/q_transmit.c | 14 + src/core/ddsi/src/q_xevent.c | 64 ++- src/core/ddsi/src/q_xmsg.c | 11 +- src/ddsrt/include/dds/config.h.in | 11 + src/ddsrt/include/dds/ddsrt/iovec.h | 11 + src/ddsrt/include/dds/ddsrt/log.h | 31 +- src/ddsrt/include/dds/ddsrt/process.h | 12 + src/ddsrt/include/dds/ddsrt/sockets.h | 18 +- .../dds/ddsrt/sockets/freertos_plus_tcp.h | 245 ++++++++ src/ddsrt/include/dds/ddsrt/sockets/posix.h | 7 + src/ddsrt/include/dds/ddsrt/threads.h | 32 ++ src/ddsrt/src/cdtors.c | 16 + src/ddsrt/src/heap/freertos/heap.c | 1 + src/ddsrt/src/ifaddrs.c | 2 + .../freertos_plus_tcp/ifaddrs_plus_tcp.c | 110 ++++ src/ddsrt/src/log.c | 121 +++- src/ddsrt/src/process/freertos/process.c | 5 + src/ddsrt/src/sockets.c | 38 +- src/ddsrt/src/threads/freertos/threads.c | 21 + src/ddsrt/src/time.c | 3 + src/ddsrt/src/time/freertos/time.c | 4 + 51 files changed, 1908 insertions(+), 61 deletions(-) create mode 100755 src/core/ddsc/include/dds/export.h create mode 100755 src/core/ddsi/src/q_sockwaitset_s.c create mode 100755 src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h create mode 100755 src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c diff --git a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h index ea0e7055..291e5d9c 100644 --- a/src/core/ddsc/include/dds/ddsc/dds_public_impl.h +++ b/src/core/ddsc/include/dds/ddsc/dds_public_impl.h @@ -26,6 +26,9 @@ #include #include "dds/export.h" #include "dds/features.h" +#ifdef DDSRT_WITH_FREERTOSTCP +#include "dds/ddsrt/align.h" +#endif #include "dds/ddsc/dds_public_alloc.h" #include "dds/ddsc/dds_opcodes.h" diff --git a/src/core/ddsc/include/dds/export.h b/src/core/ddsc/include/dds/export.h new file mode 100755 index 00000000..30103d12 --- /dev/null +++ b/src/core/ddsc/include/dds/export.h @@ -0,0 +1,50 @@ + +#ifndef DDS_EXPORT_H +#define DDS_EXPORT_H + +#ifdef DDS_STATIC_DEFINE +# define DDS_EXPORT +# define DDS_NO_EXPORT +#else +# ifndef DDS_EXPORT +# ifdef ddsc_EXPORTS + /* We are building this library */ +# define DDS_EXPORT +# else + /* We are using this library */ +# define DDS_EXPORT +# endif +# endif + +# ifndef DDS_NO_EXPORT +# define DDS_NO_EXPORT +# endif +#endif + +#ifndef DDS_DEPRECATED +# define DDS_DEPRECATED +#endif + +#ifndef DDS_DEPRECATED_EXPORT +# define DDS_DEPRECATED_EXPORT DDS_EXPORT DDS_DEPRECATED +#endif + +#ifndef DDS_DEPRECATED_NO_EXPORT +# define DDS_DEPRECATED_NO_EXPORT DDS_NO_EXPORT DDS_DEPRECATED +#endif + +#if 0 /* DEFINE_NO_DEPRECATED */ +# ifndef DDS_NO_DEPRECATED +# define DDS_NO_DEPRECATED +# endif +#endif + +#ifndef DDS_INLINE_EXPORT +# if __MINGW32__ && (!defined(__clang__) || !defined(ddsc_EXPORTS)) +# define DDS_INLINE_EXPORT +# else +# define DDS_INLINE_EXPORT DDS_EXPORT +# endif +#endif + +#endif /* DDS_EXPORT_H */ diff --git a/src/core/ddsc/src/dds_builtin.c b/src/core/ddsc/src/dds_builtin.c index fd2a31da..43f96adb 100644 --- a/src/core/ddsc/src/dds_builtin.c +++ b/src/core/ddsc/src/dds_builtin.c @@ -374,6 +374,8 @@ void dds__builtin_init (struct dds_domain *dom) { dds_qos_t *qos = dds__create_builtin_qos (); + DDS_LOG(DDS_LC_CONFIG, " dds__builtin_init ..."); + dom->btif.arg = dom; dom->btif.builtintopic_get_tkmap_entry = dds__builtin_get_tkmap_entry; dom->btif.builtintopic_is_builtintopic = dds__builtin_is_builtintopic; @@ -415,6 +417,8 @@ void dds__builtin_init (struct dds_domain *dom) dom->builtintopic_writer_subscriptions = new_local_orphan_writer (&dom->gv, to_entityid (NN_ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_WRITER), DDS_BUILTIN_TOPIC_SUBSCRIPTION_NAME, dom->builtin_reader_type, qos, builtintopic_whc_new (DSBT_READER, gh)); thread_state_asleep (lookup_thread_state ()); + DDS_LOG(DDS_LC_CONFIG, " builtin_topics writer done"); + dds_delete_qos (qos); /* ddsi_sertype_init initializes the refcount to 1 and dds_sertopic_register_locked increments diff --git a/src/core/ddsc/src/dds_domain.c b/src/core/ddsc/src/dds_domain.c index dfb6b802..81afea50 100644 --- a/src/core/ddsc/src/dds_domain.c +++ b/src/core/ddsc/src/dds_domain.c @@ -120,6 +120,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i break; } domain->m_id = domain->gv.config.domainId; + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " domain 0X%08x / 0x%08x config init done \n", domain->m_id, domain_id); if (rtps_config_prep (&domain->gv, domain->cfgst) != 0) { @@ -127,6 +128,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_config; } + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_config_prep done \n"); if (rtps_init (&domain->gv) < 0) { @@ -134,6 +136,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_init; } + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " rtps_init done! \n"); #ifdef DDS_HAS_SHM // if DDS_HAS_SHM is enabled the iceoryx runtime was created in rtps_init and is ready @@ -151,6 +154,7 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domain to configured to do so. */ if (domain->gv.config.liveliness_monitoring) { + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start ... \n"); if (dds_global.threadmon_count++ == 0) { /* FIXME: configure settings */ @@ -169,9 +173,11 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i goto fail_threadmon_start; } } + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " liveliness monitor thread start! \n"); } dds__builtin_init (domain); + DDS_ILOG (DDS_LC_CONFIG, domain->m_id, " dds__builtin_init done! \n"); /* Set additional default participant properties */ @@ -187,10 +193,21 @@ static dds_entity_t dds_domain_init (dds_domain *domain, dds_domainid_t domain_i domh = DDS_RETCODE_ERROR; goto fail_rtps_start; } + DDS_LOG(DDS_LC_CONFIG, " rtps_start done!"); if (domain->gv.config.liveliness_monitoring) ddsi_threadmon_register_domain (dds_global.threadmon, &domain->gv); dds_entity_init_complete (&domain->m_entity); + + #if 0 // def DDSRT_WITH_FREERTOSTCP + /* CAUTION: NEVER open this slice unless in UT itself. */ + sleep(2U); /* wait thread wrapper */ + DDS_LOG(DDS_LC_CONFIG, " @@@@@@@@@@@@@@@@@@ domain init threads dump"); + /* dump all threads created in domain_init */ + //eth_run_cli("ps"); + sleep(1U); + #endif + return domh; fail_rtps_start: @@ -234,6 +251,8 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o if (dom) { + DDS_LOG (DDS_LC_CONFIG, " find dom %p", dom); + if (!implicit) domh = DDS_RETCODE_PRECONDITION_NOT_MET; else @@ -254,18 +273,22 @@ static dds_entity_t dds_domain_create_internal_xml_or_raw (dds_domain **domain_o } else { + DDS_LOG (DDS_LC_CONFIG, " create dom ..."); dom = dds_alloc (sizeof (*dom)); if ((domh = dds_domain_init (dom, id, config, implicit)) < 0) - dds_free (dom); + { dds_free (dom); } else { + DDS_LOG (DDS_LC_CONFIG, " dom created, domh = 0x%x ", domh); ddsrt_mutex_lock (&dom->m_entity.m_mutex); ddsrt_avl_insert (&dds_domaintree_def, &dds_global.m_domains, dom); dds_entity_register_child (&dds_global.m_entity, &dom->m_entity); + DDS_LOG (DDS_LC_CONFIG, " register domain to global done "); if (implicit) { dds_entity_add_ref_locked (&dom->m_entity); dds_handle_repin (&dom->m_entity.m_hdllink); + DDS_LOG (DDS_LC_CONFIG, " dom->m_entity.m_hdllink.hdl = 0x%x ", dom->m_entity.m_hdllink.hdl); } domh = dom->m_entity.m_hdllink.hdl; ddsrt_mutex_unlock (&dom->m_entity.m_mutex); diff --git a/src/core/ddsc/src/dds_init.c b/src/core/ddsc/src/dds_init.c index e4252e02..4c9154cc 100644 --- a/src/core/ddsc/src/dds_init.c +++ b/src/core/ddsc/src/dds_init.c @@ -52,6 +52,10 @@ dds_cyclonedds_entity dds_global; #define CDDS_STATE_STARTING 1u #define CDDS_STATE_READY 2u #define CDDS_STATE_STOPPING 3u + +#ifdef DDSRT_WITH_FREERTOSTCP +#define MAX_THREAD_NUM 32 +#endif static ddsrt_atomic_uint32_t dds_state = DDSRT_ATOMIC_UINT32_INIT (CDDS_STATE_ZERO); static void common_cleanup (void) @@ -112,7 +116,11 @@ dds_return_t dds_init (void) ddsrt_mutex_init (&dds_global.m_mutex); ddsrt_cond_init (&dds_global.m_cond); ddsi_iid_init (); + #ifdef DDSRT_WITH_FREERTOSTCP + thread_states_init (MAX_THREAD_NUM); + #else thread_states_init (128); + #endif if (dds_handle_server_init () != DDS_RETCODE_OK) { diff --git a/src/core/ddsc/src/dds_participant.c b/src/core/ddsc/src/dds_participant.c index 9cba6a57..c9a977ad 100644 --- a/src/core/ddsc/src/dds_participant.c +++ b/src/core/ddsc/src/dds_participant.c @@ -91,6 +91,9 @@ const struct dds_entity_deriver dds_entity_deriver_participant = { .refresh_statistics = dds_entity_deriver_dummy_refresh_statistics }; +#ifdef DDSRT_WITH_FREERTOSTCP +char dds_peer[16] = {0}; +#endif dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_t *qos, const dds_listener_t *listener) { dds_domain *dom; @@ -99,6 +102,29 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ dds_participant * pp; ddsi_plist_t plist; dds_qos_t *new_qos = NULL; + +#ifdef DDSRT_WITH_FREERTOSTCP + /* Make sure DDS instance is initialized. */ + if ((ret = dds_init ()) < 0) + goto err_dds_init; + + char xml[1024]; + memset(xml, 0, sizeof(xml)); + if (inet_addr(dds_peer) == 0) + { + strncpy(dds_peer, "192.168.11.2", sizeof(dds_peer)); + dds_peer[sizeof(dds_peer) - 1] = '\0'; + } + + snprintf(xml, sizeof(xml) - 1, "\ +\ + \ +\ +", dds_peer); + const char *config = xml; + DDS_WARNING(" participant xml [%s] !", xml); + //DDS_WARNING(" participant peer using [%s] !", dds_peer); +#else const char *config = ""; /* Make sure DDS instance is initialized. */ @@ -106,6 +132,8 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ goto err_dds_init; (void) ddsrt_getenv ("CYCLONEDDS_URI", &config); +#endif + if ((ret = dds_domain_create_internal (&dom, domain, true, config)) < 0) goto err_domain_create; @@ -143,6 +171,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ret = DDS_RETCODE_ERROR; goto err_new_participant; } + DDS_INFO(" built-in participant done !"); pp = dds_alloc (sizeof (*pp)); if ((ret = dds_entity_init (&pp->m_entity, &dom->m_entity, DDS_KIND_PARTICIPANT, false, true, new_qos, listener, DDS_PARTICIPANT_STATUS_MASK)) < 0) @@ -160,6 +189,7 @@ dds_entity_t dds_create_participant (const dds_domainid_t domain, const dds_qos_ ddsrt_mutex_unlock (&dom->m_entity.m_mutex); dds_entity_init_complete (&pp->m_entity); + /* drop temporary extra ref to domain, dds_init */ dds_entity_unpin_and_drop_ref (&dom->m_entity); dds_entity_unpin_and_drop_ref (&dds_global.m_entity); diff --git a/src/core/ddsi/defconfig.c b/src/core/ddsi/defconfig.c index beae4e51..1f76f41d 100644 --- a/src/core/ddsi/defconfig.c +++ b/src/core/ddsi/defconfig.c @@ -14,7 +14,11 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->externalMaskString = "0.0.0.0"; cfg->allowMulticast = UINT32_C (2147483648); cfg->multicast_ttl = INT32_C (32); + #ifdef DDSRT_WITH_FREERTOSTCP + cfg->transport_selector = INT32_C (DDSI_TRANS_UDP); + #else cfg->transport_selector = INT32_C (1); + #endif cfg->enableMulticastLoopback = INT32_C (1); cfg->max_msg_size = UINT32_C (14720); cfg->max_rexmit_msg_size = UINT32_C (1456); @@ -58,8 +62,13 @@ void ddsi_config_init_default (struct ddsi_config *cfg) cfg->const_hb_intv_min = INT64_C (5000000); cfg->const_hb_intv_sched_min = INT64_C (20000000); cfg->const_hb_intv_sched_max = INT64_C (8000000000); + #ifdef DDSRT_WITH_FREERTOSTCP + cfg->max_queued_rexmit_bytes = UINT32_C (33554432); /* 524288->32M: > 4K framesize */ + cfg->max_queued_rexmit_msgs = UINT32_C (18000); /* 200->20480: > 4K framesize / fragmen_size */ + #else cfg->max_queued_rexmit_bytes = UINT32_C (524288); cfg->max_queued_rexmit_msgs = UINT32_C (200); + #endif cfg->writer_linger_duration = INT64_C (1000000000); cfg->socket_rcvbuf_size.min.isdefault = 1; cfg->socket_rcvbuf_size.max.isdefault = 1; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h index 5b5b3db8..d1e3e867 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_cfgelems.h @@ -15,6 +15,10 @@ #include "dds/features.h" +#ifdef DDSRT_WITH_FREERTOSTCP +#warning " debug rtos tcp stack including " +#include "dds/ddsrt/sockets/freertos_plus_tcp.h" +#endif static struct cfgelem network_interface_attributes[] = { STRING("autodetermine", NULL, 1, "false", @@ -156,7 +160,16 @@ static struct cfgelem general_cfgelems[] = { "translated to an internal address by replacing the network portion of " "the external address with the corresponding portion of the preferred " "network interface address. This option is IPv4-only.

")), - LIST("AllowMulticast", NULL, 1, "default", + LIST("AllowMulticast", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP +/* + * he "spdp" leaves multicast enabled for initial discovery only + * https://github.com/ros2/rmw_cyclonedds/issues/251 + */ + "spdp", +#else + "default", +#endif MEMBER(allowMulticast), FUNCTIONS(0, uf_allow_multicast, 0, pf_allow_multicast), DESCRIPTION( @@ -212,19 +225,34 @@ static struct cfgelem general_cfgelems[] = { "packets, to bypass the local routing tables. This is generally useful " "only when the routing tables cannot be trusted, which is highly " "unusual.

")), - ENUM("UseIPv6", NULL, 1, "default", + ENUM("UseIPv6", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + "false", +#else + "default", +#endif MEMBER(compat_use_ipv6), FUNCTIONS(0, uf_boolean_default, 0, pf_nop), DESCRIPTION("

Deprecated (use Transport instead)

"), VALUES("false","true","default")), - ENUM("Transport", NULL, 1, "default", + ENUM("Transport", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + "udp", +#else + "default", +#endif MEMBER(transport_selector), FUNCTIONS(0, uf_transport_selector, 0, pf_transport_selector), DESCRIPTION( "

This element allows selecting the transport to be used (udp, udp6, " "tcp, tcp6, raweth)

"), VALUES("default","udp","udp6","tcp","tcp6","raweth")), - BOOL("EnableMulticastLoopback", NULL, 1, "true", + BOOL("EnableMulticastLoopback", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + "false", +#else + "true", +#endif MEMBER(enableMulticastLoopback), FUNCTIONS(0, uf_boolean, 0, pf_boolean), DESCRIPTION( @@ -234,7 +262,21 @@ static struct cfgelem general_cfgelems[] = { "communications, but if a node runs only a single Cyclone DDS service " "and does not host any other DDSI-capable programs, it should be set " "to \"false\" for improved performance.

")), - STRING("MaxMessageSize", NULL, 1, "14720 B", + + STRING("MaxMessageSize", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP +/* ddsi_config.max_msg_size and fragment_size will decide how many fragments in single submsg. + * keep this below MTU if STACK not support IP fragments + */ + #ifdef EQOS_TX_JUMBO_ENABLED + "8972 B", + #else + "1456 B", + #endif + +#else + "14720 B", +#endif MEMBER(max_msg_size), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -246,7 +288,16 @@ static struct cfgelem general_cfgelems[] = { "

On some networks it may be necessary to set this item to keep the " "packetsize below the MTU to prevent IP fragmentation.

"), UNIT("memsize")), - STRING("MaxRexmitMessageSize", NULL, 1, "1456 B", + STRING("MaxRexmitMessageSize", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + #ifdef EQOS_TX_JUMBO_ENABLED + "8972 B", + #else + "1464 B", + #endif +#else + "1456 B", +#endif MEMBER(max_rexmit_msg_size), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -258,7 +309,17 @@ static struct cfgelem general_cfgelems[] = { "

On some networks it may be necessary to set this item to keep the " "packetsize below the MTU to prevent IP fragmentation.

"), UNIT("memsize")), - STRING("FragmentSize", NULL, 1, "1344 B", + STRING("FragmentSize", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + #ifdef EQOS_TX_JUMBO_ENABLED + /* ipMAX_UDP_PAYLOAD_LENGTH(8972) > $FragSize + 20(RTPS_HDR) + 12(INFO_TS) + 36(DATA_HDR) + 28(HEART_BEAT) */ + "8864 B", + #else + "1400 B", + #endif +#else + "1344 B", +#endif MEMBER(fragment_size), FUNCTIONS(0, uf_memsize16, 0, pf_memsize16), DESCRIPTION( @@ -938,7 +999,15 @@ static struct cfgelem internal_watermarks_cfgelems[] = { "expressed in bytes. A suspended writer resumes transmitting when its " "Cyclone DDS WHC shrinks to this size.

"), UNIT("memsize")), - STRING("WhcHigh", NULL, 1, "500 kB", + STRING("WhcHigh", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + /* 512K->24M: > 4K RGB888 framesize + * ALSO to be sure seqeunce limitation defined in idl + */ + "24576 kB", +#else + "500 kB", +#endif MEMBER(whc_highwater_mark), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -1282,7 +1351,16 @@ static struct cfgelem internal_cfgelems[] = { "

This element allows configuring the base interval for sending " "writer heartbeats and the bounds within which it can vary.

"), UNIT("duration_inf")), - STRING("MaxQueuedRexmitBytes", NULL, 1, "512 kB", + + STRING("MaxQueuedRexmitBytes", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + /* 512K->24M: > 4K RGB888 framesize + * ALSO to be sure seqeunce limitation defined in idl + */ + "24576 kB", +#else + "512 kB", +#endif MEMBER(max_queued_rexmit_bytes), FUNCTIONS(0, uf_memsize, 0, pf_memsize), DESCRIPTION( @@ -1292,7 +1370,14 @@ static struct cfgelem internal_cfgelems[] = { "NackDelay * AuxiliaryBandwidthLimit. It must be large enough to " "contain the largest sample that may need to be retransmitted.

"), UNIT("memsize")), - INT("MaxQueuedRexmitMessages", NULL, 1, "200", + + INT("MaxQueuedRexmitMessages", NULL, 1, +#ifdef DDSRT_WITH_FREERTOSTCP + /* 200->20480: > 4K framesize / fragmen_size */ + "20480", +#else + "200", +#endif MEMBER(max_queued_rexmit_msgs), FUNCTIONS(0, uf_uint, 0, pf_uint), DESCRIPTION( @@ -1804,7 +1889,11 @@ static struct cfgelem shmem_cfgelems[] = { #endif static struct cfgelem discovery_peer_cfgattrs[] = { +#ifdef DDSRT_WITH_FREERTOSTCP + STRING("Address", NULL, 1, "192.168.11.3:7400", // Not working, use XML string +#else STRING("Address", NULL, 1, NULL, +#endif MEMBEROF(ddsi_config_peer_listelem, peer), FUNCTIONS(0, uf_ipv4, ff_free, pf_string), DESCRIPTION( @@ -1829,6 +1918,16 @@ static struct cfgelem discovery_peers_group_cfgelems[] = { }; static struct cfgelem discovery_peers_cfgelems[] = { +#ifdef DDSRT_WITH_FREERTOSTCP + GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, // Not working, use XML string + MEMBER(peers), + FUNCTIONS(if_peer, 0, 0, 0), + DESCRIPTION( + "

This element specifies the base port number (refer to the DDSI 2.1 " + "specification, section 9.6.1, constant PB).

" + )), + +#else GROUP("Peer", NULL, discovery_peer_cfgattrs, INT_MAX, MEMBER(peers), FUNCTIONS(if_peer, 0, 0, 0), @@ -1845,6 +1944,7 @@ static struct cfgelem discovery_peers_cfgelems[] = { ), MAXIMUM(0)), /* Group element can occur more than once, but 1 is required because of the way its processed (for now) */ +#endif END_MARKER }; @@ -1900,7 +2000,12 @@ static struct cfgelem discovery_cfgelems[] = { "and fixing the participant index has no adverse effects, it is " "recommended that the second be option be used.

" )), +#ifdef DDSRT_WITH_FREERTOSTCP + /* polling port number to dest peer */ + INT("MaxAutoParticipantIndex", NULL, 1, "2", /* 9 */ +#else INT("MaxAutoParticipantIndex", NULL, 1, "9", +#endif MEMBER(maxAutoParticipantIndex), FUNCTIONS(0, uf_natint, 0, pf_int), DESCRIPTION( diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_config.h b/src/core/ddsi/include/dds/ddsi/ddsi_config.h index 6862e1cc..4036b50a 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_config.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_config.h @@ -310,8 +310,8 @@ struct ddsi_config unsigned delivery_queue_maxsamples; - uint16_t fragment_size; - uint32_t max_msg_size; + uint16_t fragment_size; // default: 1344 + uint32_t max_msg_size; /* default: 14720 how many fragment in single submsg */ uint32_t max_rexmit_msg_size; uint32_t init_transmit_extra_pct; uint32_t max_rexmit_burst_size; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h index 0d6d2631..584a06da 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_locator.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_locator.h @@ -23,7 +23,7 @@ struct ddsi_tran_conn; /* address field in locator maintained in network byte order, the rest in host */ typedef struct { - int32_t kind; + int32_t kind; // NN_LOCATOR_KIND_UDPv4 uint32_t port; unsigned char address[16]; } ddsi_locator_t; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h index b12de943..3cf62747 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_serdata_default.h @@ -98,6 +98,24 @@ struct ddsi_serdata_default_unpadded { #define DDSI_SERDATA_DEFAULT_PAD(n) (n) #endif + +#if 0 +/* un-fold to easy to track in SI */ +struct ddsi_serdata_default { + struct ddsi_serdata c; + uint32_t pos; + uint32_t size; + DDSI_SERDATA_DEFAULT_DEBUG_FIELDS + struct ddsi_serdata_default_key key; + struct serdatapool *serpool; + struct ddsi_serdata_default *next; /* in pool->freelist */ + char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))]; + struct CDRHeader hdr; + char data[]; +}; +#endif + + struct ddsi_serdata_default { DDSI_SERDATA_DEFAULT_PREPAD; char pad[DDSI_SERDATA_DEFAULT_PAD (8 - (offsetof (struct ddsi_serdata_default_unpadded, data) % 8))]; diff --git a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h index 2d36180e..14ea1252 100644 --- a/src/core/ddsi/include/dds/ddsi/ddsi_udp.h +++ b/src/core/ddsi/include/dds/ddsi/ddsi_udp.h @@ -18,7 +18,11 @@ extern "C" { typedef struct nn_udpv4mcgen_address { /* base IPv4 MC address is ipv4, host bits are bits base .. base+count-1, this machine is bit idx */ +#ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t ipv4; +#else struct in_addr ipv4; +#endif uint8_t base; uint8_t count; uint8_t idx; /* must be last: then sorting will put them consecutively */ diff --git a/src/core/ddsi/include/dds/ddsi/q_log.h b/src/core/ddsi/include/dds/ddsi/q_log.h index 64d3c0f8..cbb9fb03 100644 --- a/src/core/ddsi/include/dds/ddsi/q_log.h +++ b/src/core/ddsi/include/dds/ddsi/q_log.h @@ -24,6 +24,9 @@ extern "C" { #define GVTRACE(...) DDS_CTRACE (&gv->logconfig, __VA_ARGS__) #define GVLOG(cat, ...) DDS_CLOG ((cat), &gv->logconfig, __VA_ARGS__) +#ifdef DDSRT_WITH_FREERTOSTCP +#define GVINFO(...) DDS_CLOG (DDS_LC_INFO, &gv->logconfig, __VA_ARGS__) +#endif #define GVWARNING(...) DDS_CLOG (DDS_LC_WARNING, &gv->logconfig, __VA_ARGS__) #define GVERROR(...) DDS_CLOG (DDS_LC_ERROR, &gv->logconfig, __VA_ARGS__) diff --git a/src/core/ddsi/include/dds/ddsi/q_thread.h b/src/core/ddsi/include/dds/ddsi/q_thread.h index 5d84c11d..fd382ea9 100644 --- a/src/core/ddsi/include/dds/ddsi/q_thread.h +++ b/src/core/ddsi/include/dds/ddsi/q_thread.h @@ -132,7 +132,11 @@ DDS_EXPORT dds_return_t join_thread (struct thread_state1 *ts1); DDS_EXPORT void log_stack_traces (const struct ddsrt_log_cfg *logcfg, const struct ddsi_domaingv *gv); DDS_INLINE_EXPORT inline struct thread_state1 *lookup_thread_state (void) { +#ifdef DDSRT_WITH_FREERTOSTCP + struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); +#else struct thread_state1 *ts1 = tsd_thread_state; +#endif if (ts1) return ts1; else diff --git a/src/core/ddsi/src/ddsi_cdrstream.c b/src/core/ddsi/src/ddsi_cdrstream.c index 084a627b..5e485c49 100644 --- a/src/core/ddsi/src/ddsi_cdrstream.c +++ b/src/core/ddsi/src/ddsi_cdrstream.c @@ -861,12 +861,12 @@ static char *dds_stream_reuse_string_bound (dds_istream_t * __restrict is, char so this check is superfluous, but perhaps rejecting such a sample is the wrong thing to do */ if (!alloc) - assert (str != NULL); + { assert (str != NULL); } else if (str == NULL) - str = dds_alloc (size); + { str = dds_alloc (size); } memcpy (str, src, length > size ? size : length); if (length > size) - str[size - 1] = '\0'; + { str[size - 1] = '\0'; } is->m_index += length; return str; } @@ -3821,7 +3821,11 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd case DDS_OP_VAL_4BY: { const union { int32_t s; uint32_t u; float f; } x = { .u = dds_is_get4 (is) }; if (flags & DDS_OP_FLAG_FP) + #ifdef DDSRT_WITH_FREERTOSTCP + return prtf (buf, bufsize, "%f", x.f); + #else return prtf (buf, bufsize, "%g", x.f); + #endif else if (flags & DDS_OP_FLAG_SGN) return prtf (buf, bufsize, "%"PRId32, x.s); else @@ -3830,7 +3834,11 @@ static bool prtf_simple (char * __restrict *buf, size_t * __restrict bufsize, dd case DDS_OP_VAL_8BY: { const union { int64_t s; uint64_t u; double f; } x = { .u = dds_is_get8 (is) }; if (flags & DDS_OP_FLAG_FP) + #ifdef DDSRT_WITH_FREERTOSTCP + return prtf (buf, bufsize, "%f", x.f); + #else return prtf (buf, bufsize, "%g", x.f); + #endif else if (flags & DDS_OP_FLAG_SGN) return prtf (buf, bufsize, "%"PRId64, x.s); else diff --git a/src/core/ddsi/src/ddsi_ipaddr.c b/src/core/ddsi/src/ddsi_ipaddr.c index 5d286ff3..eb086360 100644 --- a/src/core/ddsi/src/ddsi_ipaddr.c +++ b/src/core/ddsi/src/ddsi_ipaddr.c @@ -251,7 +251,11 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_ { const struct sockaddr_in *x = (const struct sockaddr_in *) src; assert (kind == NN_LOCATOR_KIND_UDPv4 || kind == NN_LOCATOR_KIND_TCPv4); + #ifdef DDSRT_WITH_FREERTOSTCP + if (x->sin_addr == htonl (INADDR_ANY)) + #else if (x->sin_addr.s_addr == htonl (INADDR_ANY)) + #endif { dst->kind = NN_LOCATOR_KIND_INVALID; dst->port = NN_LOCATOR_PORT_INVALID; @@ -261,7 +265,11 @@ void ddsi_ipaddr_to_loc (ddsi_locator_t *dst, const struct sockaddr *src, int32_ { dst->port = (x->sin_port == 0) ? NN_LOCATOR_PORT_INVALID : ntohs (x->sin_port); memset (dst->address, 0, 12); + #ifdef DDSRT_WITH_FREERTOSTCP + memcpy (dst->address + 12, &x->sin_addr, 4); + #else memcpy (dst->address + 12, &x->sin_addr.s_addr, 4); + #endif } break; } @@ -310,7 +318,11 @@ void ddsi_ipaddr_from_loc (struct sockaddr_storage *dst, const ddsi_locator_t *s struct sockaddr_in *x = (struct sockaddr_in *) dst; x->sin_family = AF_INET; x->sin_port = (src->port == NN_LOCATOR_PORT_INVALID) ? 0 : htons ((unsigned short) src->port); + #ifdef DDSRT_WITH_FREERTOSTCP + memcpy (&x->sin_addr, src->address + 12, 4); + #else memcpy (&x->sin_addr.s_addr, src->address + 12, 4); + #endif break; } #if DDSRT_HAVE_IPV6 diff --git a/src/core/ddsi/src/ddsi_tcp.c b/src/core/ddsi/src/ddsi_tcp.c index 5dd0c4f4..cb8328de 100644 --- a/src/core/ddsi/src/ddsi_tcp.c +++ b/src/core/ddsi/src/ddsi_tcp.c @@ -188,7 +188,11 @@ static dds_return_t ddsi_tcp_sock_new (struct ddsi_tran_factory_tcp * const fact { case NN_LOCATOR_KIND_TCPv4: socketname.a4.sin_family = AF_INET; + #ifdef DDSRT_WITH_FREERTOSTCP + socketname.a4.sin_addr = htonl (INADDR_ANY); + #else socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); + #endif socketname.a4.sin_port = htons (port); break; #if DDSRT_HAVE_IPV6 @@ -459,8 +463,13 @@ static bool ddsi_tcp_select (struct ddsi_domaingv const * const gv, ddsrt_socket static int32_t addrfam_to_locator_kind (int af) { +#if DDSRT_HAVE_IPV6 assert (af == AF_INET || af == AF_INET6); return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_TCPv6; +#else + assert (af == AF_INET); + return (af == AF_INET) ? NN_LOCATOR_KIND_TCPv4 : NN_LOCATOR_KIND_INVALID; +#endif } static ssize_t ddsi_tcp_conn_read (ddsi_tran_conn_t conn, unsigned char *buf, size_t len, bool allow_spurious, ddsi_locator_t *srcloc) @@ -1072,8 +1081,13 @@ static void ddsi_tcp_unblock_listener (ddsi_tran_listener_t listener) switch (addr.a.sa_family) { case AF_INET: - if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY)) - addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + #ifdef DDSRT_WITH_FREERTOSTCP + if (addr.a4.sin_addr == htonl (INADDR_ANY)) + { addr.a4.sin_addr = htonl (INADDR_LOOPBACK); } + #else + if (addr.a4.sin_addr.s_addr == htonl (INADDR_ANY)) + { addr.a4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); } + #endif break; #if DDSRT_HAVE_IPV6 case AF_INET6: diff --git a/src/core/ddsi/src/ddsi_tran.c b/src/core/ddsi/src/ddsi_tran.c index be1ed3d7..6f5411bd 100644 --- a/src/core/ddsi/src/ddsi_tran.c +++ b/src/core/ddsi/src/ddsi_tran.c @@ -134,7 +134,9 @@ void ddsi_conn_free (ddsi_tran_conn_t conn) for (uint32_t i = 0; i < conn->m_base.gv->n_recv_threads; i++) { if (!conn->m_base.gv->recv_threads[i].ts) + { assert (!ddsrt_atomic_ld32 (&conn->m_base.gv->rtps_keepgoing)); + } else { switch (conn->m_base.gv->recv_threads[i].arg.mode) diff --git a/src/core/ddsi/src/ddsi_udp.c b/src/core/ddsi/src/ddsi_udp.c index 26c59e9e..2964bd5d 100644 --- a/src/core/ddsi/src/ddsi_udp.c +++ b/src/core/ddsi/src/ddsi_udp.c @@ -88,6 +88,19 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu msghdr.msg_controllen = 0; #endif +#ifdef DDSRT_WITH_FREERTOSTCP +{ + if (conn->m_base.m_base.m_port == 7410) + { + GVTRACE(" @@@@@@ waitset UDP RX on port %u ... ", conn->m_base.m_base.m_port); + } + if (conn->m_base.m_base.m_port == 7411) + { + GVTRACE(" @@@@@@ uc UDP RX on port %u ... ", conn->m_base.m_base.m_port); + } +} +#endif + do { rc = ddsrt_recvmsg (conn->m_sock, &msghdr, 0, &ret); } while (rc == DDS_RETCODE_INTERRUPTED); @@ -95,7 +108,9 @@ static ssize_t ddsi_udp_conn_read (ddsi_tran_conn_t conn_cmn, unsigned char * bu if (ret > 0) { if (srcloc) - addr_to_loc (conn->m_base.m_factory, srcloc, &src); + { + addr_to_loc (conn->m_base.m_factory, srcloc, &src); + } if (gv->pcap_fp) { @@ -153,6 +168,13 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato #if defined(__sun) && !defined(_XPG4_2) msg.msg_accrights = NULL; msg.msg_accrightslen = 0; +#elif defined DDSRT_WITH_FREERTOSTCP /* got whole payload sz for trans */ + msg.msg_control = NULL; + msg.msg_controllen = 0U; + for (int ii = 0; ii < niov; ii++) + { + msg.msg_controllen += iov[ii].iov_len; + } #else msg.msg_control = NULL; msg.msg_controllen = 0; @@ -163,6 +185,7 @@ static ssize_t ddsi_udp_conn_write (ddsi_tran_conn_t conn_cmn, const ddsi_locato DDSRT_UNUSED_ARG (flags); #endif #if MSG_NOSIGNAL && !LWIP_SOCKET +#error sendflags |= MSG_NOSIGNAL; #endif do { @@ -266,7 +289,13 @@ static dds_return_t set_dont_route (struct ddsi_domaingv const * const gv, ddsrt return rc; } +#ifdef DDSRT_WITH_FREERTOSTCP +static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, + ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, + const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size) +#else static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, int32_t socket_option, const char *socket_option_name, const char *name, const struct ddsi_config_socket_buf_size *config, uint32_t default_min_size) +#endif { // if (min, max)= and initbuf= then request= and result= // (def, def) < defmin defmin whatever it is @@ -275,9 +304,14 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd // (M, N=M) anything N error if < M // defmin = 1MB for receive buffer, 0B for send buffer + +#ifdef DDSRT_WITH_FREERTOSTCP + const bool always_set_size = true; +#else const bool always_set_size = // whether to call setsockopt unconditionally ((config->min.isdefault && !config->max.isdefault) || (!config->min.isdefault && !config->max.isdefault && config->max.value >= config->min.value)); +#endif const uint32_t socket_min_buf_size = // error if it ends up below this !config->min.isdefault ? config->min.value : 0; const uint32_t socket_req_buf_size = // size to request @@ -289,7 +323,13 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd socklen_t optlen = (socklen_t) sizeof (actsize); dds_return_t rc; +#ifdef DDSRT_WITH_FREERTOSTCP +#warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..." + rc = DDS_RETCODE_OK; + actsize = socket_req_buf_size + 1U; /* stub getsockopt a different value */ +#else rc = ddsrt_getsockopt (sock, SOL_SOCKET, socket_option, &actsize, &optlen); +#endif if (rc == DDS_RETCODE_BAD_PARAMETER) { /* not all stacks support getting/setting RCVBUF */ @@ -304,6 +344,13 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd if (always_set_size || actsize < socket_req_buf_size) { + #ifdef DDSRT_WITH_FREERTOSTCP + rc = ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize)); + + #warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..." + actsize = socket_req_buf_size; + + #else (void) ddsrt_setsockopt (sock, SOL_SOCKET, socket_option, &socket_req_buf_size, sizeof (actsize)); /* We don't check the return code from setsockopt, because some O/Ss tend @@ -316,11 +363,15 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd } if (actsize >= socket_req_buf_size) - GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize); + { + GVLOG (DDS_LC_CONFIG, "socket %s buffer size set to %"PRIu32" bytes\n", name, actsize); + } else if (actsize >= socket_min_buf_size) - GVLOG (DDS_LC_CONFIG, + { + GVLOG (DDS_LC_CONFIG, "failed to increase socket %s buffer size to %"PRIu32" bytes, continuing with %"PRIu32" bytes\n", name, socket_req_buf_size, actsize); + } else { /* If the configuration states it must be >= X, then error out if the @@ -330,9 +381,10 @@ static dds_return_t set_socket_buffer (struct ddsi_domaingv const * const gv, dd name, socket_min_buf_size, actsize); rc = DDS_RETCODE_NOT_ENOUGH_SPACE; } + #endif } - return (rc < 0) ? rc : (actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize; + return (rc < 0) ? rc : ((actsize > (uint32_t) INT32_MAX) ? INT32_MAX : (int32_t) actsize); } static dds_return_t set_rcvbuf (struct ddsi_domaingv const * const gv, ddsrt_socket_t sock, const struct ddsi_config_socket_buf_size *config) @@ -374,6 +426,7 @@ static dds_return_t set_mc_options_transmit_ipv6 (struct ddsi_domaingv const * c static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const * const gv, struct nn_interface const * const intf, ddsrt_socket_t sock) { +#ifndef DDSRT_WITH_FREERTOSTCP #if (defined(__linux) || defined(__APPLE__)) && !LWIP_SOCKET if (gv->config.use_multicast_if_mreqn) { @@ -390,6 +443,7 @@ static dds_return_t set_mc_options_transmit_ipv4_if (struct ddsi_domaingv const } #else (void) gv; +#endif #endif return ddsrt_setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, intf->loc.address + 12, 4); } @@ -466,7 +520,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ { case NN_LOCATOR_KIND_UDPv4: if (bind_to_any) - socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); + #ifdef DDSRT_WITH_FREERTOSTCP + { socketname.a4.sin_addr = htonl (INADDR_ANY); } + #else + { socketname.a4.sin_addr.s_addr = htonl (INADDR_ANY); } + #endif break; #if DDSRT_HAVE_IPV6 case NN_LOCATOR_KIND_UDPv6: @@ -509,11 +567,15 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ break; } while (!ddsrt_atomic_cas32 (&fact->receive_buf_size, old, (uint32_t) rc)); } + GVLOG (DDS_LC_CONFIG, " set_rcvbuf done\n"); if (set_sndbuf (gv, sock, &gv->config.socket_sndbuf_size) < 0) goto fail_w_socket; + GVLOG (DDS_LC_CONFIG, " set_sndbuf done\n"); + if (gv->config.dontRoute && set_dont_route (gv, sock, ipv6) != DDS_RETCODE_OK) goto fail_w_socket; + GVLOG (DDS_LC_CONFIG, " set_dont_route done\n"); if ((rc = ddsrt_bind (sock, &socketname.a, ddsrt_sockaddr_get_size (&socketname.a))) != DDS_RETCODE_OK) { @@ -531,6 +593,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ (rc == DDS_RETCODE_PRECONDITION_NOT_MET) ? "address in use" : dds_strretcode (rc)); goto fail_w_socket; } + GVLOG (DDS_LC_CONFIG, " ddsrt_bind to port %u done \n", get_socket_port (gv, sock)); if (set_mc_xmit_options) { @@ -538,6 +601,7 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ if (rc != DDS_RETCODE_OK) goto fail_w_socket; } + GVLOG (DDS_LC_CONFIG, " set_mc_options_transmit %d done\n", set_mc_xmit_options); #ifdef DDS_HAS_NETWORK_CHANNELS if (qos->m_diffserv != 0 && fact->m_kind == NN_LOCATOR_KIND_UDPv4) @@ -571,7 +635,11 @@ static dds_return_t ddsi_udp_create_conn (ddsi_tran_conn_t *conn_out, ddsi_tran_ conn->m_base.m_disable_multiplexing_fn = ddsi_udp_disable_multiplexing; conn->m_base.m_locator_fn = ddsi_udp_conn_locator; +#ifdef DDSRT_WITH_FREERTOSTCP + GVLOG (DDS_LC_CONFIG, "ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port); +#else GVTRACE ("ddsi_udp_create_conn %s socket %"PRIdSOCK" port %"PRIu32"\n", purpose_str, conn->m_sock, conn->m_base.m_base.m_port); +#endif *conn_out = &conn->m_base; return DDS_RETCODE_OK; @@ -605,9 +673,13 @@ static int joinleave_asm_mcgroup (ddsrt_socket_t socket, int join, const ddsi_lo struct ip_mreq mreq; mreq.imr_multiaddr = mcip.a4.sin_addr; if (interf) - memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); + { memcpy (&mreq.imr_interface, interf->loc.address + 12, sizeof (mreq.imr_interface)); } else - mreq.imr_interface.s_addr = htonl (INADDR_ANY); + #ifdef DDSRT_WITH_FREERTOSTCP + { mreq.imr_interface = htonl (INADDR_ANY); } + #else + { mreq.imr_interface.s_addr = htonl (INADDR_ANY); } + #endif rc = ddsrt_setsockopt (socket, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof (mreq)); } return (rc == DDS_RETCODE_OK) ? 0 : -1; @@ -714,15 +786,25 @@ static int ddsi_udp_is_mcaddr (const struct ddsi_tran_factory *tran, const ddsi_ switch (loc->kind) { case NN_LOCATOR_KIND_UDPv4: { +#ifdef DDSRT_WITH_FREERTOSTCP + const in_addr_t *ipv4 = (const in_addr_t *) (loc->address + 12); + DDSRT_WARNING_GNUC_OFF(sign-conversion) + return IN_MULTICAST (ntohl (*ipv4)); +#else const struct in_addr *ipv4 = (const struct in_addr *) (loc->address + 12); DDSRT_WARNING_GNUC_OFF(sign-conversion) return IN_MULTICAST (ntohl (ipv4->s_addr)); +#endif DDSRT_WARNING_GNUC_ON(sign-conversion) } case NN_LOCATOR_KIND_UDPv4MCGEN: { const nn_udpv4mcgen_address_t *mcgen = (const nn_udpv4mcgen_address_t *) loc->address; DDSRT_WARNING_GNUC_OFF(sign-conversion) + #ifdef DDSRT_WITH_FREERTOSTCP + return IN_MULTICAST (ntohl (mcgen->ipv4)); + #else return IN_MULTICAST (ntohl (mcgen->ipv4.s_addr)); + #endif DDSRT_WARNING_GNUC_ON(sign-conversion) } #if DDSRT_HAVE_IPV6 @@ -832,7 +914,11 @@ static char *ddsi_udp_locator_to_string (char *dst, size_t sizeof_dst, const dds memcpy (&mcgen, loc->address, sizeof (mcgen)); memset (&src, 0, sizeof (src)); src.sin_family = AF_INET; + #ifdef DDSRT_WITH_FREERTOSTCP + memcpy (&src.sin_addr, &mcgen.ipv4, 4); + #else memcpy (&src.sin_addr.s_addr, &mcgen.ipv4, 4); + #endif ddsrt_sockaddrtostr ((const struct sockaddr *) &src, dst, sizeof_dst); pos = strlen (dst); assert (pos <= sizeof_dst); @@ -876,9 +962,11 @@ static int ddsi_udp_locator_from_sockaddr (const struct ddsi_tran_factory *tran_ if (tran->m_kind != NN_LOCATOR_KIND_UDPv4) return -1; break; +#if DDSRT_HAVE_IPV6 case AF_INET6: if (tran->m_kind != NN_LOCATOR_KIND_UDPv6) return -1; +#endif break; } ddsi_ipaddr_to_loc (loc, sockaddr, tran->m_kind); diff --git a/src/core/ddsi/src/ddsi_wraddrset.c b/src/core/ddsi/src/ddsi_wraddrset.c index d3430d38..dcca2a15 100644 --- a/src/core/ddsi/src/ddsi_wraddrset.c +++ b/src/core/ddsi/src/ddsi_wraddrset.c @@ -691,7 +691,11 @@ static void wras_add_locator (const struct ddsi_domaingv *gv, struct addrset *ne memcpy (&l1, tmploc.c.address, sizeof (l1)); tmploc.c.kind = NN_LOCATOR_KIND_UDPv4; memset (tmploc.c.address, 0, 12); + #ifdef DDSRT_WITH_FREERTOSTCP + iph = ntohl (l1.ipv4); + #else iph = ntohl (l1.ipv4.s_addr); + #endif for (i = 0; i < nreaders; i++) { cover_info_t ci = cover_get (covered, i, locidx); diff --git a/src/core/ddsi/src/q_addrset.c b/src/core/ddsi/src/q_addrset.c index 25759c80..5e1095e1 100644 --- a/src/core/ddsi/src/q_addrset.c +++ b/src/core/ddsi/src/q_addrset.c @@ -96,6 +96,8 @@ int add_addresses_to_addrset (const struct ddsi_domaingv *gv, struct addrset *as DDSRT_WARNING_MSVC_OFF(4996); char *addrs_copy, *cursor, *a; int retval = -1; + + GVLOG (DDS_LC_CONFIG, " add addrs [%s] @@@@@@@@@@@@", addrs); addrs_copy = ddsrt_strdup (addrs); cursor = addrs_copy; while ((a = ddsrt_strsep (&cursor, ",")) != NULL) diff --git a/src/core/ddsi/src/q_ddsi_discovery.c b/src/core/ddsi/src/q_ddsi_discovery.c index 2e60c34b..c293de6c 100644 --- a/src/core/ddsi/src/q_ddsi_discovery.c +++ b/src/core/ddsi/src/q_ddsi_discovery.c @@ -223,6 +223,20 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv external IP address, this locator will be translated into one in the same subnet as our own local ip and selected. */ assert (gv->n_interfaces == 1); // gv->extmask: the hack is only supported if limited to a single interface + #ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t tmp4 = *((in_addr_t *) (loc.address + 12)); + const in_addr_t ownip = *((in_addr_t *) (gv->interfaces[0].loc.address + 12)); + const in_addr_t extip = *((in_addr_t *) (gv->interfaces[0].extloc.address + 12)); + const in_addr_t extmask = *((in_addr_t *) (gv->extmask.address + 12)); + + if ((tmp4 & extmask) == (extip & extmask)) + { + /* translate network part of the IP address from the external + one to the internal one */ + tmp4 = (tmp4 & ~extmask) | (ownip & extmask); + memcpy (loc.address + 12, &tmp4, 4); + } + #else struct in_addr tmp4 = *((struct in_addr *) (loc.address + 12)); const struct in_addr ownip = *((struct in_addr *) (gv->interfaces[0].loc.address + 12)); const struct in_addr extip = *((struct in_addr *) (gv->interfaces[0].extloc.address + 12)); @@ -235,6 +249,8 @@ static struct addrset *addrset_from_locatorlists (const struct ddsi_domaingv *gv tmp4.s_addr = (tmp4.s_addr & ~extmask.s_addr) | (ownip.s_addr & extmask.s_addr); memcpy (loc.address + 12, &tmp4, 4); } + #endif + } addrset_from_locatorlists_add_one (gv, &loc, as, &intfs, &direct); diff --git a/src/core/ddsi/src/q_entity.c b/src/core/ddsi/src/q_entity.c index f04deeca..d934f86c 100644 --- a/src/core/ddsi/src/q_entity.c +++ b/src/core/ddsi/src/q_entity.c @@ -4346,7 +4346,11 @@ static void joinleave_mcast_helper (struct ddsi_domaingv *gv, ddsi_tran_conn_t c memcpy (&l1, l.address, sizeof (l1)); l.kind = NN_LOCATOR_KIND_UDPv4; memset (l.address, 0, 12); + #ifdef DDSRT_WITH_FREERTOSTCP + iph = ntohl (l1.ipv4); + #else iph = ntohl (l1.ipv4.s_addr); + #endif for (uint32_t i = 1; i < ((uint32_t)1 << l1.count); i++) { uint32_t ipn, iph1 = iph; @@ -5987,9 +5991,9 @@ static int proxy_endpoint_common_init (struct entity_common *e, struct proxy_end int ret; if (is_builtin_entityid (guid->entityid, proxypp->vendor)) - assert ((plist->qos.present & QP_TYPE_NAME) == 0); + { assert ((plist->qos.present & QP_TYPE_NAME) == 0); } else - assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); + { assert ((plist->qos.present & (QP_TOPIC_NAME | QP_TYPE_NAME)) == (QP_TOPIC_NAME | QP_TYPE_NAME)); } name = (plist->present & PP_ENTITY_NAME) ? plist->entity_name : ""; entity_common_init (e, proxypp->e.gv, guid, name, kind, tcreate, proxypp->vendor, false); diff --git a/src/core/ddsi/src/q_freelist.c b/src/core/ddsi/src/q_freelist.c index 28ed6ea1..9ce76244 100644 --- a/src/core/ddsi/src/q_freelist.c +++ b/src/core/ddsi/src/q_freelist.c @@ -120,6 +120,11 @@ void nn_freelist_init (struct nn_freelist *fl, uint32_t max, size_t linkoff) fl->count = 0; fl->max = (max == UINT32_MAX) ? max-1 : max; fl->linkoff = linkoff; + +#ifdef DDSRT_WITH_FREERTOSTCP + /* init TLS var */ + ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1)); +#endif } static void *get_next (const struct nn_freelist *fl, const void *e) @@ -160,6 +165,27 @@ void nn_freelist_fini (struct nn_freelist *fl, void (*xfree) (void *)) static ddsrt_atomic_uint32_t freelist_inner_idx_off = DDSRT_ATOMIC_UINT32_INIT(0); +#ifdef DDSRT_WITH_FREERTOSTCP +static int get_freelist_inner_idx (void) +{ + int inner_idx = -1; + + inner_idx = ddsrt_thread_tls_get(DDS_TLS_IDX_FREE, freelist_inner_idx); + + if(inner_idx == -1) + { + static const uint64_t unihashconsts[] = { + UINT64_C (16292676669999574021), + UINT64_C (10242350189706880077), + }; + uintptr_t addr; + uint64_t t = (uint64_t) ((uintptr_t) &addr) + ddsrt_atomic_ld32 (&freelist_inner_idx_off); + inner_idx = (int) (((((uint32_t) t + unihashconsts[0]) * ((uint32_t) (t >> 32) + unihashconsts[1]))) >> (64 - NN_FREELIST_NPAR_LG2)); + } + ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, inner_idx); + return inner_idx; +} +#else static int get_freelist_inner_idx (void) { if (freelist_inner_idx == -1) @@ -174,6 +200,7 @@ static int get_freelist_inner_idx (void) } return freelist_inner_idx; } +#endif static int lock_inner (struct nn_freelist *fl) { @@ -185,7 +212,12 @@ static int lock_inner (struct nn_freelist *fl) { ddsrt_atomic_st32(&fl->cc, 0); ddsrt_atomic_inc32(&freelist_inner_idx_off); + + #ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(freelist_inner_idx, DDS_TLS_IDX_FREE, (void*)(-1)); + #else freelist_inner_idx = -1; + #endif } } return k; diff --git a/src/core/ddsi/src/q_gc.c b/src/core/ddsi/src/q_gc.c index 61819126..7941ceb3 100644 --- a/src/core/ddsi/src/q_gc.c +++ b/src/core/ddsi/src/q_gc.c @@ -204,7 +204,11 @@ struct gcreq_queue *gcreq_queue_new (struct ddsi_domaingv *gv) bool gcreq_queue_start (struct gcreq_queue *q) { +#ifdef DDSRT_WITH_FREERTOSTCP + if (create_thread (&q->ts, q->gv, "dds_gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK) +#else if (create_thread (&q->ts, q->gv, "gc", (uint32_t (*) (void *)) gcreq_queue_thread, q) == DDS_RETCODE_OK) +#endif return true; else { diff --git a/src/core/ddsi/src/q_init.c b/src/core/ddsi/src/q_init.c index 0338f7e8..f7f4725d 100644 --- a/src/core/ddsi/src/q_init.c +++ b/src/core/ddsi/src/q_init.c @@ -130,6 +130,13 @@ static enum make_uc_sockets_ret make_uc_sockets (struct ddsi_domaingv *gv, uint3 } ddsi_conn_locator (gv->disc_conn_uc, &gv->loc_meta_uc); ddsi_conn_locator (gv->data_conn_uc, &gv->loc_default_uc); + + #ifdef DDSRT_WITH_FREERTOSTCP + /* update portid to up */ + *pdisc = gv->disc_conn_uc->m_base.m_port; + *pdata = gv->data_conn_uc->m_base.m_port; + #endif + return MUSRET_SUCCESS; fail_data: @@ -539,6 +546,7 @@ int rtps_config_prep (struct ddsi_domaingv *gv, struct cfgst *cfgst) DDS_ILOG (DDS_LC_ERROR, gv->config.domainId, "Invalid port mapping: %s\n", message); goto err_config_late_error; } + DDS_ILOG (DDS_LC_INFO, gv->config.domainId, " @@@@@@@@@@@ port mapping: <%s> \n", message); } /* retry_on_reject_duration default is dependent on late_ack_mode and responsiveness timeout, so fix up */ @@ -1022,20 +1030,23 @@ static int setup_and_start_recv_threads (struct ddsi_domaingv *gv) it before it does anything with it. */ if ((gv->recv_threads[i].arg.rbpool = nn_rbufpool_new (&gv->logconfig, gv->config.rbuf_size, gv->config.rmsg_chunk_size)) == NULL) { - GVERROR ("rtps_init: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_start: can't allocate receive buffer pool for thread %s\n", gv->recv_threads[i].name); goto fail; } + GVLOG(DDS_LC_CONFIG, "rtps_start: alloc rbpool %p for recv_thread[%d] '%s' done \n", + gv->recv_threads[i].arg.rbpool, i, gv->recv_threads[i].name); if (gv->recv_threads[i].arg.mode == RTM_MANY) { if ((gv->recv_threads[i].arg.u.many.ws = os_sockWaitsetNew ()) == NULL) { - GVERROR ("rtps_init: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_start: can't allocate sock waitset for thread %s\n", gv->recv_threads[i].name); goto fail; } + GVLOG(DDS_LC_CONFIG, "rtps_start: allocate sock waitset for thread %s done \n", gv->recv_threads[i].name); } if (create_thread (&gv->recv_threads[i].ts, gv, gv->recv_threads[i].name, recv_thread, &gv->recv_threads[i].arg) != DDS_RETCODE_OK) { - GVERROR ("rtps_init: failed to start thread %s\n", gv->recv_threads[i].name); + GVERROR ("rtps_start: failed to start thread %s\n", gv->recv_threads[i].name); goto fail; } } @@ -1339,6 +1350,7 @@ int rtps_init (struct ddsi_domaingv *gv) gv->listener = NULL; gv->debmon = NULL; +#ifndef DDSRT_WITH_FREERTOS /* Print start time for referencing relative times in the remainder of the DDS_LOG. */ { int sec = (int) (gv->tstart.v / 1000000000); @@ -1347,6 +1359,7 @@ int rtps_init (struct ddsi_domaingv *gv) ddsrt_ctime(gv->tstart.v, str, sizeof(str)); GVLOG (DDS_LC_CONFIG, "started at %d.06%d -- %s\n", sec, usec, str); } +#endif /* Allow configuration to set "deaf_mute" in case we want to start out that way */ gv->deaf = gv->config.initial_deaf; @@ -1362,6 +1375,7 @@ int rtps_init (struct ddsi_domaingv *gv) { case DDSI_TRANS_DEFAULT: assert(0); +#ifdef DDSRT_TRANS_UDP case DDSI_TRANS_UDP: case DDSI_TRANS_UDP6: gv->config.publish_uc_locators = 1; @@ -1370,6 +1384,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_UDP ? "udp" : "udp6"); break; +#endif +#ifdef DDSRT_TRANS_TCP case DDSI_TRANS_TCP: case DDSI_TRANS_TCP6: gv->config.publish_uc_locators = (gv->config.tcp_port != -1); @@ -1381,6 +1397,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, gv->config.transport_selector == DDSI_TRANS_TCP ? "tcp" : "tcp6"); break; +#endif +#ifdef DDSRT_TRANS_RAWETH case DDSI_TRANS_RAWETH: gv->config.publish_uc_locators = 1; gv->config.enable_uc_locators = 0; @@ -1390,6 +1408,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, "raweth"); break; +#endif +#ifdef DDSRT_TRANS_NONE case DDSI_TRANS_NONE: gv->config.publish_uc_locators = 0; gv->config.enable_uc_locators = 0; @@ -1399,6 +1419,7 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_udp_tcp_init; gv->m_factory = ddsi_factory_find (gv, "dummy"); break; +#endif } gv->m_factory->m_enable = true; @@ -1423,12 +1444,12 @@ int rtps_init (struct ddsi_domaingv *gv) { if (!gv->interfaces[i].mc_capable) { - GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name); gv->config.allowMulticast = DDSI_AMC_FALSE; /* ensure discovery can work: firstly, that the process will be reachable on a "well-known" port number, and secondly, that the local interface's IP address gets added to the discovery address set */ gv->config.participantIndex = DDSI_PARTICIPANT_INDEX_AUTO; + GVWARNING ("selected interface \"%s\" is not multicast-capable: disabling multicast\n", gv->interfaces[i].name); } else if (gv->config.allowMulticast & DDSI_AMC_DEFAULT) { @@ -1438,7 +1459,7 @@ int rtps_init (struct ddsi_domaingv *gv) if (gv->interfaces[i].mc_flaky) { gv->config.allowMulticast = DDSI_AMC_SPDP; - GVLOG (DDS_LC_CONFIG, "presumed flaky multicast, use for SPDP only\n"); + GVLOG (DDS_LC_CONFIG, "presumed flaky multicast(0x%08x), use for SPDP only\n", gv->config.allowMulticast); } else { @@ -1447,6 +1468,12 @@ int rtps_init (struct ddsi_domaingv *gv) } } } +#ifdef DDSRT_WITH_FREERTOSTCP + } + else + { + GVWARNING (" (gv->config.allowMulticast) is false! \n"); +#endif } assert ((gv->config.allowMulticast & DDSI_AMC_DEFAULT) == 0); @@ -1573,8 +1600,12 @@ int rtps_init (struct ddsi_domaingv *gv) memcpy (&gv->ppguid_base.prefix.s[2], digest, sizeof (gv->ppguid_base.prefix.s) - 2); gv->ppguid_base.prefix = nn_ntoh_guid_prefix (gv->ppguid_base.prefix); gv->ppguid_base.entityid.u = NN_ENTITYID_PARTICIPANT; + GVLOG(DDS_LC_CONFIG, " GUID prefix: "PGUIDFMT "vs [%08x %08x %08x]", + PGUID (gv->ppguid_base), + gv->ppguid_base.prefix.u[0], gv->ppguid_base.prefix.u[1], gv->ppguid_base.prefix.u[2]); } + ddsrt_mutex_init (&gv->lock); ddsrt_mutex_init (&gv->spdp_lock); gv->spdp_defrag = nn_defrag_new (&gv->logconfig, NN_DEFRAG_DROP_OLDEST, gv->config.defrag_unreliable_maxsamples); @@ -1582,6 +1613,8 @@ int rtps_init (struct ddsi_domaingv *gv) gv->m_tkmap = ddsi_tkmap_new (gv); + GVLOG (DDS_LC_CONFIG, "participantIndex %d \n", gv->config.participantIndex); + if (gv->m_factory->m_connless) { if (gv->config.participantIndex >= 0 || gv->config.participantIndex == DDSI_PARTICIPANT_INDEX_NONE) @@ -1600,6 +1633,8 @@ int rtps_init (struct ddsi_domaingv *gv) goto err_unicast_sockets; case MUSRET_ERROR: /* something bad happened; assume make_uc_sockets logged the error */ + GVERROR ("rtps_init: other failed to create unicast sockets for domain %"PRId32" participant index %d (ports %"PRIu32", %"PRIu32")\n", + gv->config.extDomainId.value, gv->config.participantIndex, port_disc_uc, port_data_uc); goto err_unicast_sockets; } } @@ -1621,8 +1656,10 @@ int rtps_init (struct ddsi_domaingv *gv) gv->config.extDomainId.value, ppid, port_disc_uc, port_data_uc); goto err_unicast_sockets; case MUSRET_PORTS_IN_USE: /* Try next one */ + GVERROR ("Failed to create unicast sockets PORTS_IN_USE \n"); break; case MUSRET_ERROR: + GVERROR ("Failed to create unicast sockets ERROR \n"); /* something bad happened; assume make_uc_sockets logged the error */ goto err_unicast_sockets; } @@ -1632,6 +1669,7 @@ int rtps_init (struct ddsi_domaingv *gv) GVERROR ("Failed to find a free participant index for domain %"PRIu32"\n", gv->config.extDomainId.value); goto err_unicast_sockets; } + GVLOG (DDS_LC_INFO,"find a participant %d index for domain %"PRIu32"\n", ppid, gv->config.extDomainId.value); gv->config.participantIndex = ppid; } else @@ -1640,11 +1678,12 @@ int rtps_init (struct ddsi_domaingv *gv) } GVLOG (DDS_LC_CONFIG, "rtps_init: uc ports: disc %"PRIu32" data %"PRIu32"\n", port_disc_uc, port_data_uc); } - GVLOG (DDS_LC_CONFIG, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); + GVLOG (DDS_LC_INFO, "rtps_init: domainid %"PRIu32" participantid %d\n", gv->config.domainId, gv->config.participantIndex); if (gv->config.pcap_file && *gv->config.pcap_file) { gv->pcap_fp = new_pcap_file (gv, gv->config.pcap_file); + GVLOG (DDS_LC_CONFIG, "rtps_init: pcap_file %s done \n", gv->config.pcap_file); if (gv->pcap_fp) { ddsrt_mutex_init (&gv->pcap_lock); @@ -2032,6 +2071,8 @@ int rtps_start (struct ddsi_domaingv *gv) return -1; } } + +#ifdef DDSRT_TRANS_TCP if (gv->config.monitor_port >= 0) { if ((gv->debmon = new_debug_monitor (gv, gv->config.monitor_port)) == NULL) @@ -2041,6 +2082,7 @@ int rtps_start (struct ddsi_domaingv *gv) return -1; } } +#endif return 0; } diff --git a/src/core/ddsi/src/q_pcap.c b/src/core/ddsi/src/q_pcap.c index 3b843f79..bb0115c1 100644 --- a/src/core/ddsi/src/q_pcap.c +++ b/src/core/ddsi/src/q_pcap.c @@ -145,8 +145,13 @@ void write_pcap_received (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud); u.ipv4_hdr.ttl = 128; + #ifdef DDSRT_WITH_FREERTOSTCP + u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr; + u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr; + #else u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr; u.ipv4_hdr.dstip = ((struct sockaddr_in*) dst)->sin_addr.s_addr; + #endif u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x); (void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp); udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port; @@ -178,8 +183,13 @@ void write_pcap_sent (struct ddsi_domaingv *gv, ddsrt_wctime_t tstamp, const str u.ipv4_hdr = ipv4_hdr_template; u.ipv4_hdr.totallength = ddsrt_toBE2u ((unsigned short) sz_iud); u.ipv4_hdr.ttl = 255; + #ifdef DDSRT_WITH_FREERTOSTCP + u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr; + u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr; + #else u.ipv4_hdr.srcip = ((struct sockaddr_in*) src)->sin_addr.s_addr; u.ipv4_hdr.dstip = ((struct sockaddr_in*) hdr->msg_name)->sin_addr.s_addr; + #endif u.ipv4_hdr.checksum = calc_ipv4_checksum (u.x); (void) fwrite (&u.ipv4_hdr, sizeof (u.ipv4_hdr), 1, gv->pcap_fp); udp_hdr.srcport = ((struct sockaddr_in*) src)->sin_port; diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index e4898c34..65cd2e8b 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -3177,7 +3177,7 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d else if (hdr->version.major != RTPS_MAJOR || (hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) { if ((hdr->version.major == RTPS_MAJOR && hdr->version.minor < RTPS_MINOR_MINIMUM)) - GVTRACE ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", + GVWARNING ("HDR(%"PRIx32":%"PRIx32":%"PRIx32" vendor %d.%d) len %lu\n, version mismatch: %d.%d\n", PGUIDPREFIX (hdr->guid_prefix), hdr->vendorid.id[0], hdr->vendorid.id[1], (unsigned long) sz, hdr->version.major, hdr->version.minor); if (DDSI_SC_PEDANTIC_P (gv->config)) malformed_packet_received (gv, msg, NULL, (size_t) sz, hdr->vendorid); @@ -3197,6 +3197,12 @@ static void handle_rtps_message (struct thread_state1 * const ts1, struct ddsi_d if (res != NN_RTPS_MSG_STATE_ERROR) { handle_submsg_sequence (ts1, gv, conn, srcloc, ddsrt_time_wallclock (), ddsrt_time_elapsed (), &hdr->guid_prefix, guidprefix, msg, (size_t) sz, msg + RTPS_MESSAGE_HEADER_SIZE, rmsg, res == NN_RTPS_MSG_STATE_ENCODED); +#ifdef DDSRT_WITH_FREERTOSTCP + } + else + { + GVWARNING(" decode_rtps_messages error! \n"); +#endif } } } @@ -3229,7 +3235,7 @@ static bool do_packet (struct thread_state1 * const ts1, struct ddsi_domaingv *g buff = (unsigned char *) NN_RMSG_PAYLOAD (rmsg); hdr = (Header_t*) buff; - if (conn->m_stream) + if (conn->m_stream) /* ONLY for TCP conn */ { MsgLen_t * ml = (MsgLen_t*) (hdr + 1); @@ -3446,13 +3452,16 @@ uint32_t listen_thread (struct ddsi_tran_listener *listener) static int recv_thread_waitset_add_conn (os_sockWaitset ws, ddsi_tran_conn_t conn) { if (conn == NULL) - return 0; + { return 0; } else { struct ddsi_domaingv *gv = conn->m_base.gv; for (uint32_t i = 0; i < gv->n_recv_threads; i++) + { + /* SKIP add thread "recvUC" / gv->data_conn_uc to waitset! */ if (gv->recv_threads[i].arg.mode == RTM_SINGLE && gv->recv_threads[i].arg.u.single.conn == conn) - return 0; + { return 0; } + } return os_sockWaitsetAdd (ws, conn); } } @@ -3495,6 +3504,12 @@ uint32_t recv_thread (void *vrecv_thread_arg) os_sockWaitset waitset = recv_thread_arg->mode == RTM_MANY ? recv_thread_arg->u.many.ws : NULL; ddsrt_mtime_t next_thread_cputime = { 0 }; +#ifdef DDSRT_WITH_FREERTOS + char name[64]; + ddsrt_thread_getname (name, sizeof (name)); + DDS_WARNING("recv_thread: called up for thread[%s] \n", name); +#endif + nn_rbufpool_setowner (rbpool, ddsrt_thread_self ()); if (waitset == NULL) { @@ -3515,17 +3530,36 @@ uint32_t recv_thread (void *vrecv_thread_arg) { int rc; if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_uc)) < 0) - DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); + { DDS_FATAL("recv_thread: failed to add disc_conn_uc to waitset\n"); } + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add disc_conn_uc to waitset ! \n"); } + #endif num_fixed_uc += (unsigned)rc; + if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_uc)) < 0) DDS_FATAL("recv_thread: failed to add data_conn_uc to waitset\n"); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add data_conn_uc to waitset ! \n"); } + #endif num_fixed_uc += (unsigned)rc; + num_fixed += num_fixed_uc; if ((rc = recv_thread_waitset_add_conn (waitset, gv->disc_conn_mc)) < 0) DDS_FATAL("recv_thread: failed to add disc_conn_mc to waitset\n"); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add disc_conn_mc to waitset ! \n"); } + #endif num_fixed += (unsigned)rc; + if ((rc = recv_thread_waitset_add_conn (waitset, gv->data_conn_mc)) < 0) DDS_FATAL("recv_thread: failed to add data_conn_mc to waitset\n"); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add data_conn_mc to waitset ! \n"); } + #endif num_fixed += (unsigned)rc; // OpenDDS doesn't respect the locator lists and insists on sending to the @@ -3535,9 +3569,13 @@ uint32_t recv_thread (void *vrecv_thread_arg) // Iceoryx gets added as a pseudo-interface but there's no socket to wait // for input on if (ddsi_conn_handle (gv->xmit_conns[i]) == DDSRT_INVALID_SOCKET) - continue; + { continue; } if ((rc = recv_thread_waitset_add_conn (waitset, gv->xmit_conns[i])) < 0) - DDS_FATAL("recv_thread: failed to add transmit_conn[%d] to waitset\n", i); + DDS_FATAL("recv_thread: failed to add xmit_conn[%d] to waitset\n", i); + #ifdef DDSRT_WITH_FREERTOSTCP + if (rc > 0) + { DDS_INFO("recv_thread: add xmit_conn[%d] to waitset ! \n", i); } + #endif num_fixed += (unsigned)rc; } } @@ -3564,7 +3602,7 @@ uint32_t recv_thread (void *vrecv_thread_arg) for (uint32_t i = 0; i < lps.nps; i++) { if (lps.ps[i].m_conn) - os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); + { os_sockWaitsetAdd (waitset, lps.ps[i].m_conn); } } } @@ -3575,13 +3613,18 @@ uint32_t recv_thread (void *vrecv_thread_arg) while ((idx = os_sockWaitsetNextEvent (ctx, &conn)) >= 0) { const ddsi_guid_prefix_t *guid_prefix; - if (((unsigned)idx < num_fixed) || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST) - guid_prefix = NULL; + if (((unsigned)idx < num_fixed) + || gv->config.many_sockets_mode != DDSI_MSM_MANY_UNICAST) + { guid_prefix = NULL; } else - guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; + { guid_prefix = &lps.ps[(unsigned)idx - num_fixed].guid_prefix; } + /* Process message and clean out connection if failed or closed */ - if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) && !conn->m_connless) + if (!do_packet (ts1, gv, conn, guid_prefix, rbpool) + && !conn->m_connless) + { ddsi_conn_free (conn); + } } } } diff --git a/src/core/ddsi/src/q_sockwaitset_s.c b/src/core/ddsi/src/q_sockwaitset_s.c new file mode 100755 index 00000000..df1c8bc9 --- /dev/null +++ b/src/core/ddsi/src/q_sockwaitset_s.c @@ -0,0 +1,522 @@ +/* + * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License + * v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ +#include +#include +#include + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/sockets.h" +#include "dds/ddsrt/sync.h" + +#include "dds/ddsi/q_sockwaitset.h" +#include "dds/ddsi/ddsi_config_impl.h" +#include "dds/ddsi/q_log.h" +#include "dds/ddsi/ddsi_tran.h" + +#define WAITSET_DELTA 8 + +#define MODE_KQUEUE 1 +#define MODE_SELECT 2 +#define MODE_WFMEVS 3 + +#if defined __APPLE__ +#define MODE_SEL MODE_KQUEUE +#elif defined WINCE +#define MODE_SEL MODE_WFMEVS +#else +#define MODE_SEL MODE_SELECT /* FreeRTOS always use select */ +#endif + + +#ifdef DDSRT_WITH_FREERTOSTCP +# warning " *** FreeRTOS-Plus-TCP debug include tree " + +#else +#if !_WIN32 && !LWIP_SOCKET + +#if ! __VXWORKS__&& !__QNXNTO__ +#include +#endif /* __VXWORKS__ __QNXNTO__ */ + +#ifndef _WRS_KERNEL +#include +#endif +#ifdef __sun +#include +#include +#include +#endif + +#endif /* !_WIN32 && !LWIP_SOCKET */ +#endif + +typedef struct os_sockWaitsetSet +{ + ddsi_tran_conn_t * conns; /* connections in set */ + ddsrt_socket_t * fds; /* file descriptors in set */ + unsigned sz; /* max number of fds in context */ + unsigned n; /* actual number of fds in context */ +} os_sockWaitsetSet; + +struct os_sockWaitsetCtx +{ + os_sockWaitsetSet set; /* set of connections and descriptors */ + unsigned index; /* cursor for enumerating */ + ddsrt_fd_set_t rdset; /* read file descriptors set */ +}; + +struct os_sockWaitset +{ + ddsrt_socket_t pipe[2]; /* pipe used for triggering */ + ddsrt_mutex_t mutex; /* concurrency guard */ + int fdmax_plus_1; /* value for first parameter of select() */ + os_sockWaitsetSet set; /* set of descriptors handled next */ + struct os_sockWaitsetCtx ctx; /* set of descriptors being handled */ +}; + +#if defined (_WIN32) +static int make_pipe (ddsrt_socket_t fd[2]) +{ + struct sockaddr_in addr; + socklen_t asize = sizeof (addr); + ddsrt_socket_t listener = socket (AF_INET, SOCK_STREAM, 0); + ddsrt_socket_t s1 = socket (AF_INET, SOCK_STREAM, 0); + ddsrt_socket_t s2 = DDSRT_INVALID_SOCKET; + + addr.sin_family = AF_INET; + #ifdef DDSRT_WITH_FREERTOSTCP + addr.sin_addr = htonl (INADDR_LOOPBACK); + #else + addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + #endif + addr.sin_port = 0; + if (bind (listener, (struct sockaddr *)&addr, sizeof (addr)) == -1) + goto fail; + if (getsockname (listener, (struct sockaddr *)&addr, &asize) == -1) + goto fail; + if (listen (listener, 1) == -1) + goto fail; + if (connect (s1, (struct sockaddr *)&addr, sizeof (addr)) == -1) + goto fail; + if ((s2 = accept (listener, 0, 0)) == INVALID_SOCKET) + goto fail; + closesocket (listener); + /* Equivalent to FD_CLOEXEC */ + SetHandleInformation ((HANDLE) s1, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation ((HANDLE) s2, HANDLE_FLAG_INHERIT, 0); + fd[0] = s1; + fd[1] = s2; + return 0; + +fail: + closesocket (listener); + closesocket (s1); + closesocket (s2); + return -1; +} +#elif defined(__VXWORKS__) +static int make_pipe (int pfd[2]) +{ + char pipename[OSPL_PIPENAMESIZE]; + int pipecount = 0; + do { + snprintf ((char*)&pipename, sizeof (pipename), "/pipe/ospl%d", pipecount++); + } while ((result = pipeDevCreate ((char*)&pipename, 1, 1)) == -1 && os_getErrno() == EINVAL); + if (result == -1) + goto fail_pipedev; + if ((pfd[0] = open ((char*)&pipename, O_RDWR, 0644)) == -1) + goto fail_open0; + if ((pfd[1] = open ((char*)&pipename, O_RDWR, 0644)) == -1) + goto fail_open1; + return 0; + +fail_open1: + close (pfd[0]); +fail_open0: + pipeDevDelete (pipename, 0); +fail_pipedev: + return -1; +} +#elif !defined(LWIP_SOCKET) +static int make_pipe (int pfd[2]) +{ + return pipe (pfd); +} +#endif + +static void os_sockWaitsetNewSet (os_sockWaitsetSet * set) +{ + set->fds = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->fds)); + set->conns = ddsrt_malloc (WAITSET_DELTA * sizeof (*set->conns)); + set->sz = WAITSET_DELTA; + set->n = 1; +} + +static void os_sockWaitsetFreeSet (os_sockWaitsetSet * set) +{ + ddsrt_free (set->fds); + ddsrt_free (set->conns); +} + +static void os_sockWaitsetNewCtx (os_sockWaitsetCtx ctx) +{ + os_sockWaitsetNewSet (&ctx->set); + + #ifdef DDSRT_WITH_FREERTOSTCP + ctx->rdset = DDSRT_FD_SET_CRATE(); + DDSRT_FD_ZERO (ctx->rdset); + DDS_WARNING("os_sockWaitsetNewCtx: rdset created! rdset %p \n", ctx->rdset); + #else + FD_ZERO (ctx->rdset); + #endif +} + +static void os_sockWaitsetFreeCtx (os_sockWaitsetCtx ctx) +{ + #ifdef DDSRT_WITH_FREERTOSTCP + DDSRT_FD_SET_DELETE(ctx->rdset); + #endif + os_sockWaitsetFreeSet (&ctx->set); +} + +os_sockWaitset os_sockWaitsetNew (void) +{ + int result; + os_sockWaitset ws = ddsrt_malloc (sizeof (*ws)); + + os_sockWaitsetNewSet (&ws->set); + os_sockWaitsetNewCtx (&ws->ctx); + +#if ! defined (_WIN32) + ws->fdmax_plus_1 = 0; +#else + ws->fdmax_plus_1 = FD_SETSIZE; +#endif + +#if defined(LWIP_SOCKET) + ws->pipe[0] = -1; + ws->pipe[1] = -1; + result = 0; +#elif defined(DDSRT_WITH_FREERTOSTCP) + # warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..." + ws->pipe[0] = -1; + ws->pipe[1] = -1; + result = 0; +#else + # error " *** NO makepipe for FreeRTOS " + + result = make_pipe (ws->pipe); +#endif + if (result == -1) + { + os_sockWaitsetFreeCtx (&ws->ctx); + os_sockWaitsetFreeSet (&ws->set); + ddsrt_free (ws); + return NULL; + } + +#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + ws->set.fds[0] = ws->pipe[0]; +#else +#warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..." + ws->set.fds[0] = 0; +#endif + ws->set.conns[0] = NULL; + +#if !defined(__VXWORKS__) && !defined(_WIN32) && !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) && !defined(__QNXNTO__) + (void) fcntl (ws->pipe[0], F_SETFD, fcntl (ws->pipe[0], F_GETFD) | FD_CLOEXEC); + (void) fcntl (ws->pipe[1], F_SETFD, fcntl (ws->pipe[1], F_GETFD) | FD_CLOEXEC); +#endif + +#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + FD_SET (ws->set.fds[0], ws->ctx.rdset); +#endif + +#if !defined(_WIN32) && !defined(DDSRT_WITH_FREERTOSTCP) + ws->fdmax_plus_1 = ws->set.fds[0] + 1; +#endif + + ddsrt_mutex_init (&ws->mutex); + + return ws; +} + +static void os_sockWaitsetGrow (os_sockWaitsetSet * set) +{ + set->sz += WAITSET_DELTA; + set->conns = ddsrt_realloc (set->conns, set->sz * sizeof (*set->conns)); + set->fds = ddsrt_realloc (set->fds, set->sz * sizeof (*set->fds)); +} + +void os_sockWaitsetFree (os_sockWaitset ws) +{ +#if defined(__VXWORKS__) && defined(__RTP__) + char nameBuf[OSPL_PIPENAMESIZE]; + ioctl (ws->pipe[0], FIOGETNAME, &nameBuf); +#endif + +#if defined(DDSRT_WITH_FREERTOSTCP) +# warning " *** FreeRTOS-Plus-TCP runtime tree " + (void) ddsrt_close (ws->pipe[0]); + (void) ddsrt_close (ws->pipe[1]); +#else + +#if defined(_WIN32) + closesocket (ws->pipe[0]); + closesocket (ws->pipe[1]); +#elif !defined(LWIP_SOCKET) + (void) close (ws->pipe[0]); + (void) close (ws->pipe[1]); +#endif +#endif + +#if defined(__VXWORKS__) && defined(__RTP__) + pipeDevDelete ((char*) &nameBuf, 0); +#endif + os_sockWaitsetFreeSet (&ws->set); + os_sockWaitsetFreeCtx (&ws->ctx); + ddsrt_mutex_destroy (&ws->mutex); + ddsrt_free (ws); +} + +void os_sockWaitsetTrigger (os_sockWaitset ws) +{ +#if defined(LWIP_SOCKET) + (void)ws; +#elif defined (DDSRT_WITH_FREERTOSTCP) +#warning " *** FreeRTOS-Plus-TCP FreeRTOS_Plus_TCP runtime wrapper ..." + (void)ws; +#else + char buf = 0; + int n; + +#if defined (_WIN32) + n = send (ws->pipe[1], &buf, 1, 0); +#else + n = (int) write (ws->pipe[1], &buf, 1); +#endif + if (n != 1) + { + DDS_WARNING("os_sockWaitsetTrigger: write failed on trigger pipe\n"); + } +#endif +} + +int os_sockWaitsetAdd (os_sockWaitset ws, ddsi_tran_conn_t conn) +{ + ddsrt_socket_t handle = ddsi_conn_handle (conn); + os_sockWaitsetSet * set = &ws->set; + unsigned idx; + int ret; + +#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP) + assert (handle >= 0); + assert (handle < FD_SETSIZE); +#endif + + ddsrt_mutex_lock (&ws->mutex); + for (idx = 0; idx < set->n; idx++) + { + if (set->conns[idx] == conn) + break; + } + if (idx < set->n) + { ret = 0; } + else + { + if (set->n == set->sz) + { os_sockWaitsetGrow (set); } +#if ! defined (_WIN32) && ! defined(DDSRT_WITH_FREERTOSTCP) + if ((int) handle >= ws->fdmax_plus_1) + ws->fdmax_plus_1 = handle + 1; +#endif + set->conns[set->n] = conn; + set->fds[set->n] = handle; + set->n++; + ret = 1; + } + ddsrt_mutex_unlock (&ws->mutex); + return ret; +} + +void os_sockWaitsetPurge (os_sockWaitset ws, unsigned index) +{ + os_sockWaitsetSet * set = &ws->set; + + ddsrt_mutex_lock (&ws->mutex); + if (index + 1 <= set->n) + { + for (unsigned i = index + 1; i < set->n; i++) + { + set->conns[i] = NULL; + set->fds[i] = 0; + } + set->n = index + 1; + } + ddsrt_mutex_unlock (&ws->mutex); +} + +void os_sockWaitsetRemove (os_sockWaitset ws, ddsi_tran_conn_t conn) +{ + os_sockWaitsetSet * set = &ws->set; + + ddsrt_mutex_lock (&ws->mutex); + for (unsigned i = 0; i < set->n; i++) + { + if (conn == set->conns[i]) + { + set->n--; + if (i != set->n) + { + set->fds[i] = set->fds[set->n]; + set->conns[i] = set->conns[set->n]; + } + break; + } + } + ddsrt_mutex_unlock (&ws->mutex); +} + +os_sockWaitsetCtx os_sockWaitsetWait (os_sockWaitset ws) +{ + unsigned u; +#if !_WIN32 + int fdmax; +#endif + ddsrt_fd_set_t rdset = NULL; + os_sockWaitsetCtx ctx = &ws->ctx; + os_sockWaitsetSet * dst = &ctx->set; + os_sockWaitsetSet * src = &ws->set; + + ddsrt_mutex_lock (&ws->mutex); + +#ifdef DDSRT_WITH_FREERTOSTCP + fdmax = 0; /* For FreeRTOS_TCP stack, fdmax is stub for api compatible */ +#else + #if !_WIN32 + fdmax = ws->fdmax_plus_1; + #endif +#endif + + /* Copy context to working context */ + + while (dst->sz < src->sz) + { + os_sockWaitsetGrow (dst); + } + dst->n = src->n; + + for (u = 0; u < src->n; u++) + { + dst->conns[u] = src->conns[u]; + dst->fds[u] = src->fds[u]; + } + + ddsrt_mutex_unlock (&ws->mutex); + + + /* Copy file descriptors into select read set */ + rdset = ctx->rdset; +#ifdef DDSRT_WITH_FREERTOSTCP + if (rdset == NULL) + { + assert(0); + } + +#endif + + DDSRT_FD_ZERO (rdset); +#if !defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + for (u = 0; u < dst->n; u++) + { + FD_SET (dst->fds[u], rdset); + } +#else + /* fds[0]/conns[0] not using for RTOS */ + for (u = 1; u < dst->n; u++) + { + DDSRT_WARNING_GNUC_OFF(sign-conversion) + DDSRT_FD_SET (dst->fds[u], rdset); + DDSRT_WARNING_GNUC_ON(sign-conversion) + } +#endif /* LWIP_SOCKET */ + + dds_return_t rc; + do + { + rc = ddsrt_select (fdmax, rdset, NULL, NULL, SELECT_TIMEOUT_MS); + if (rc < 0 && rc != DDS_RETCODE_INTERRUPTED && rc != DDS_RETCODE_TRY_AGAIN) + { + DDS_WARNING("os_sockWaitsetWait: select failed, retcode = %"PRId32, rc); + break; + } + } while (rc < 0); + + if (rc > 0) + { + /* set start VALID conn index + * this simply skips the trigger fd, index0 is INV. + */ + ctx->index = 1; + + /* to confirm for DDSRT_WITH_FREERTOSTCP + TODO + TODO + TODO + TODO + TODO + TODO + */ +#if ! defined(LWIP_SOCKET) && !defined(DDSRT_WITH_FREERTOSTCP) + if (FD_ISSET (dst->fds[0], rdset)) + { + char buf; + int n1; + #if defined (_WIN32) + n1 = recv (dst->fds[0], &buf, 1, 0); + #else + n1 = (int) read (dst->fds[0], &buf, 1); + #endif + if (n1 != 1) + { + DDS_WARNING("os_sockWaitsetWait: read failed on trigger pipe\n"); + assert (0); + } + } +#endif /* LWIP_SOCKET */ + return ctx; + } + + return NULL; +} + +int os_sockWaitsetNextEvent (os_sockWaitsetCtx ctx, ddsi_tran_conn_t * conn) +{ + while (ctx->index < ctx->set.n) + { + unsigned idx = ctx->index++; + ddsrt_socket_t fd = ctx->set.fds[idx]; +#if ! defined (LWIP_SOCKET) && ! defined(DDSRT_WITH_FREERTOSTCP) + assert(idx > 0); +#endif + + if (DDSRT_FD_ISSET (fd, ctx->rdset)) + { + *conn = ctx->set.conns[idx]; + + return (int) (idx - 1); + } + } + return -1; +} + + diff --git a/src/core/ddsi/src/q_thread.c b/src/core/ddsi/src/q_thread.c index 6de01fa1..3205bc74 100644 --- a/src/core/ddsi/src/q_thread.c +++ b/src/core/ddsi/src/q_thread.c @@ -109,7 +109,12 @@ void thread_states_init (unsigned maxthreads) (not strictly required, but it'll get one eventually anyway, and this makes it rather more clear). */ #ifndef NDEBUG +#ifdef DDSRT_WITH_FREERTOSTCP + struct thread_state1 * const ts0 = (struct thread_state1 * const)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); +#else struct thread_state1 * const ts0 = tsd_thread_state; +#endif + #endif struct thread_state1 * const ts1 = lookup_thread_state_real (); assert (ts0 == NULL || ts0 == ts1); @@ -124,7 +129,12 @@ bool thread_states_fini (void) struct thread_state1 *ts1 = lookup_thread_state (); assert (vtime_asleep_p (ddsrt_atomic_ld32 (&ts1->vtime))); reap_thread_state (ts1, true); + + #ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL); + #else tsd_thread_state = NULL; + #endif /* Some applications threads that, at some point, required a thread state, may still be around. Of those, the cleanup routine is invoked when the thread terminates. This should be rewritten @@ -215,13 +225,22 @@ static struct thread_state1 *lazy_create_thread_state (ddsrt_thread_t self) struct thread_state1 *lookup_thread_state_real (void) { +#ifdef DDSRT_WITH_FREERTOSTCP + struct thread_state1 *ts1 = (struct thread_state1 *)ddsrt_thread_tls_get(DDS_TLS_IDX_STATE, tsd_thread_state); +#else struct thread_state1 *ts1 = tsd_thread_state; +#endif + if (ts1 == NULL) { ddsrt_thread_t self = ddsrt_thread_self (); if ((ts1 = find_thread_state (self)) == NULL) ts1 = lazy_create_thread_state (self); +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1); +#else tsd_thread_state = ts1; +#endif } assert (ts1 != NULL); return ts1; @@ -232,9 +251,19 @@ static uint32_t create_thread_wrapper (void *ptr) struct thread_state1 * const ts1 = ptr; struct ddsi_domaingv const * const gv = ddsrt_atomic_ldvoidp (&ts1->gv); if (gv) - GVTRACE ("started new thread %"PRIdTID": %s\n", ddsrt_gettid (), ts1->name); + { + #ifndef DDSRT_WITH_FREERTOSTCP + GVTRACE ("started new thread %"PRIdTID": %s \n", ddsrt_gettid (), ts1->name); + #else + GVTRACE ("started new thread %"PRIdTID": %s, thread_t 0x%lx \n", ddsrt_gettid (), ts1->name, ts1->tid.task); + #endif + } assert (ts1->state == THREAD_STATE_INIT); +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, ts1); +#else tsd_thread_state = ts1; +#endif ddsrt_mutex_lock (&thread_states.lock); ts1->state = THREAD_STATE_ALIVE; ddsrt_mutex_unlock (&thread_states.lock); @@ -242,7 +271,12 @@ static uint32_t create_thread_wrapper (void *ptr) ddsrt_mutex_lock (&thread_states.lock); ts1->state = THREAD_STATE_STOPPED; ddsrt_mutex_unlock (&thread_states.lock); +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(tsd_thread_state, DDS_TLS_IDX_STATE, NULL); +#else tsd_thread_state = NULL; +#endif + return ret; } diff --git a/src/core/ddsi/src/q_transmit.c b/src/core/ddsi/src/q_transmit.c index 3e07fb55..b1bbd0d3 100644 --- a/src/core/ddsi/src/q_transmit.c +++ b/src/core/ddsi/src/q_transmit.c @@ -323,18 +323,32 @@ struct nn_xmsg *writer_hbcontrol_piggyback (struct writer *wr, const struct whc_ { if (ddsrt_avl_is_empty (&wr->readers)) { +#ifdef DDSRT_WITH_FREERTOSTCP + ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + *hbansreq ? "" : " final", + (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, +#endif whcst->max_seq, writer_read_seq_xmit(wr)); } else { +#ifdef DDSRT_WITH_FREERTOSTCP + ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %u usec (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + *hbansreq ? "" : " final", + (hbc->tsched.v == DDS_NEVER) ? DDS_NEVER : ((hbc->tsched.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else ETRACE (wr, "heartbeat(wr "PGUIDFMT"%s) piggybacked, resched in %g s (min-ack %"PRIu64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), *hbansreq ? "" : " final", (hbc->tsched.v == DDS_NEVER) ? INFINITY : (double) (hbc->tsched.v - tnow.v) / 1e9, +#endif root_rdmatch (wr)->min_seq, root_rdmatch (wr)->all_have_replied_to_hb ? "" : "!", whcst->max_seq, writer_read_seq_xmit(wr)); diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index 62af2967..0b285405 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -531,14 +531,22 @@ struct xeventq * xeventq_new (struct ddsi_domaingv *gv, size_t max_queued_rexmit dds_return_t xeventq_start (struct xeventq *evq, const char *name) { dds_return_t rc; +#ifdef DDSRT_WITH_FREERTOSTCP + char * evqname = "dds_tev"; +#else char * evqname = "tev"; +#endif assert (evq->ts == NULL); if (name) { size_t slen = strlen (name) + 5; evqname = ddsrt_malloc (slen); + #ifdef DDSRT_WITH_FREERTOSTCP + (void) snprintf (evqname, slen, "dds_tev.%s", name); + #else (void) snprintf (evqname, slen, "tev.%s", name); + #endif } evq->terminate = 0; @@ -764,20 +772,36 @@ static void handle_xevk_heartbeat (struct nn_xpack *xp, struct xevent *ev, ddsrt if (ddsrt_avl_is_empty (&wr->readers)) { - GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", +#ifdef DDSRT_WITH_FREERTOSTCP + GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + hbansreq ? "" : " final", + msg ? "sent" : "suppressed", + (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else + GVINFO ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack [none], avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, +#endif whcst.max_seq, writer_read_seq_xmit (wr)); } else { - GVTRACE ("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", +#ifdef DDSRT_WITH_FREERTOSTCP + GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %u usec (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", PGUID (wr->e.guid), hbansreq ? "" : " final", msg ? "sent" : "suppressed", - (t_next.v == DDS_NEVER) ? INFINITY : (double)(t_next.v - tnow.v) / 1e9, + (t_next.v == DDS_NEVER) ? DDS_NEVER : ((t_next.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND)), // usec +#else + GVINFO("heartbeat(wr "PGUIDFMT"%s) %s, resched in %g s (min-ack %"PRId64"%s, avail-seq %"PRIu64", xmit %"PRIu64")\n", + PGUID (wr->e.guid), + hbansreq ? "" : " final", + msg ? "sent" : "suppressed", + (t_next.v == DDS_NEVER) ? DDS_NEVER : (double)(t_next.v - tnow.v) / 1e9, +#endif ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->min_seq, ((struct wr_prd_match *) ddsrt_avl_root_non_empty (&wr_readers_treedef, &wr->readers))->all_have_replied_to_hb ? "" : "!", whcst.max_seq, writer_read_seq_xmit (wr)); @@ -1028,10 +1052,18 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e else { ddsrt_mtime_t tnext = ddsrt_mtime_add_duration (tnow, DDS_SECS (1)); - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", +#ifdef DDSRT_WITH_FREERTOSTCP + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n", + PGUID (pp->e.guid), + PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, + (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec + ); +#else + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9); +#endif (void) resched_xevent_if_earlier (ev, tnext); } } @@ -1055,10 +1087,18 @@ static void handle_xevk_spdp (UNUSED_ARG (struct nn_xpack *xp), struct xevent *e intv = gv->config.spdp_interval; tnext = ddsrt_mtime_add_duration (tnow, intv); - GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %gs)\n", + #ifdef DDSRT_WITH_FREERTOSTCP + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %u usec)\n", + PGUID (pp->e.guid), + PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, + (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec + ); + #else + GVTRACE ("xmit spdp "PGUIDFMT" to %"PRIx32":%"PRIx32":%"PRIx32":%x (resched %g s)\n", PGUID (pp->e.guid), PGUIDPREFIX (ev->u.spdp.dest_proxypp_guid_prefix), NN_ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER, (double)(tnext.v - tnow.v) / 1e9); + #endif (void) resched_xevent_if_earlier (ev, tnext); } } @@ -1091,7 +1131,13 @@ static void handle_xevk_pmd_update (struct thread_state1 * const ts1, struct nn_ tnext.v = tnow.v + intv - DDS_SECS (2); else tnext.v = tnow.v + 4 * intv / 5; - GVTRACE ("resched pmd("PGUIDFMT"): %gs\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); + #ifdef DDSRT_WITH_FREERTOSTCP + GVTRACE ("resched pmd("PGUIDFMT"): %u usec\n", PGUID (pp->e.guid), + (tnext.v - tnow.v) / (NANOSECONDS_PER_SECOND / MICROSECONDS_PER_SECOND) // usec + ); + #else + GVTRACE ("resched pmd("PGUIDFMT"): %g s\n", PGUID (pp->e.guid), (double)(tnext.v - tnow.v) / 1e9); + #endif } (void) resched_xevent_if_earlier (ev, tnext); @@ -1127,6 +1173,12 @@ static void handle_individual_xevent (struct thread_state1 * const ts1, struct x switch (xev->kind) { case XEVK_HEARTBEAT: + #ifdef DDSRT_WITH_FREERTOSTCP + { + static uint32_t hb_cnt = 0U; + DDS_WARNING(" handle_xevk_heartbeat %u ... ", hb_cnt++); + } + #endif handle_xevk_heartbeat (xp, xev, tnow); break; case XEVK_ACKNACK: diff --git a/src/core/ddsi/src/q_xmsg.c b/src/core/ddsi/src/q_xmsg.c index aa5bbc75..1cb12543 100644 --- a/src/core/ddsi/src/q_xmsg.c +++ b/src/core/ddsi/src/q_xmsg.c @@ -121,6 +121,7 @@ struct nn_xmsg { #ifdef IOV_MAX #if IOV_MAX > 0 && IOV_MAX < 256 +#error " you should not be here for DDSRT_WITH_FREERTOSTCP" #define NN_XMSG_MAX_MESSAGE_IOVECS IOV_MAX #endif #endif /* defined IOV_MAX */ @@ -1248,7 +1249,15 @@ static ssize_t nn_xpack_send1 (const ddsi_xlocator_t *loc, void * varg) } /* Possible number of bytes written can be larger * due to security. */ + #ifdef DDSRT_WITH_FREERTOSTCP + if (nbytes < len) + { + GVERROR (" sent len is NOT right! len %u v %u", len, nbytes); + assert (nbytes == -1 || (size_t) nbytes >= len); + } + #else assert (nbytes == -1 || (size_t) nbytes >= len); + #endif } #endif } @@ -1718,7 +1727,7 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag const uint32_t max_msg_size = rexmit ? xp->gv->config.max_rexmit_msg_size : xp->gv->config.max_msg_size; if (xpo_niov > 0 && sz > max_msg_size) { - GVTRACE (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", + GVINFO (" => now niov %d sz %"PRIuSIZE" > max_msg_size %"PRIu32", nn_xpack_send niov %d sz %"PRIu32" now\n", (int) niov, sz, max_msg_size, (int) xpo_niov, xpo_sz); xp->msg_len.length = xpo_sz; xp->niov = xpo_niov; diff --git a/src/ddsrt/include/dds/config.h.in b/src/ddsrt/include/dds/config.h.in index 87493ab3..f33ed369 100644 --- a/src/ddsrt/include/dds/config.h.in +++ b/src/ddsrt/include/dds/config.h.in @@ -15,6 +15,17 @@ #cmakedefine DDSRT_WITH_LWIP 1 #cmakedefine DDSRT_WITH_FREERTOS 1 +/* begin: FreeRTOS_Plus_TCP IP stack */ +#cmakedefine DDSRT_WITH_FREERTOSTCP 1 + +#cmakedefine DDSRT_TRANS_UDP 1 +#cmakedefine DDSRT_TRANS_TCP 1 +#cmakedefine DDSRT_TRANS_RAWETH 1 +#cmakedefine DDSRT_TRANS_NONE 1 + +/* end: FreeRTOS_Plus_TCP IP stack */ + + #cmakedefine DDSRT_HAVE_DYNLIB 1 #cmakedefine DDSRT_HAVE_FILESYSTEM 1 #cmakedefine DDSRT_HAVE_NETSTAT 1 diff --git a/src/ddsrt/include/dds/ddsrt/iovec.h b/src/ddsrt/include/dds/ddsrt/iovec.h index cbfa3514..3e9fe845 100644 --- a/src/ddsrt/include/dds/ddsrt/iovec.h +++ b/src/ddsrt/include/dds/ddsrt/iovec.h @@ -26,6 +26,15 @@ typedef unsigned long ddsrt_msg_iovlen_t; #if DDSRT_WITH_LWIP #include + +#elif defined DDSRT_WITH_FREERTOSTCP +#warning "debug rtos tcp stack including " +/* will implement struct io_vec in freertos_plus_tcp.h wrapper header. */ + +struct iovec { + void *iov_base; + size_t iov_len; +}; #else #include #include @@ -36,6 +45,8 @@ typedef size_t ddsrt_iov_len_t; #if defined(__linux) && !LWIP_SOCKET typedef size_t ddsrt_msg_iovlen_t; +#elif defined DDSRT_WITH_FREERTOSTCP +typedef size_t ddsrt_msg_iovlen_t; #else /* POSIX says int (which macOS, FreeBSD, Solaris do) */ typedef int ddsrt_msg_iovlen_t; #endif diff --git a/src/ddsrt/include/dds/ddsrt/log.h b/src/ddsrt/include/dds/ddsrt/log.h index dabdacb8..cbe31492 100644 --- a/src/ddsrt/include/dds/ddsrt/log.h +++ b/src/ddsrt/include/dds/ddsrt/log.h @@ -24,6 +24,9 @@ #include #include +#include "dds/config.h" +#include "dds/features.h" + #include "dds/export.h" #include "dds/ddsrt/attributes.h" @@ -87,8 +90,12 @@ extern "C" { DDS_LC_CONTENT | DDS_LC_SHM) /** @}*/ +#ifdef DDSRT_WITH_FREERTOSTCP +#define DDS_LOG_MASK DDS_LC_ALL +#else #define DDS_LOG_MASK \ (DDS_LC_FATAL | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_INFO) +#endif #define DDS_TRACE_MASK \ (~DDS_LOG_MASK) @@ -382,9 +389,15 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_LOG(cat, ...) \ ((dds_get_log_mask() & (cat)) ? \ dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) +#else +#define DDS_LOG(cat, fmt, ...) \ + ((dds_get_log_mask() & (cat)) ? \ + dds_log((cat), __FILE__, __LINE__, DDS_FUNCTION, fmt, ##__VA_ARGS__) : 0) +#endif /** * @brief Write a log message with a domain id override. @@ -398,10 +411,15 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_ILOG(cat, domid, ...) \ ((dds_get_log_mask() & (cat)) ? \ dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) - +#else +#define DDS_ILOG(cat, domid, fmt, ...) \ + ((dds_get_log_mask() & (cat)) ? \ + dds_log_id((cat), (domid), __FILE__, __LINE__, DDS_FUNCTION, fmt " \n", ##__VA_ARGS__) : 0) +#endif /** * @brief Write a log message using a specific config. * @@ -414,9 +432,15 @@ dds_log( * passed just as easily, they are rejected so that tracing is kept entirely * separate from logging, if only cosmetic. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_CLOG(cat, cfg, ...) \ (((cfg)->c.mask & (cat)) ? \ dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) : 0) +#else +#define DDS_CLOG(cat, cfg, fmt, ...) \ + (((cfg)->c.mask & (cat)) ? \ + dds_log_cfg((cfg), (cat), __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) : 0) +#endif /** Write a log message of type #DDS_LC_INFO into global log. */ #define DDS_INFO(...) \ @@ -428,8 +452,13 @@ dds_log( #define DDS_ERROR(...) \ DDS_LOG(DDS_LC_ERROR, __VA_ARGS__) /** Write a log message of type #DDS_LC_ERROR into global log and abort. */ +#ifndef DDSRT_WITH_FREERTOSTCP #define DDS_FATAL(...) \ dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, __VA_ARGS__) +#else +#define DDS_FATAL(fmt, ...) \ + dds_log(DDS_LC_FATAL, __FILE__, __LINE__, DDS_FUNCTION, fmt "\n", ##__VA_ARGS__) +#endif /* MSVC mishandles __VA_ARGS__ while claiming to be conforming -- and even if they have a defensible implement, they still differ from every other diff --git a/src/ddsrt/include/dds/ddsrt/process.h b/src/ddsrt/include/dds/ddsrt/process.h index c074d084..84e75197 100644 --- a/src/ddsrt/include/dds/ddsrt/process.h +++ b/src/ddsrt/include/dds/ddsrt/process.h @@ -55,6 +55,18 @@ extern "C" { DDS_EXPORT ddsrt_pid_t ddsrt_getpid(void); +/** + * @brief Return process name of the calling process. + * + * On linux maps to /proc/self/cmdline's first entry (argv[0]), + * on mac/windows maps to relevant API calls. Falls back to process-{pid} + * on failure. + * + * @returns The process name of the calling process. + */ +DDS_EXPORT char * +ddsrt_getprocessname(void); + #if defined (__cplusplus) } #endif diff --git a/src/ddsrt/include/dds/ddsrt/sockets.h b/src/ddsrt/include/dds/ddsrt/sockets.h index 65b40ed5..4a911c67 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets.h +++ b/src/ddsrt/include/dds/ddsrt/sockets.h @@ -10,10 +10,16 @@ #include "dds/ddsrt/retcode.h" #include "dds/ddsrt/time.h" #include "dds/ddsrt/misc.h" -#if _WIN32 -#include "dds/ddsrt/sockets/windows.h" + +#if defined DDSRT_WITH_FREERTOSTCP + #warning " debug rtos tcp stack including " + #include "dds/ddsrt/sockets/freertos_plus_tcp.h" #else -#include "dds/ddsrt/sockets/posix.h" + #if _WIN32 + #include "dds/ddsrt/sockets/windows.h" + #else + #include "dds/ddsrt/sockets/posix.h" + #endif #endif #if defined (__cplusplus) @@ -187,9 +193,15 @@ ddsrt_setsockreuse( DDS_EXPORT dds_return_t ddsrt_select( int32_t nfds, +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_fd_set_t readfds, + ddsrt_fd_set_t writefds, + ddsrt_fd_set_t errorfds, +#else fd_set *readfds, fd_set *writefds, fd_set *errorfds, +#endif dds_duration_t reltime); #if _WIN32 diff --git a/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h new file mode 100755 index 00000000..c2c01e22 --- /dev/null +++ b/src/ddsrt/include/dds/ddsrt/sockets/freertos_plus_tcp.h @@ -0,0 +1,245 @@ +/* + * INTEL CONFIDENTIAL + * + * Copyright (C) 2022 Intel Corporation + * + * This software and the related documents are Intel copyrighted materials, + * and your use of them is governed by the express license under which they + * were provided to you ("License"). Unless the License provides otherwise, + * you may not use, modify, copy, publish, distribute, disclose or transmit + * this software or the related documents without Intel's prior written permission. + * This software and the related documents are provided as is, with no express + * or implied warranties, other than those that are expressly + * stated in the License. + */ + +#ifndef DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H +#define DDSRT_SOCKETS_FREERTOS_PLUS_TCP_H + +#define __need_size_t +#include + +/* This operating system-specific header file defines the SOCK_*, PF_*, + AF_*, MSG_*, SOL_*, and SO_* constants, and the `struct sockaddr', + `struct msghdr', and `struct linger' types. */ + +#include + +#include +#include +#include +#include + +#include "dds/ddsrt/iovec.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#ifndef ntohl +#define ntohl FreeRTOS_ntohl +#define htol FreeRTOS_htonl + +#define htos FreeRTOS_htons +#define ntohs FreeRTOS_ntohs +#endif + +#define inet_addr FreeRTOS_inet_addr +#define IN_MULTICAST(ip) (xIsIPv4Multicast(ntohl(ip))) + + +/* posix data for FreeRTOS+TCP stack */ +#define DDSRT_HAVE_SSM 0 +#define IFF_UP 0x1 +#define IFF_BROADCAST 0x2 +#define IFF_LOOPBACK 0x8 +#define IFF_POINTOPOINT 0x10 +#define IFF_MULTICAST 0x1000 + +struct msghdr +{ + void *msg_name; + socklen_t msg_namelen; + struct iovec *msg_iov; + int msg_iovlen; + void *msg_control; + socklen_t msg_controllen; + int msg_flags; +}; + +struct timeval +{ + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +typedef struct msghdr ddsrt_msghdr_t; +#define DDSRT_MSGHDR_FLAGS 0 + + +/* adaption to ddsrt socket interface */ +typedef Socket_t ddsrt_socket_t; /* Socket_t ==> FreeRTOS_Socket_t* */ +// typedef SocketSelect_t fd_set; /* SocketSelect_t => struct xSOCKET_SET */ +typedef SocketSet_t ddsrt_fd_set_t; + +#define SELECT_TIMEOUT_MS 1000U /* 200U experienced value from XRCE-client */ + +/* +FD_ZERO() clears a set. +FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set. +FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns. +*/ +static inline void DDSRT_FD_ZERO(ddsrt_fd_set_t set) +{ + (void)set; +} + +static ddsrt_fd_set_t DDSRT_FD_SET_CRATE(void) +{ + SocketSet_t set = FreeRTOS_CreateSocketSet(); + assert(set); + return set; +} + +static void DDSRT_FD_SET_DELETE(ddsrt_fd_set_t set) +{ + assert(set); + FreeRTOS_DeleteSocketSet(set); +} + +/* +#define DDSRT_FD_ISSET(fd, set) FreeRTOS_FD_ISSET(fd, set) +#define DDSRT_FD_SET(fd, set) FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT) +#define DDSRT_FD_CLR(fd, set) FreeRTOS_FD_CLR(fd, set, eSELECT_ALL) +*/ + +static inline int32_t DDSRT_FD_ISSET(ddsrt_socket_t fd, ddsrt_fd_set_t set) +{ + return (int32_t)FreeRTOS_FD_ISSET(fd, set); +} + +/* for FD_SET only be used in CDDS for rdset */ +static inline void DDSRT_FD_SET(ddsrt_socket_t fd, ddsrt_fd_set_t set) +{ + FreeRTOS_FD_SET(fd, set, eSELECT_READ | eSELECT_EXCEPT); +} + +static inline void DDSRT_FD_CLR(ddsrt_socket_t fd, ddsrt_fd_set_t set) +{ + FreeRTOS_FD_CLR(fd, set, eSELECT_ALL); +} + +#ifndef sa_family_t + typedef uint8_t sa_family_t; +#endif + + struct sockaddr_storage + { + uint8_t s2_len; + sa_family_t ss_family; + char s2_data1[2]; + uint32_t s2_data2[3]; + }; + +#if 1 + /* for posix compatible sa_family reference inside DDS + * we declare sockaddr a new struct but same W/ freertos_sockaddr + */ + struct sockaddr + { + uint8_t sa_len; + sa_family_t sa_family; + uint16_t sin_port; + uint32_t sin_addr; + }; +#else +#define sockaddr freertos_sockaddr +#endif + +#define sockaddr_in freertos_sockaddr +typedef uint32_t in_addr_t; /* base type for internet address */ + +/* + * Options and types related to multicast membership + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 + typedef struct ip_mreq + { + in_addr_t imr_multiaddr; /* IP multicast address of group */ + in_addr_t imr_interface; /* local IP address of interface */ + } ip_mreq; + // end multicast + +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +/** 255.255.255.255 */ +#define INADDR_NONE ((uint32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define INADDR_LOOPBACK ((uint32_t)0x7f000000UL) +/** 0.0.0.0 */ +#define INADDR_ANY ((uint32_t)0x00000000UL) +/** 255.255.255.255 */ +#define INADDR_BROADCAST ((uint32_t)0xffffffffUL) + +#define AF_INET FREERTOS_AF_INET +#define AF_INET6 FREERTOS_AF_INET6 + +#define IPPROTO_IP 0 +#define IPPROTO_ICMP ipPROTOCOL_ICMP + +#define SOCK_DGRAM FREERTOS_SOCK_DGRAM +#define IPPROTO_UDP FREERTOS_IPPROTO_UDP + +#define SOCK_STREAM FREERTOS_SOCK_STREAM +#define IPPROTO_TCP FREERTOS_IPPROTO_TCP + +#define SOL_SOCKET IPPROTO_IP /* set socket level, always 0 for RTOS */ + +#define SO_REUSEADDR FREERTOS_SO_REUSE_LISTEN_SOCKET +#define SO_RCVTIMEO FREERTOS_SO_RCVTIMEO +#define SO_SNDTIMEO FREERTOS_SO_SNDTIMEO +#define SO_SNDBUF FREERTOS_SO_SNDBUF +#define SO_RCVBUF FREERTOS_SO_RCVBUF + +#define SO_OOB FREERTOS_MSG_OOB +#define SO_PEEK FREERTOS_MSG_PEEK +#define SO_DONTROUTE FREERTOS_MSG_DONTROUTE +#define SO_DONTWAIT FREERTOS_MSG_DONTWAIT + +/* + FreeRTOS_accept() has an optional timeout. The timeout defaults + to ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME, and is modified + using the FREERTOS_SO_RCVTIMEO parameter in a call to FreeRTOS_setsockopt() + + If a timeout occurs before a connection from a remote socket + is accepted then NULL is returned. +*/ +#define ACCEPT_TIMEOUT (NULL) // accpet timeout +#define INVALID_SOCKET (FREERTOS_INVALID_SOCKET) + +/* The following constants should be used for the second parameter of + `shutdown'. */ +#define SHUT_RD FREERTOS_SHUT_RD +#define SHUT_WR FREERTOS_SHUT_WR +#define SHUT_RDWR FREERTOS_SHUT_RDWR + + +#define DDSRT_INVALID_SOCKET (INVALID_SOCKET) +#define PRIdSOCK PRIxPTR + +// #define errno FreeRTOS_errno +#define DDSRT_RET_OK (0) + +#ifndef FD_SETSIZE +#define FD_SETSIZE 8 +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/src/ddsrt/include/dds/ddsrt/sockets/posix.h b/src/ddsrt/include/dds/ddsrt/sockets/posix.h index e48cc0c2..2c232415 100644 --- a/src/ddsrt/include/dds/ddsrt/sockets/posix.h +++ b/src/ddsrt/include/dds/ddsrt/sockets/posix.h @@ -31,6 +31,13 @@ extern "C" { #endif typedef int ddsrt_socket_t; + +#ifdef DDSRT_WITH_FREERTOSTCP +typedef fd_set* ddsrt_fd_set_t; /* compatible with FreeRTOS +TCP */ +#define SELECT_TIMEOUT_MS DDS_INFINITY +#endif + + #define DDSRT_INVALID_SOCKET (-1) #define PRIdSOCK "d" diff --git a/src/ddsrt/include/dds/ddsrt/threads.h b/src/ddsrt/include/dds/ddsrt/threads.h index 6341bf7a..46ac58fb 100644 --- a/src/ddsrt/include/dds/ddsrt/threads.h +++ b/src/ddsrt/include/dds/ddsrt/threads.h @@ -49,7 +49,13 @@ extern "C" { supports Thread-local storage since version 2.0. */ /* VxWorks 7 supports __thread for both GCC and DIAB, older versions may support it as well, but that is not verified. */ + +#ifdef DDSRT_WITH_FREERTOSTCP +#define ddsrt_thread_local +#else #define ddsrt_thread_local __thread +#endif + #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) #define ddsrt_thread_local __thread #else @@ -73,6 +79,32 @@ typedef struct { uint32_t stackSize; } ddsrt_threadattr_t; + +#ifdef DDSRT_WITH_FREERTOS +#if configNUM_THREAD_LOCAL_STORAGE_POINTERS <= 0 +#error " Error, FreeRTOS THREAD_LOCAL_STORAGE support NOT enabled!" +#endif + +/* +add configNUM_THREAD_LOCAL_STORAGE_POINTERS for DDS usage + 22 taskguard and FATfs reserved 0~3 +*/ +#define DDS_TLS_IDX_LOGBUFF 4 +#define DDS_TLS_IDX_FREE 5 +#define DDS_TLS_IDX_STATE 6 +#define DDS_TLS_IDX_CTX 7 + +#define ddsrt_thread_tls_set(d, idx, s) \ + vTaskSetThreadLocalStoragePointer(NULL, idx, (void*)s) + +#define ddsrt_thread_tls_get(idx, s) \ + pvTaskGetThreadLocalStoragePointer(NULL, idx) +#else +#error +#define ddsrt_thread_tls_set(d, idx, s) (d) = (s) +#define ddsrt_thread_tls_get(idx, s) (s) +#endif + /** * @brief Initialize thread attributes to platform defaults. */ diff --git a/src/ddsrt/src/cdtors.c b/src/ddsrt/src/cdtors.c index 5ceca0a8..ad49ab2e 100644 --- a/src/ddsrt/src/cdtors.c +++ b/src/ddsrt/src/cdtors.c @@ -165,6 +165,19 @@ DDSRT_WARNING_CLANG_ON(missing-prototypes) #pragma data_seg() #endif #else /* _WIN32 */ + +#ifdef DDSRT_WITH_FREERTOSTCP +void ddsrt_ctor(void) +{ + ddsrt_init(); +} + +void ddsrt_dtor(void) +{ + ddsrt_fini(); +} + +#else void __attribute__((constructor)) ddsrt_ctor(void); void __attribute__((destructor)) ddsrt_dtor(void); @@ -177,5 +190,8 @@ void __attribute__((destructor)) ddsrt_dtor(void) { ddsrt_fini(); } + +#endif + #endif /* _WIN32 */ diff --git a/src/ddsrt/src/heap/freertos/heap.c b/src/ddsrt/src/heap/freertos/heap.c index ffb3d0fb..89d448bc 100644 --- a/src/ddsrt/src/heap/freertos/heap.c +++ b/src/ddsrt/src/heap/freertos/heap.c @@ -10,6 +10,7 @@ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause */ #include +#include #if defined(configSUPPORT_DYNAMIC_ALLOCATION) && \ (configSUPPORT_DYNAMIC_ALLOCATION == 0) diff --git a/src/ddsrt/src/ifaddrs.c b/src/ddsrt/src/ifaddrs.c index d50a2e40..8114780d 100644 --- a/src/ddsrt/src/ifaddrs.c +++ b/src/ddsrt/src/ifaddrs.c @@ -19,7 +19,9 @@ ddsrt_freeifaddrs(ddsrt_ifaddrs_t *ifa) while (ifa != NULL) { next = ifa->next; + #ifndef DDSRT_WITH_FREERTOSTCP ddsrt_free(ifa->name); + #endif ddsrt_free(ifa->addr); ddsrt_free(ifa->netmask); ddsrt_free(ifa->broadaddr); diff --git a/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c new file mode 100755 index 00000000..52c17792 --- /dev/null +++ b/src/ddsrt/src/ifaddrs/freertos_plus_tcp/ifaddrs_plus_tcp.c @@ -0,0 +1,110 @@ + +#include +#include + +#include "dds/ddsrt/log.h" +#include "dds/ddsrt/misc.h" +#include "sockets_priv.h" + +#include "dds/ddsrt/heap.h" +#include "dds/ddsrt/io.h" +#include "dds/ddsrt/ifaddrs.h" +#include "dds/ddsrt/retcode.h" +#include "dds/ddsrt/string.h" + +extern const int *const os_supp_afs; + + +static dds_return_t copyaddr(ddsrt_ifaddrs_t **ifap) +{ + dds_return_t rc = DDS_RETCODE_OK; + ddsrt_ifaddrs_t *ifa; + struct sockaddr sa = {0U}; + + assert(ifap != NULL); + + /* note: local IP shoule be got after STACK up! */ + u32 lip, netmask, bcip; + bcip = ipBROADCAST_IP_ADDRESS; + FreeRTOS_GetAddressConfiguration(&lip, &netmask, NULL, NULL); + + ifa = ddsrt_calloc(1, sizeof(*ifa)); + if(ifa == NULL) + { + rc = DDS_RETCODE_OUT_OF_RESOURCES; + goto __exit; + } + + ifa->addr = ddsrt_calloc(1, sizeof(struct sockaddr)); + ifa->netmask = ddsrt_calloc(1, sizeof(struct sockaddr)); + ifa->broadaddr = ddsrt_calloc(1, sizeof(struct sockaddr)); + if ((ifa->addr == NULL) + || (ifa->netmask == NULL) + || (ifa->broadaddr == NULL)) + { + rc = DDS_RETCODE_OUT_OF_RESOURCES; + goto __exit; + } + + sa.sa_len = sizeof(struct sockaddr); + sa.sa_family = AF_INET; + sa.sin_addr = (lip); /* storage IP, no need. FreeRTOS_htonl */ + memcpy((void*)ifa->addr, &sa, sizeof(struct sockaddr)); + + sa.sin_addr = (netmask); + memcpy((void*)ifa->netmask, &sa, sizeof(struct sockaddr)); + + sa.sin_addr = (bcip); + memcpy((void*)ifa->broadaddr, &sa, sizeof(struct sockaddr)); + + ifa->next = NULL; + ifa->type = DDSRT_IFTYPE_WIRED; + ifa->name = "eqos0"; + ifa->index = 0; + ifa->flags = IFF_UP | IFF_BROADCAST; // | IFF_MULTICAST; + +__exit: + if (rc == DDS_RETCODE_OK) + { + *ifap = ifa; + } + else + { + ddsrt_freeifaddrs(ifa); + *ifap = NULL; + } + + return rc; +} + +dds_return_t ddsrt_getifaddrs(ddsrt_ifaddrs_t **ifap, const int *afs) +{ + dds_return_t rc = DDS_RETCODE_OK; + int use_ip4 = 0; + int use_ip6 = 0; + + assert(ifap != NULL); + + if (afs == NULL) + { + afs = os_supp_afs; + } + + for (int i = 0; afs[i] != DDSRT_AF_TERM; i++) + { + if (afs[i] == AF_INET) + { + use_ip4 = 1; + } +#ifdef DDSRT_HAVE_IPV6 + else if (afs[i] == AF_INET6) + { + use_ip6 = 1; + } +#endif + } + + rc = copyaddr(ifap); + + return rc; +} diff --git a/src/ddsrt/src/log.c b/src/ddsrt/src/log.c index a291c0ca..33d3f29e 100644 --- a/src/ddsrt/src/log.c +++ b/src/ddsrt/src/log.c @@ -38,7 +38,9 @@ typedef struct { FILE *out; } log_sink_t; +#ifndef DDSRT_WITH_FREERTOS static ddsrt_thread_local log_buffer_t log_buffer; +#endif static ddsrt_once_t lock_inited = DDSRT_ONCE_INIT; static ddsrt_rwlock_t lock; @@ -50,13 +52,82 @@ struct ddsrt_log_cfg_impl { DDSRT_STATIC_ASSERT (sizeof (struct ddsrt_log_cfg_impl) <= sizeof (struct ddsrt_log_cfg)); +static const uint8_t * ddslstr[] = { + "DDS_LC_FATAL", + "DDS_LC_ERROR", + "DDS_LC_WARNING", + "DDS_LC_INFO", + "DDS_LC_CONFIG", + "DDS_LC_DISCOVERY", + "DDS_LC_DATA", + "DDS_LC_TRACE", + "DDS_LC_RADMIN", + "DDS_LC_TIMING", + "DDS_LC_TRAFFIC", + "DDS_LC_TOPIC", + "DDS_LC_TCP", + "DDS_LC_PLIST", + "DDS_LC_WHC", + "DDS_LC_THROTTLE", + "DDS_LC_RHC", + "DDS_LC_CONTENT", + "DDS_LC_SHM", + }; + static void default_sink (void *ptr, const dds_log_data_t *data) { + #ifdef DDSRT_WITH_FREERTOSTCP + + (void)ptr; + uint32_t lv; + + uint32_t i; + for (i = 0U; i < sizeof(int) * 8U; i++) + { + if (data->priority <= (1U << i)) + { break; } + } + + switch (data->priority) + { + case DDS_LC_FATAL: + case DDS_LC_ERROR: + lv = IPLOG_LEVEL_ERROR; + pr_error("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + case DDS_LC_WARNING: + lv = IPLOG_LEVEL_WARN; + pr_warn("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + case DDS_LC_CONFIG: + case DDS_LC_INFO: + lv = IPLOG_LEVEL_INFO; + pr_info("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + case DDS_LC_TRACE: + lv = IPLOG_LEVEL_DEBUG; + pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + + case DDS_LC_DISCOVERY: + lv = IPLOG_LEVEL_DEBUG; + pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + + default: + lv = IPLOG_LEVEL_DEBUG; + pr_debug("[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + break; + } + //net_log_print(lv, "[%s] %s @%s-%d", ddslstr[i], data->message, data->function, data->line); + + #else if (ptr) { (void) fwrite (data->message - data->hdrsize, 1, data->hdrsize + data->size + 1, (FILE *) ptr); fflush ((FILE *) ptr); } + #endif } #define LOG (0) @@ -64,7 +135,14 @@ static void default_sink (void *ptr, const dds_log_data_t *data) static struct ddsrt_log_cfg_impl logconfig = { .c = { + #ifdef DDSRT_WITH_FREERTOSTCP + .mask = DDS_LC_ALL + | DDS_LC_DISCOVERY | DDS_LC_TOPIC + | DDS_LC_CONFIG | DDS_LC_INFO | DDS_LC_WARNING + | DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL, + #else .mask = DDS_LC_ERROR | DDS_LC_WARNING | DDS_LC_FATAL, + #endif .tracemask = 0, .domid = UINT32_MAX }, @@ -172,8 +250,19 @@ static size_t print_header (char *str, uint32_t id) { int cnt, off; char *tid, buf[MAX_TID_LEN+1] = { 0 }; + #ifdef DDSRT_WITH_FREERTOSTCP + /* + * for RTOS, printf might not support all format output, + * so add explict len other that this STDIO tricks + * printf("%.*s", 10, str) - output str with cutoff or prefix padding to 10 chars. + */ + static const char fmt_no_id[] = "%06u.%06d [] %.10s:"; + static const char fmt_with_id[] = "%06u.%06d [%"PRIu32"] %.10s:"; + // snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, tid); + #else static const char fmt_no_id[] = "%10u.%06d [] %*.*s:"; static const char fmt_with_id[] = "%10u.%06d [%"PRIu32"] %*.*s:"; + #endif dds_time_t time; unsigned sec; int usec; @@ -187,18 +276,44 @@ static size_t print_header (char *str, uint32_t id) if (id == UINT32_MAX) { off = MAX_ID_LEN; + #ifdef DDSRT_WITH_FREERTOSTCP + /* fix bug, HDR might overwrite log buffer set before. + HDR_LEN - off + //snprintf (str + off, HDR_LEN, "%10u.%06d [] %*.*s:", sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid) + */ + cnt = snprintf (str + off, HDR_LEN - off, fmt_no_id, sec, usec, + tid); + #else cnt = snprintf (str + off, HDR_LEN, fmt_no_id, sec, usec, MAX_TID_LEN, MAX_TID_LEN, tid); + #endif } else { /* low domain ids tend to be most used from what I have seen */ off = 9; if (id >= 10) - for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); + { for (uint32_t thres = 10; off > 0 && id >= thres; off--, thres *= 10); } + + #ifdef DDSRT_WITH_FREERTOSTCP + cnt = snprintf (str + off, HDR_LEN - off, fmt_with_id, sec, usec, id, tid); + #else cnt = snprintf (str + off, HDR_LEN, fmt_with_id, sec, usec, id, MAX_TID_LEN, MAX_TID_LEN, tid); + #endif } +#ifdef DDSRT_WITH_FREERTOSTCP + /* fix CycloneDDS bug + * for RTOS printf might not support all STDIO format. "%.*s" + */ + assert (off + cnt < HDR_LEN); + for (int i = off + cnt; i < HDR_LEN; i++) + { + str[i] = ' '; /* Replace snprintf null byte by space. */ + } +#else assert (off + cnt == (HDR_LEN - 1)); str[off + cnt] = ' '; /* Replace snprintf null byte by space. */ +#endif + return (size_t) (cnt + 1); } @@ -209,6 +324,10 @@ static void vlog1 (const struct ddsrt_log_cfg_impl *cfg, uint32_t cat, uint32_t log_buffer_t *lb; dds_log_data_t data; + #ifdef DDSRT_WITH_FREERTOS + log_buffer_t log_buffer = {0}; + #endif + /* id can be used to override the id in logconfig, so that the global logging configuration can be used for reporting errors while inlcuding a domain id. This simply verifies that the id override is only ever diff --git a/src/ddsrt/src/process/freertos/process.c b/src/ddsrt/src/process/freertos/process.c index b2998885..360d499d 100644 --- a/src/ddsrt/src/process/freertos/process.c +++ b/src/ddsrt/src/process/freertos/process.c @@ -20,3 +20,8 @@ ddsrt_getpid(void) return xTaskGetCurrentTaskHandle(); } +char * +ddsrt_getprocessname(void) +{ + return pcTaskGetName(xTaskGetCurrentTaskHandle()); +} diff --git a/src/ddsrt/src/sockets.c b/src/ddsrt/src/sockets.c index 364be9a8..08bfd800 100644 --- a/src/ddsrt/src/sockets.c +++ b/src/ddsrt/src/sockets.c @@ -19,6 +19,9 @@ #include "dds/ddsrt/heap.h" #include "dds/ddsrt/log.h" +#ifdef DDSRT_WITH_FREERTOSTCP +# warning " *** FreeRTOS-Plus-TCP debug include tree " +#else #if !LWIP_SOCKET # if !defined(_WIN32) # include @@ -29,6 +32,7 @@ # endif /* __linux */ # endif /* _WIN32 */ #endif /* LWIP_SOCKET */ +#endif /* FreeRTOSTCP */ #if defined __APPLE__ #include @@ -119,7 +123,11 @@ ddsrt_sockaddr_isunspecified(const struct sockaddr *__restrict sa) return IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6*)sa)->sin6_addr); #endif case AF_INET: - return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0); + #ifdef DDSRT_WITH_FREERTOSTCP + return (((struct sockaddr_in *)sa)->sin_addr == 0); + #else + return (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0); + #endif } return false; @@ -137,8 +145,12 @@ ddsrt_sockaddr_isloopback(const struct sockaddr *__restrict sa) &((const struct sockaddr_in6 *)sa)->sin6_addr); #endif /* DDSRT_HAVE_IPV6 */ case AF_INET: + #ifdef DDSRT_WITH_FREERTOSTCP + return (((const struct sockaddr_in *)sa)->sin_addr == htonl(INADDR_LOOPBACK)); + #else return (((const struct sockaddr_in *)sa)->sin_addr.s_addr == htonl(INADDR_LOOPBACK)); + #endif } return false; @@ -160,11 +172,19 @@ ddsrt_sockaddr_insamesubnet( switch (sa1->sa_family) { case AF_INET: { + #ifdef DDSRT_WITH_FREERTOSTCP + eq = ((((struct sockaddr_in *)sa1)->sin_addr & + ((struct sockaddr_in *)mask)->sin_addr) + == + (((struct sockaddr_in *)sa2)->sin_addr & + ((struct sockaddr_in *)mask)->sin_addr)); + #else eq = ((((struct sockaddr_in *)sa1)->sin_addr.s_addr & ((struct sockaddr_in *)mask)->sin_addr.s_addr) == (((struct sockaddr_in *)sa2)->sin_addr.s_addr & ((struct sockaddr_in *)mask)->sin_addr.s_addr)); + #endif } break; #if DDSRT_HAVE_IPV6 case AF_INET6: { @@ -196,14 +216,24 @@ ddsrt_sockaddrfromstr(int af, const char *str, void *sa) switch (af) { case AF_INET: { + #ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t buf; + #else struct in_addr buf; + #endif #if DDSRT_HAVE_INET_PTON if (inet_pton(af, str, &buf) != 1) { return DDS_RETCODE_BAD_PARAMETER; } #else + #ifdef DDSRT_WITH_FREERTOSTCP + buf = inet_addr (str); + if (buf == (in_addr_t)(-1)) + #else buf.s_addr = inet_addr (str); - if (buf.s_addr == (in_addr_t)-1) { + if (buf.s_addr == (in_addr_t)(-1)) + #endif + { return DDS_RETCODE_BAD_PARAMETER; } #endif @@ -247,7 +277,11 @@ DDSRT_WARNING_GNUC_OFF(sign-conversion) AF_INET, &((struct sockaddr_in *)sa)->sin_addr, buf, (uint32_t)size); #else { + #ifdef DDSRT_WITH_FREERTOSTCP + in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr); + #else in_addr_t x = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr); + #endif snprintf(buf,size,"%u.%u.%u.%u",(x>>24),(x>>16)&0xff,(x>>8)&0xff,x&0xff); ptr = buf; } diff --git a/src/ddsrt/src/threads/freertos/threads.c b/src/ddsrt/src/threads/freertos/threads.c index 206d7d62..9f3be999 100644 --- a/src/ddsrt/src/threads/freertos/threads.c +++ b/src/ddsrt/src/threads/freertos/threads.c @@ -183,7 +183,11 @@ static dds_return_t thread_context_acquire(thread_context_t **ctxptr) { dds_return_t rc = DDS_RETCODE_OK; + #ifdef DDSRT_WITH_FREERTOSTCP + thread_context_t *ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context); + #else thread_context_t *ctx = thread_context; + #endif if (ctx == NULL) { /* Dynamically initialize global thread registry (exactly once). */ @@ -199,7 +203,11 @@ thread_context_acquire(thread_context_t **ctxptr) ctx->task = xTaskGetCurrentTaskHandle(); } ddsrt_mutex_unlock(&thread_registry.mutex); + #ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx); + #else thread_context = ctx; + #endif } else { assert(ctx->func != NULL); assert(ctx->stat == THREAD_RUNNING); @@ -326,7 +334,11 @@ thread_start_routine(void *arg) thread because a reference to the thread's context is stored and synchronization is considerably easier if it's handled there. */ +#ifdef DDSRT_WITH_FREERTOSTCP + ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, ctx); +#else thread_context = ctx; +#endif ret = ctx->func(ctx->arg); thread_fini(ctx, ret); /* DO NOT DEREFERENCE THREAD CONTEXT ANYMORE! */ @@ -427,6 +439,10 @@ void ddsrt_thread_init(uint32_t reason) { (void)reason; +#ifdef DDSRT_WITH_FREERTOSTCP + /* init TLS var */ + ddsrt_thread_tls_set(thread_context, DDS_TLS_IDX_CTX, NULL); +#endif if (thread_context_require() != DDS_RETCODE_OK) { assert(0); } @@ -440,7 +456,12 @@ ddsrt_thread_fini(uint32_t reason) (void)reason; /* NO-OP if no context exists since thread-local storage and cleanup handler references are both stored in the thread context. */ + #ifdef DDSRT_WITH_FREERTOSTCP + ctx = (thread_context_t *)ddsrt_thread_tls_get(DDS_TLS_IDX_CTX, thread_context); + if ( ctx != NULL) { + #else if ((ctx = thread_context) != NULL) { + #endif assert(ctx->func != &non_local_thread); thread_fini(ctx, 0); } diff --git a/src/ddsrt/src/time.c b/src/ddsrt/src/time.c index 9551f0dd..64945fcc 100644 --- a/src/ddsrt/src/time.c +++ b/src/ddsrt/src/time.c @@ -38,6 +38,8 @@ void dds_sleepfor(dds_duration_t n) } #endif +#ifndef DDSRT_WITH_FREERTOS +#warning " ctime in glib, ignore it for FreeRTOS " size_t ddsrt_ctime(dds_time_t n, char *str, size_t size) { @@ -73,6 +75,7 @@ ddsrt_ctime(dds_time_t n, char *str, size_t size) return ddsrt_strlcpy(str, buf, size); } +#endif static void time_to_sec_usec (int32_t * __restrict sec, int32_t * __restrict usec, int64_t t) { diff --git a/src/ddsrt/src/time/freertos/time.c b/src/ddsrt/src/time/freertos/time.c index 01c367bb..e1e5d5a9 100644 --- a/src/ddsrt/src/time/freertos/time.c +++ b/src/ddsrt/src/time/freertos/time.c @@ -20,6 +20,9 @@ DDS_EXPORT extern inline TickType_t ddsrt_duration_to_ticks_ceil(dds_duration_t dds_time_t dds_time(void) { +#ifdef DDSRT_WITH_FREERTOSTCP + return get_timer_us(0U) * 1000U; +#else struct timespec ts; #if __STDC_VERSION__ >= 201112L @@ -29,6 +32,7 @@ dds_time_t dds_time(void) #endif return (ts.tv_sec * DDS_NSECS_IN_SEC) + ts.tv_nsec; +#endif } #define NSECS_PER_TICK (DDS_NSECS_IN_SEC / configTICK_RATE_HZ) From ccde1ec1accefcf9120c883118a326ff94952256 Mon Sep 17 00:00:00 2001 From: Zhou Shengyong Date: Mon, 16 Jun 2025 11:29:05 +0800 Subject: [PATCH 26/27] Update README.md --- README.md | 344 +++++------------------------------------------------- 1 file changed, 26 insertions(+), 318 deletions(-) diff --git a/README.md b/README.md index 2a9b041d..feb11e5f 100644 --- a/README.md +++ b/README.md @@ -4,323 +4,31 @@ [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-EDL%201.0-blue)](https://choosealicense.com/licenses/edl-1.0/) -# Eclipse Cyclone DDS +# This branch supports CycloneDDS over FreeRTOS-Plus-TCP stack on FreeRTOS. +CycloneDDS looks have support on FreeRTOS+LWIP Stack, + however lacking FreeRTOS-Plus-TCP Stack support +This change managed to add +TCP support + +* base CycloneDDS version0.9.1 +* ddsrt socket / thread ... + +[Changes] ++TCP socket +ddsrt header and source +sockaddr ifaddr +.init_array section +log sink +multicast/unicast peer define in xml +TLS-Thread_Local_Storage from FreeRTOS SW impl instread of toolchain +sock_waitset +sock fdset +sendmsg/recvmsg for UDP +dds_align from 0.10.2 +FragmentSize for jumbo and normal + + +# DDS Readme refer to master readme +Link: +https://github.com/polejoe/cycloneDDS_RTOS/blob/master/README.md -Eclipse Cyclone DDS is a very performant and robust open-source implementation of the [OMG DDS specification](https://www.omg.org/spec/DDS/1.4/About-DDS/). -Cyclone DDS is developed completely in the open as an Eclipse IoT project (see [eclipse-cyclone-dds](https://projects.eclipse.org/projects/iot.cyclonedds)) with a growing list of [adopters](https://iot.eclipse.org/adopters/?#iot.cyclonedds) (if you're one of them, please add your [logo](https://github.com/EclipseFdn/iot.eclipse.org/issues/new?template=adopter_request.md)). -It is a tier-1 middleware for the Robot Operating System [ROS 2](https://docs.ros.org/en/rolling/). -* [What is DDS?](#what-is-dds) -* [Getting Started](#getting-started) -* [Performance](#performance) -* [Configuration](#run-time-configuration) - -# What is DDS? - -DDS is the best-kept secret in distributed systems, one that has been around for much longer than most publish-subscribe messaging systems and still outclasses so many of them. -DDS is used in a wide variety of systems, including air-traffic control, jet engine testing, railway control, medical systems, naval command-and-control, smart greenhouses and much more. -In short, it is well-established in aerospace and defense but no longer limited to that. -And yet it is easy to use! - -Types are usually defined in IDL and preprocessed with the IDL compiler included in Cyclone, but our [Python binding](https://github.com/eclipse-cyclonedds/cyclonedds-python) allows you to define data types on the fly: -```Python -from dataclasses import dataclass -from cyclonedds.domain import DomainParticipant -from cyclonedds.core import Qos, Policy -from cyclonedds.pub import DataWriter -from cyclonedds.sub import DataReader -from cyclonedds.topic import Topic -from cyclonedds.idl import IdlStruct -from cyclonedds.idl.annotations import key -from time import sleep -import numpy as np -try: - from names import get_full_name - name = get_full_name() -except: - import os - name = f"{os.getpid()}" - -# C, C++ require using IDL, Python doesn't -@dataclass -class Chatter(IdlStruct, typename="Chatter"): - name: str - key("name") - message: str - count: int - -rng = np.random.default_rng() -dp = DomainParticipant() -tp = Topic(dp, "Hello", Chatter, qos=Qos(Policy.Reliability.Reliable(0))) -dw = DataWriter(dp, tp) -dr = DataReader(dp, tp) -count = 0 -while True: - sample = Chatter(name=name, message="Hello, World!", count=count) - count = count + 1 - print("Writing ", sample) - dw.write(sample) - for sample in dr.take(10): - print("Read ", sample) - sleep(rng.exponential()) -``` - -Today DDS is also popular in robotics and autonomous vehicles because those really depend on high-throuhgput, low-latency control systems without introducing a single point of failure by having a message broker in the middle. -Indeed, it is by far the most used and the default middleware choice in ROS 2. -It is used to transfer commands, sensor data and even video and point clouds between components. - -The OMG DDS specifications cover everything one needs to build systems using publish-subscribe messaging. -They define a structural type system that allows automatic endianness conversion and type checking between readers and writers. -This type system also supports type evolution. -The interoperable networking protocol and standard C++ API make it easy to build systems that integrate multiple DDS implementations. -Zero-configuration discovery is also included in the standard and supported by all implementations. - -DDS actually brings more: publish-subscribe messaging is a nice abstraction over "ordinary" networking, but plain publish-subscribe doesn't affect how one *thinks* about systems. -A very powerful architecture that truly changes the perspective on distributed systems is that of the "shared data space", in itself an old idea, and really just a distributed database. -Most shared data space designs have failed miserably in real-time control systems because they provided strong consistency guarantees and sacrificed too much performance and flexibility. -The *eventually consistent* shared data space of DDS has been very successful in helping with building systems that need to satisfy many "ilities": dependability, maintainability, extensibility, upgradeability, ... -Truth be told, that's why it was invented, and publish-subscribe messaging was simply an implementation technique. - -Cyclone DDS aims at full coverage of the specs and today already covers most of this. -With references to the individual OMG specifications, the following is available: - -- [DCPS](https://www.omg.org/spec/DDS/1.4/PDF) the base specification - - zero configuration discovery (if multicast works) - - publish/subscribe messaging - - configurable storage of data in subscribers - - many QoS settings - liveliness monitoring, deadlines, historical data, ... - - coverage includes the Minimum, Ownership and (partially) Content profiles -- [DDS Security](https://www.omg.org/spec/DDS-SECURITY/1.1/PDF) - providing authentication, access control and encryption -- [DDS C++ API](https://www.omg.org/spec/DDS-PSM-Cxx/1.0/PDF) -- [DDS XTypes](https://www.omg.org/spec/DDS-XTypes/1.3/PDF) - the structural type system (some [caveats](docs/dev/xtypes_relnotes.md) here) -- [DDSI-RTPS](https://www.omg.org/spec/DDSI-RTPS/2.5/PDF) - the interoperable network protocol - -The network stack in Cyclone DDS has been around for over a decade in one form or another and has proven itself in many systems, including large, high-availability ones and systems where interoperation with other implementations was needed. - -This repository provides the core of Cyclone DDS including its C API, the [OMG C++](https://github.com/eclipse-cyclonedds/cyclonedds-cxx) and the [Python](https://github.com/eclipse-cyclonedds/cyclonedds-python) language bindings are in sibling repositories. - -Consult the [roadmap](ROADMAP.md) for a high-level overview of upcoming features. - -# Getting Started - -## Building Eclipse Cyclone DDS - -In order to build Cyclone DDS you need a Linux, Mac or Windows 10 machine (or, with some caveats, a *BSD, QNX, OpenIndiana or a Solaris 2.6 one) with the following installed on your host: - - * C compiler (most commonly GCC on Linux, Visual Studio on Windows, Xcode on macOS); - * Optionally GIT version control system; - * [CMake](https://cmake.org/download/), version 3.10 or later; - * Optionally [OpenSSL](https://www.openssl.org/), preferably version 1.1; - * Optionally [Eclipse Iceoryx](https://iceoryx.io) version 2.0 for shared memory and zero-copy support; - * Optionally [Bison](https://www.gnu.org/software/bison/) parser generator. A cached source is checked into the repository. - -If you want to play around with the parser you will need to install the bison parser generator. On Ubuntu `apt install bison` should do the trick for getting it installed. -On Windows, installing chocolatey and `choco install winflexbison3` should get you a long way. On macOS, `brew install bison` is easiest. - -To obtain Eclipse Cyclone DDS, do - - $ git clone https://github.com/eclipse-cyclonedds/cyclonedds.git - $ cd cyclonedds - $ mkdir build - -Depending on whether you want to develop applications using Cyclone DDS or contribute to it you can follow different procedures: - -### Build configuration - -There are some configuration options specified using CMake defines in addition to the standard options like `CMAKE_BUILD_TYPE`: - -* `-DBUILD_EXAMPLES=ON`: to build the included examples -* `-DBUILD_TESTING=ON`: to build the test suite (this requires [CUnit](http://cunit.sourceforge.net/), see [Contributing to Eclipse Cyclone DDS](#contributing-to-eclipse-cyclone-dds) below for more information) -* `-DBUILD_IDLC=NO`: to disable building the IDL compiler (affects building examples, tests and `ddsperf`) -* `-DBUILD_DDSPERF=NO`: to disable building the [`ddsperf`](https://github.com/eclipse-cyclonedds/cyclonedds/tree/master/src/tools/ddsperf) tool for performance measurement -* `-DENABLE_SSL=NO`: to not look for OpenSSL, remove TLS/TCP support and avoid building the plugins that implement authentication and encryption (default is `AUTO` to enable them if OpenSSL is found) -* `-DENABLE_SHM=NO`: to not look for Iceoryx and disabled shared memory support (default is `AUTO` to enable it if Iceoryx is found) -* `-DENABLE_SECURITY=NO`: to not build the security interfaces and hooks in the core code, nor the plugins (one can enable security without OpenSSL present, you'll just have to find plugins elsewhere in that case) -* `-DENABLE_LIFESPAN=NO`: to exclude support for finite lifespans QoS -* `-DENABLE_DEADLINE_MISSED=NO`: to exclude support for finite deadline QoS settings -* `-DENABLE_TYPE_DISCOVERY=YES`: to include support for type discovery and checking type compatibility (likely to become enabled by default in the future) -* `-DENABLE_TOPIC_DISCOVERY=YES`: to include support for topic discovery (requires `-DENABLE_TYPE_DISCOVERY=YES`; somewhat likely to become enabled by default in the future) -* `-DENABLE_SOURCE_SPECIFIC_MULTICAST=NO`: to disable support for source-specific multicast (disabling this and `-DENABLE_IPV6=NO` may be needed for QNX builds) -* `-DENABLE_IPV6=NO`: to disable ipv6 support (disabling this and `-DENABLE_SOURCE_SPECIFIC_MULTICAST=NO` may be needed for QNX builds) - -### For application developers - -To build and install the required libraries needed to develop your own applications using Cyclone -DDS requires a few simple steps. -There are some small differences between Linux and macOS on the one -hand, and Windows on the other. -For Linux or macOS: - - $ cd build - $ cmake -DCMAKE_INSTALL_PREFIX= .. - $ cmake --build . - -and for Windows: - - $ cd build - $ cmake -G "" -DCMAKE_INSTALL_PREFIX= .. - $ cmake --build . - -where you should replace `` by the directory under which you would like to install Cyclone DDS and `` by one of the ways CMake [generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) offer for generating build files. -For example, "Visual Studio 15 2017 Win64" would target a 64-bit build using Visual Studio 2017. - -To install it after a successful build, do: - - $ cmake --build . --target install - -which will copy everything to: - - * `/lib` - * `/bin` - * `/include/ddsc` - * `/share/CycloneDDS` - -Depending on the installation location you may need administrator privileges. - -At this point you are ready to use Eclipse Cyclone DDS in your own projects. - -Note that the default build type is a release build with debug information included (RelWithDebInfo), which is generally the most convenient type of build to use from applications because of a good mix between performance and still being able to debug things. If you'd rather have a Debug or pure Release build, set `CMAKE_BUILD_TYPE` accordingly. - -### Contributing to Eclipse Cyclone DDS - -We very much welcome all contributions to the project, whether that is questions, examples, bug -fixes, enhancements or improvements to the documentation, or anything else really. -When considering contributing code, it might be good to know that build configurations for Azure pipelines are present in the repository and that there is a test suite using CTest and CUnit that can be built locally if desired. -To build it, set the cmake variable `BUILD_TESTING` to on when configuring, e.g.: - - $ cd build - $ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON .. - $ cmake --build . - $ ctest - -Such a build requires the presence of [CUnit](http://cunit.sourceforge.net/). -You can install this yourself, or you can choose to instead rely on the [Conan](https://conan.io) packaging system that the CI build infrastructure also uses. -In that case, install Conan and do: - - $ conan install .. --build missing - -in the build directory prior to running cmake. - -For Windows, depending on the generator, you might also need to add switches to select the architecture and build type, e.g., `conan install -s arch=x86_64 -s build_type=Debug ..` -This will automatically download and/or build CUnit (and, at the moment, OpenSSL). - -## Documentation - -The [documentation](https://cyclonedds.io) is still rather limited and some parts of it are still only available in the form of text files in the `docs` directory. -This README is usually out-of-date and the state of the documentation is slowly improving, so it definitely worth hopping over to have a look. - -## Building and Running the Roundtrip Example - -We will show you how to build and run an example program that measures latency. -The examples are built automatically when you build Cyclone DDS, so you don't need to follow these steps to be able to run the program, it is merely to illustrate the process. - - $ mkdir roundtrip - $ cd roundtrip - $ cmake /share/CycloneDDS/examples/roundtrip - $ cmake --build . - -On one terminal start the application that will be responding to pings: - - $ ./RoundtripPong - -On another terminal, start the application that will be sending the pings: - - $ ./RoundtripPing 0 0 0 - # payloadSize: 0 | numSamples: 0 | timeOut: 0 - # Waiting for startup jitter to stabilise - # Warm up complete. - # Latency measurements (in us) - # Latency [us] Write-access time [us] Read-access time [us] - # Seconds Count median min 99% max Count median min Count median min - 1 28065 17 16 23 87 28065 8 6 28065 1 0 - 2 28115 17 16 23 46 28115 8 6 28115 1 0 - 3 28381 17 16 22 46 28381 8 6 28381 1 0 - 4 27928 17 16 24 127 27928 8 6 27928 1 0 - 5 28427 17 16 20 47 28427 8 6 28427 1 0 - 6 27685 17 16 26 51 27685 8 6 27685 1 0 - 7 28391 17 16 23 47 28391 8 6 28391 1 0 - 8 27938 17 16 24 63 27938 8 6 27938 1 0 - 9 28242 17 16 24 132 28242 8 6 28242 1 0 - 10 28075 17 16 23 46 28075 8 6 28075 1 0 - -The numbers above were measured on Mac running a 4.2 GHz Intel Core i7 on December 12th 2018. -From these numbers you can see how the roundtrip is very stable and the minimal latency is now down to 17 micro-seconds (used to be 25 micro-seconds) on this HW. - -# Performance - -Reliable message throughput is over 1MS/s for very small samples and is roughly 90% of GbE with 100 -byte samples, and latency is about 30us when measured using [ddsperf](src/tools/ddsperf) between two Intel(R) Xeon(R) CPU E3-1270 V2 @ 3.50GHz (that's 2012 hardware ...) running Ubuntu 16.04, with the executables built on Ubuntu 18.04 using gcc 7.4.0 for a default (i.e., "RelWithDebInfo") build. - -ThroughputThroughput - -This is with the subscriber in listener mode, using asynchronous delivery for the throughput -test. -The configuration is a marginally tweaked out-of-the-box configuration: an increased maximum -message size and fragment size, and an increased high-water mark for the reliability window on the -writer side. -For details, see the [scripts](examples/perfscript) directory, -the -[environment details](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/config.txt) and the [throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/sub.log) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/ping.log) data underlying the graphs. These also include CPU usage ([throughput](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-cpu.png) and [latency](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/latency-sync-listener-bwcpu.png)) and [memory usage](https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/assets/performance/20190730/throughput-async-listener-memory.png). - -# Run-time configuration - -The out-of-the-box configuration should usually be fine, but there are a great many options that can be tweaked by creating an XML file with the desired settings and defining the `CYCLONEDDS_URI` to point to it. -E.g. (on Linux): - - $ cat cyclonedds.xml - - - - - - - - default - 65500B - - - - 500kB - - - - config - cdds.log.${CYCLONEDDS_PID} - - - - $ export CYCLONEDDS_URI=file://$PWD/cyclonedds.xml - -(on Windows, one would have to use `set CYCLONEDDS_URI=file://...` instead.) - -This example shows a few things: - -* `Interfaces` can be used to override the interfaces selected by default. - Members are - * `NetworkInterface[@autodetermine]` tells Cyclone DDS to autoselect the interface it deems best. - * `NetworkInterface[@name]` specifies the name of an interface to select (not shown above, alternative for autodetermine). - * `NetworkInterface[@ip]` specifies the ipv4/ipv6 address of an interface to select (not shown above, alternative for autodetermine). - * `NetworkInterface[@multicast]` specifies whether multicast should be used on this interface. - The default value 'default' means Cyclone DDS will check the OS reported flags of the interface and enable multicast if it is supported. - Use 'true' to ignore what the OS reports and enable it anyway and 'false' to always disable multicast on this interface. - * `NetworkInterface[@priority]` specifies the priority of an interface. - The default value (`default`) means priority `0` for normal interfaces and `2` for loopback interfaces. -* `AllowMulticast` configures the circumstances under which multicast will be used. - If the selected interface doesn't support it, it obviously won't be used (`false`); but if it does support it, the type of the network adapter determines the default value. - For a wired network, it will use multicast for initial discovery as well as for data when there are multiple peers that the data needs to go to (`true`). - On a WiFi network it will use it only for initial discovery (`spdp`), because multicast on WiFi is very unreliable. -* `Verbosity` allows control over the tracing, "config" dumps the configuration to the trace output (which defaults to "cyclonedds.log", but here the process id is appended). - Which interface is used, what multicast settings are used, etc., is all in the trace. - Setting the verbosity to "finest" gives way more output on the inner workings, and there are various other levels as well. -* `MaxMessageSize` controls the maximum size of the RTPS messages (basically the size of the UDP payload). - Large values such as these typically improve performance over the (current) default values on a loopback interface. -* `WhcHigh` determines when the sender will wait for acknowledgements from the readers because it has buffered too much unacknowledged data. - There is some auto-tuning, the (current) default value is a bit small to get really high throughput. - -Background information on configuring Cyclone DDS can be found [here](docs/manual/config.rst) and a list of settings is [available](docs/manual/options.md). - -# Trademarks - -* "Eclipse Cyclone DDS", "Cyclone DDS", "Eclipse Iceoryx" and "Iceoryx" are trademarks of the Eclipse Foundation. -* "DDS" is a trademark of the Object Management Group, Inc. -* "ROS" is a trademark of Open Source Robotics Foundation, Inc. From e31beafc4a0d6cfc4d09349710d1a3dd7be5dd53 Mon Sep 17 00:00:00 2001 From: Zhou Shengyong Date: Mon, 16 Jun 2025 11:33:33 +0800 Subject: [PATCH 27/27] Update README.md --- README.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index feb11e5f..5da77b67 100644 --- a/README.md +++ b/README.md @@ -4,28 +4,27 @@ [![License](https://img.shields.io/badge/License-EPL%202.0-blue)](https://choosealicense.com/licenses/epl-2.0/) [![License](https://img.shields.io/badge/License-EDL%201.0-blue)](https://choosealicense.com/licenses/edl-1.0/) -# This branch supports CycloneDDS over FreeRTOS-Plus-TCP stack on FreeRTOS. -CycloneDDS looks have support on FreeRTOS+LWIP Stack, - however lacking FreeRTOS-Plus-TCP Stack support -This change managed to add +TCP support +# This branch supports CycloneDDS over FreeRTOS-Plus-TCP stack on FreeRTOS. +CycloneDDS looks have support on FreeRTOS+LWIP Stack, +however lacking FreeRTOS-Plus-TCP Stack support +This change managed to add +TCP support -* base CycloneDDS version0.9.1 -* ddsrt socket / thread ... - -[Changes] -+TCP socket -ddsrt header and source -sockaddr ifaddr -.init_array section -log sink -multicast/unicast peer define in xml -TLS-Thread_Local_Storage from FreeRTOS SW impl instread of toolchain -sock_waitset -sock fdset -sendmsg/recvmsg for UDP -dds_align from 0.10.2 -FragmentSize for jumbo and normal +* base CycloneDDS version0.9.1 +* ddsrt socket / thread ... +[Changes] ++TCP socket +ddsrt header and source +sockaddr ifaddr +.init_array section +log sink +multicast/unicast peer define in xml +TLS-Thread_Local_Storage from FreeRTOS SW impl instread of toolchain +sock_waitset +sock fdset +sendmsg/recvmsg for UDP +dds_align from 0.10.2 +FragmentSize for jumbo and normal # DDS Readme refer to master readme Link: