Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1142 Add readme
Browse files Browse the repository at this point in the history
Signed-off-by: Marika Lehmann <[email protected]>
  • Loading branch information
FerdinandSpitzschnueffler authored and MatthiasKillat committed Mar 1, 2022
1 parent cb375ae commit 76d3348
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 0 deletions.
131 changes: 131 additions & 0 deletions iceoryx_examples/icediscovery_in_c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# 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 these making 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 have to create a service discovery handle
which points to `storage`, the memory location where the service discovery is
stored.

<!--[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);
```

It is included via:

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

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 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 can not only search for exactly matching services, but also for wildcards
using `NULL`:

<!--[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);
```
With the above call we look for every `Radar` service with any instance and any
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 found services are written into this array, but
at maximum `SEARCH_RESULT_CAPACITY`. If the number of found services exceeds
the array's capacity, the number of not stored services 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:
<!--[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 parameter to the function 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(service.instanceString, "FrontLeft", IOX_CONFIG_SERVICE_STRING_SIZE - 1U) == 0
|| strncmp(service.instanceString, "FrontRight", IOX_CONFIG_SERVICE_STRING_SIZE - 1U) == 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>
18 changes: 18 additions & 0 deletions iceoryx_examples/icediscovery_in_c/iox_c_find_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_binding_c/runtime.h"
//! [include service discovery]
#include "iceoryx_binding_c/service_discovery.h"
//! [include service discovery]
#include "sleep_for.h"

#include <signal.h>
Expand All @@ -37,12 +39,15 @@ static void sigHandler(int signalValue)
keepRunning = false;
}

//! [print function to be applied to search results]
void printSearchResult(const iox_service_description_t service)
{
printf(
"- Service: %s, Instance: %s, Event: %s\n", service.serviceString, service.instanceString, service.eventString);
}
//! [print function to be applied to search results]

//! [search function for all front devices]
void searchFrontDevices(const iox_service_description_t service, void* count)
{
if (strncmp(service.instanceString, "FrontLeft", IOX_CONFIG_SERVICE_STRING_SIZE - 1U) == 0
Expand All @@ -51,6 +56,7 @@ void searchFrontDevices(const iox_service_description_t service, void* count)
++*(uint32_t*)count;
}
}
//! [search function for all front devices]

int main()
{
Expand All @@ -59,8 +65,10 @@ int main()

iox_runtime_init(APP_NAME);

//! [create service discovery handle]
iox_service_discovery_storage_t storage;
iox_service_discovery_t serviceDiscovery = iox_service_discovery_init(&storage);
//! [create service discovery handle]

iox_service_description_t searchResult[SEARCH_RESULT_CAPACITY];
uint64_t missedServices = 0U;
Expand All @@ -69,17 +77,23 @@ int main()

while (keepRunning)
{
//! [store number of front cameras]
uint32_t numberFrontCameras = 0U;
//! [store number of front cameras]

printf("\n=========================================\n");

printf("\nSearched for {'Radar', 'FrontLeft', 'Image'}. Found the following services:\n");
//! [find service and apply callable]
iox_service_discovery_find_service_apply_callable(
serviceDiscovery, "Radar", "FrontLeft", "Image", printSearchResult, MessagingPattern_PUB_SUB);
//! [find service and apply callable]

printf("\nSearched for {'Radar', *, *}. Found the following services:\n");
//! [search for all Radar services]
iox_service_discovery_find_service_apply_callable(
serviceDiscovery, "Radar", NULL, NULL, printSearchResult, MessagingPattern_PUB_SUB);
//! [search for all Radar services]

printf("\nSearched for {*, 'FrontLeft', *}. Found the following services:\n");
iox_service_discovery_find_service_apply_callable(
Expand All @@ -89,6 +103,7 @@ int main()
iox_service_discovery_find_service_apply_callable(
serviceDiscovery, NULL, "FrontRight", "Image", printSearchResult, MessagingPattern_PUB_SUB);

//! [search for all Camera services]
numberFoundServices = iox_service_discovery_find_service(serviceDiscovery,
"Camera",
NULL,
Expand All @@ -97,14 +112,17 @@ int main()
SEARCH_RESULT_CAPACITY,
&missedServices,
MessagingPattern_PUB_SUB);
//! [search for all Camera services]
printf("\nSearched for {'Camera', *, *}. Found the following services:\n");
for (uint64_t i = 0; i < numberFoundServices; ++i)
{
printSearchResult(searchResult[i]);
}

//! [search for all front camera services]
iox_service_discovery_find_service_apply_callable_with_context_data(
serviceDiscovery, "Camera", NULL, NULL, searchFrontDevices, &numberFrontCameras, MessagingPattern_PUB_SUB);
//! [search for all front camera services]
printf("\nFound %u front cameras\n", numberFrontCameras);

sleep_for(1000);
Expand Down

0 comments on commit 76d3348

Please sign in to comment.