diff --git a/src/core/ddsc/include/dds/dds.h b/src/core/ddsc/include/dds/dds.h index 206b26338e..ce803d1374 100644 --- a/src/core/ddsc/include/dds/dds.h +++ b/src/core/ddsc/include/dds/dds.h @@ -418,6 +418,26 @@ dds_get_mask(dds_entity_t condition, uint32_t *mask); DDS_EXPORT dds_return_t dds_get_instance_handle(dds_entity_t entity, dds_instance_handle_t *ihdl); +/** + * @brief Returns the GUID that represents the entity in the network, + * and therefore only supports participants, readers and writers. + * + * @param[in] entity Entity of which to get the instance handle. + * @param[out] guid Where to store the GUID. + * + * @returns A dds_return_t indicating success or failure. + * + * @retval DDS_RETCODE_OK + * Success. + * @retval DDS_RETCODE_ILLEGAL_OPERATION + * The operation is invoked on an inappropriate object. + * @retval DDS_RETCODE_ERROR + * An internal error has occurred. + */ +/* TODO: Check list of return codes is complete. */ +DDS_EXPORT dds_return_t +dds_get_guid (dds_entity_t entity, dds_guid_t *guid); + /* All entities have a set of "status conditions" (following the DCPS spec), read peeks, take reads & resets (analogously to read & take diff --git a/src/core/ddsc/src/dds_entity.c b/src/core/ddsc/src/dds_entity.c index e6620db4d3..0e48251e35 100644 --- a/src/core/ddsc/src/dds_entity.c +++ b/src/core/ddsc/src/dds_entity.c @@ -25,6 +25,7 @@ #include "dds/ddsi/ddsi_pmd.h" #include "dds/ddsi/ddsi_xqos.h" #include "dds/ddsi/q_transmit.h" +#include "dds/ddsi/q_bswap.h" extern inline dds_entity *dds_entity_from_handle_link (struct dds_handle_link *hdllink); extern inline bool dds_entity_is_enabled (const dds_entity *e); @@ -1285,6 +1286,36 @@ dds_return_t dds_get_instance_handle (dds_entity_t entity, dds_instance_handle_t return ret; } +dds_return_t dds_get_guid (dds_entity_t entity, dds_guid_t *guid) +{ + dds_entity *e; + dds_return_t ret; + + if (guid == NULL) + return DDS_RETCODE_BAD_PARAMETER; + + if ((ret = dds_entity_pin (entity, &e)) != DDS_RETCODE_OK) + return ret; + switch (dds_entity_kind (e)) + { + case DDS_KIND_PARTICIPANT: + case DDS_KIND_READER: + case DDS_KIND_WRITER: { + DDSRT_STATIC_ASSERT (sizeof (dds_guid_t) == sizeof (ddsi_guid_t)); + ddsi_guid_t tmp = nn_ntoh_guid (e->m_guid); + memcpy (guid, &tmp, sizeof (*guid)); + ret = DDS_RETCODE_OK; + break; + } + default: { + ret = DDS_RETCODE_ILLEGAL_OPERATION; + break; + } + } + dds_entity_unpin(e); + return ret; +} + dds_return_t dds_entity_pin (dds_entity_t hdl, dds_entity **eptr) { dds_return_t hres; diff --git a/src/core/ddsc/tests/entity_api.c b/src/core/ddsc/tests/entity_api.c index f00edab3a5..876fc59064 100644 --- a/src/core/ddsc/tests/entity_api.c +++ b/src/core/ddsc/tests/entity_api.c @@ -255,6 +255,28 @@ CU_Test(ddsc_entity, status, .init = create_entity, .fini = delete_entity) CU_ASSERT_EQUAL_FATAL(status1, DDS_RETCODE_OK); } +CU_Test(ddsc_entity, guid, .init = create_entity, .fini = delete_entity) +{ + dds_return_t status; + dds_guid_t guid, zero; + memset(&zero, 0, sizeof(zero)); + + /* Don't check actual handle contents. That's a job + * for the specific entity children, not for the generic part. */ + + /* Check getting Handle with bad parameters. */ + status = dds_get_guid (0, NULL); + CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_BAD_PARAMETER); + status = dds_get_guid (entity, NULL); + CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_BAD_PARAMETER); + status = dds_get_guid (0, &guid); + CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_BAD_PARAMETER); + + /* Get Instance Handle, which should not be 0 for a participant. */ + status = dds_get_guid (entity, &guid); + CU_ASSERT_EQUAL_FATAL(status, DDS_RETCODE_OK); + CU_ASSERT_FATAL(memcmp(&guid, &zero, sizeof(guid)) != 0); +} CU_Test(ddsc_entity, instance_handle, .init = create_entity, .fini = delete_entity) {