1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# 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/icediscovery).
## Expected Output
[](https://asciinema.org/a/476732)
## Code walkthrough
### Offer services
We create several publishers 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 publishers,
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(service.instanceString, "FrontLeft", IOX_CONFIG_SERVICE_STRING_SIZE) == 0
|| strncmp(service.instanceString, "FrontRight", 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>
|