# How to use services correctly in libcanard

**URL:** <https://forum.opencyphal.org/t/how-to-use-services-correctly-in-libcanard/927>\
**Category:** Libcanard\
**Created:** [August 23, 2020, 8:21am UTC](https://forum.opencyphal.org/t/how-to-use-services-correctly-in-libcanard/927 "2020-08-23T08:21:13Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 23, 2020, 9:01am UTC](https://forum.opencyphal.org/t/how-to-use-services-correctly-in-libcanard/927/2 "2020-08-23T09:01:52Z")

</div>

Not quite. See, we have two kinds of communication: messages and services. Messages can be published and subscribed to; services can be invoked (or called) and provided (or served). You can’t “publish” a service call or “subscribe” to a service, it doesn’t make sense. In Libcanard, there is a bit of an implementation-specific terminology mishap: it uses “subscribe” in the sense of “tell the library that the application wants to receive this kind of transfers”; the mishap is because I couldn’t find a better word to use. Maybe I should have used “listen” instead, like `canardRxListen`? I wonder if we should change it.

So if you want to provide a service, you tell the library to receive service request transfers, like this:

```auto
// Configure the library to listen for register access service requests.
CanardRxSubscription srv_register_access;
(void) canardRxSubscribe(&canard,
                         CanardTransferKindRequest,
                         RegisterAccessServiceID,
                         1024U, // Larger buffers are OK.
                         CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
                         &srv_register_access);

```

Then you handle the calls like this:

```auto
// Process received frames, if any.
CanardFrame rxf;
uint8_t buffer[64];
while (socketcanPop(sock, &rxf, sizeof(buffer), buffer, 1000) > 0) // Error handling not implemented
{
    CanardTransfer transfer;
    if (canardRxAccept(&canard, &rxf, 0, &transfer))
    {
        if ((transfer.transfer_kind == CanardTransferKindRequest) &&
            (transfer.port_id == RegisterAccessServiceID))
        {
            handleRegisterAccess(&canard, &transfer);
        }
        free((void*) transfer.payload);
    }
}

```

```auto
static void handleRegisterAccess(CanardInstance* const canard, const CanardTransfer* const request_transfer)
{
    <... business logic not shown ...>
    // Send the response back. Make sure to re-use the same priority and transfer-ID.
    CanardTransfer response_transfer = *request_transfer;
    response_transfer.transfer_kind = CanardTransferKindResponse;
    response_transfer.payload_size = response_size;
    response_transfer.payload = response;
    (void) canardTxPush(canard, &response_transfer);
}

```

When invoking a service, you inverse the logic: listen for service response transfers and emit service request transfers. When receiving the responses, match them by their transfer-ID value.

The examples above have been copy-pasted from this demo: [Automatic configuration of port identifiers](https://forum.opencyphal.org/t/automatic-configuration-of-port-identifiers/840/3)

---

_[View the full topic](https://forum.opencyphal.org/t/how-to-use-services-correctly-in-libcanard/927)._
