Skip to content

Commit

Permalink
Merge pull request eclipse-iceoryx#1165 from ApexAI/iox-#1142-icedisc…
Browse files Browse the repository at this point in the history
…overy-in-c

Iox eclipse-iceoryx#1142 icediscovery in c
  • Loading branch information
FerdinandSpitzschnueffler authored and MatthiasKillat committed Mar 1, 2022
2 parents af547df + 7b20fa7 commit 7352e68
Show file tree
Hide file tree
Showing 17 changed files with 608 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ hicpp-*,
-bugprone-easily-swappable-parameters,
-bugprone-branch-clone,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-not-null-terminated-result,
-concurrency-mt-unsafe,
-readability-named-parameter,
-readability-avoid-const-params-in-decls,
Expand Down Expand Up @@ -86,7 +87,7 @@ hicpp-*,
# -readability-function-cognitive-complexity
#
## is it working correctly? produces hard to understand warning
# -clang-analyzer-core.uninitialized.UndefReturn
# -clang-analyzer-core.uninitialized.UndefReturn
# -clang-analyzer-optin.cplusplus.VirtualCall
#
###########################################
Expand Down
4 changes: 4 additions & 0 deletions doc/website/examples/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ nav:
- icecrystal.md
- request_response_in_c.md
- request_response.md
- complexdata.md
- user_header.md
- icediscovery.md
- icediscovery_in_c.md
2 changes: 1 addition & 1 deletion doc/website/examples/icediscovery.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Searching for currently available services
title: Searching for currently available services using C++
---

{! ../iceoryx/iceoryx_examples/icediscovery/README.md !}
5 changes: 5 additions & 0 deletions doc/website/examples/icediscovery_in_c.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Searching for currently available services using C
---

{! ../iceoryx/iceoryx_examples/icediscovery/README.md !}
3 changes: 3 additions & 0 deletions iceoryx_binding_c/include/iceoryx_binding_c/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,7 @@ uint32_t iox_cfg_max_runtime_name_length();
/// @brief the maximum size of a node name string + \0 terminator
#define IOX_CONFIG_NODE_NAME_SIZE 101

/// @brief the maximum size of a service description string identifier + \0 terminator
#define IOX_CONFIG_SERVICE_STRING_SIZE 101

#endif // IOX_BINDING_C_CONFIG_H
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
// Copyright (c) 2021 - 2022 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -17,13 +17,15 @@
#ifndef IOX_BINDING_C_SERVICE_DESCRIPTION_H
#define IOX_BINDING_C_SERVICE_DESCRIPTION_H

#include "iceoryx_binding_c/config.h"

#include <stdint.h>

typedef struct
{
char serviceString[100U];
char instanceString[100U];
char eventString[100U];
char serviceString[IOX_CONFIG_SERVICE_STRING_SIZE];
char instanceString[IOX_CONFIG_SERVICE_STRING_SIZE];
char eventString[IOX_CONFIG_SERVICE_STRING_SIZE];
} iox_service_description_t;

#endif
4 changes: 3 additions & 1 deletion iceoryx_binding_c/test/moduletests/test_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ TEST(iox_cfg, valuesAreCorrectlyConnected)
EXPECT_EQ(iox_cfg_max_findservice_result_size(), iox::MAX_FINDSERVICE_RESULT_SIZE);
EXPECT_EQ(iox_cfg_max_runtime_name_length(), iox::MAX_RUNTIME_NAME_LENGTH);

constexpr uint64_t ZERO_TERMINATOR_SIZE = 1;
constexpr uint64_t ZERO_TERMINATOR_SIZE = 1U;
EXPECT_EQ(IOX_CONFIG_NODE_NAME_SIZE, iox::NodeName_t::capacity() + ZERO_TERMINATOR_SIZE);

EXPECT_EQ(IOX_CONFIG_SERVICE_STRING_SIZE, iox::capro::IdString_t::capacity() + ZERO_TERMINATOR_SIZE);
}
} // namespace
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021 Apex.AI Inc. All rights reserved.
// Copyright (c) 2021 - 2022 Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,13 +32,14 @@ using namespace iox::capro;

TEST(iox_service_description_test, StringSizesAreCorrect)
{
constexpr uint64_t ZERO_TERMINATOR_SIZE = 1U;
::testing::Test::RecordProperty("TEST_ID", "f32a6d19-9ff7-4913-a1d8-39d46267b114");
EXPECT_THAT(sizeof(decltype(std::declval<iox_service_description_t>().serviceString)),
Eq(iox::capro::IdString_t().capacity()));
Eq(iox::capro::IdString_t().capacity() + ZERO_TERMINATOR_SIZE));
EXPECT_THAT(sizeof(decltype(std::declval<iox_service_description_t>().instanceString)),
Eq(iox::capro::IdString_t().capacity()));
Eq(iox::capro::IdString_t().capacity() + ZERO_TERMINATOR_SIZE));
EXPECT_THAT(sizeof(decltype(std::declval<iox_service_description_t>().eventString)),
Eq(iox::capro::IdString_t().capacity()));
Eq(iox::capro::IdString_t().capacity() + ZERO_TERMINATOR_SIZE));
}

} // namespace
1 change: 1 addition & 0 deletions iceoryx_examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
|[singleprocess](./singleprocess/) | Communicating in a single process between threads | :star::star: |
|[user_header](./user_header/) | Using a user-header for additional meta-information like timestamps | :star::star: |
|[icediscovery](./icediscovery) | Searching for currently available services | :star::star: |
|[icediscovery_in_c](./icediscovery_in_c/) | Searching for currently available services using C | :star::star: |
|[ice_access_control](./ice_access_control/) | Configuring access rights for shared memory segments | :star::star::star: |
|[iceperf](./iceperf/) | Measuring the latency of different IPC mechanisms | :star::star::star: |
|[icecrystal](./icecrystal/) | Using the introspection client for debugging | :star::star::star: |
54 changes: 54 additions & 0 deletions iceoryx_examples/icediscovery_in_c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (c) 2022 by Apex.AI Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

# Build icediscovery example
cmake_minimum_required(VERSION 3.16)
project(example_icediscovery_in_c)

include(GNUInstallDirs)

find_package(iceoryx_posh CONFIG REQUIRED)
find_package(iceoryx_hoofs CONFIG REQUIRED)
find_package(iceoryx_binding_c CONFIG REQUIRED)

get_target_property(ICEORYX_CXX_STANDARD iceoryx_posh::iceoryx_posh CXX_STANDARD)
include(IceoryxPlatform)

add_executable(iox-c-offer-service ./iox_c_offer_service.c)
set_source_files_properties(./ice_c_offer_service.c PROPERTIES LANGUAGE C)
target_link_libraries(iox-c-offer-service
iceoryx_binding_c::iceoryx_binding_c
)
set_target_properties(iox-c-offer-service PROPERTIES
POSITION_INDEPENDENT_CODE ON
)
target_compile_options(iox-c-offer-service PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS})

add_executable(iox-c-find-service ./iox_c_find_service.c)
set_source_files_properties(./ice_c_find_service.c PROPERTIES LANGUAGE C)
target_link_libraries(iox-c-find-service
iceoryx_binding_c::iceoryx_binding_c
)
set_target_properties(iox-c-offer-service PROPERTIES
POSITION_INDEPENDENT_CODE ON
)
target_compile_options(iox-c-find-service PRIVATE ${ICEORYX_WARNINGS} ${ICEORYX_SANITIZER_FLAGS})

# ========================================================== //

install(TARGETS iox-c-offer-service
iox-c-find-service
RUNTIME DESTINATION bin)
132 changes: 132 additions & 0 deletions iceoryx_examples/icediscovery_in_c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# icediscovery in C

## Introduction

This example demonstrates how to search for specific services using iceoryx's
service discovery. It provides two applications - one offering different
services and one searching for those with different search queries. The
behavior and structure is quite similar to the [icediscovery C++ example](https://github.com/eclipse-iceoryx/iceoryx/tree/v2.0.0/iceoryx_examples/icedelivery).

<!--## Expected Output-->
<!-- @todo Add expected output with asciinema recording before v2.0-->

## Code walkthrough

### Offer services

We create several publisher ports which offer their services on construction by
default. For more dynamism the `cameraPublishers` offer/stop their services
periodically. If you want more information on how to create publisher ports,
have a look at the [icedelivery C example](https://github.com/eclipse-iceoryx/iceoryx/tree/v2.0.0/iceoryx_examples/icedelivery_in_c).

### Find services

To be able to search for services, we need to include:

<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][include service discovery]-->
```c
#include "iceoryx_binding_c/service_discovery.h"
```

We create some storage for the service discovery and initialize it.

<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][create service discovery handle]-->
```c
iox_service_discovery_storage_t storage;
iox_service_discovery_t serviceDiscovery = iox_service_discovery_init(&storage);
```

We can now call three different find service functions. Let's start with

<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][find service and apply callable]-->
```c
iox_service_discovery_find_service_apply_callable(
serviceDiscovery, "Radar", "FrontLeft", "Image", printSearchResult, MessagingPattern_PUB_SUB);
```
which searches for all `{Radar, FrontLeft, Image}` services offered by
publishers and applies the provided function `printSearchResult` on each of
them. The function must have the signature
`void(const iox_service_description_t)`. Here we pass a function that prints the
found services on the console:
<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][print function to be applied to search results]-->
```c
void printSearchResult(const iox_service_description_t service)
{
printf(
"- Service: %s, Instance: %s, Event: %s\n", service.serviceString, service.instanceString, service.eventString);
}
```

We cannot only search for exact matching services. In combination with
wildcards (`NULL`) we can also search for all instances and events with the
service `Radar`:

<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][search for all Radar services]-->
```c
iox_service_discovery_find_service_apply_callable(
serviceDiscovery, "Radar", NULL, NULL, printSearchResult, MessagingPattern_PUB_SUB);
```
The wildcard can be used for all strings which describe a service, i.e. service,
instance and event.
Let's now search for all `Camera` services and store the results in an array:
<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][search for all Camera services]-->
```c
numberFoundServices = iox_service_discovery_find_service(serviceDiscovery,
"Camera",
NULL,
NULL,
searchResult,
SEARCH_RESULT_CAPACITY,
&missedServices,
MessagingPattern_PUB_SUB);
```

`searchResult` is a `iox_service_description_t` array of size
`SEARCH_RESULT_CAPACITY`. The matching services are written into this array, up
to a maximum of `SEARCH_RESULT_CAPACITY`. If the number of found services
exceeds the array's capacity, the number of services that could not be stored is
written to `missedServices`. The number of stored services is returned. Since
the `cameraPublishers` periodically offer/stop their services, you should see
sometimes 5 `Camera` services and sometimes none.

Finally, let's try out the third find service function. We search again for all
`Camera` services but additionally count the front camera services:

<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][search for all front camera services]-->
```c
iox_service_discovery_find_service_apply_callable_with_context_data(
serviceDiscovery, "Camera", NULL, NULL, searchFrontDevices, &numberFrontCameras, MessagingPattern_PUB_SUB);
```
This function is quite similar to the first find service function, but we
pass an additional argument `numberFrontCameras`:
<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][store number of front cameras]-->
```c
uint32_t numberFrontCameras = 0U;
```

We use this variable to store the number of front cameras and provide it as
second argument `count` to the function `searchFrontDevices` which is applied to
all found services:

<!--[geoffrey][iceoryx_examples/icediscovery_in_c/iox_c_find_service.c][search function for all front devices]-->
```c
void searchFrontDevices(const iox_service_description_t service, void* count)
{
if (strncmp("FrontLeft", service.instanceString, IOX_CONFIG_SERVICE_STRING_SIZE) == 0
|| strncmp("FrontRight", service.instanceString, IOX_CONFIG_SERVICE_STRING_SIZE) == 0)
{
++*(uint32_t*)count;
}
}
```
<center>
[Check out icediscovery on GitHub :fontawesome-brands-github:](https://github.com/eclipse-iceoryx/iceoryx/tree/v2.0.0/iceoryx_examples/icediscovery_in_c){ .md-button }
</center>
Loading

0 comments on commit 7352e68

Please sign in to comment.