# C language support

Source: [https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html)

## Files Generated

For the C language, five files are generated by ifgen from the component interface file:

- **client interface header file (interface.h)** - C definitions for the
                    interface. This file should be included by any C source files that want to use
                    the interface.
- **server header file (server.h)** - C definitions for the server interface.
                    There is some duplication between this file and the interface file, but it also
                    contains definitions that are not part of the public client interface. This file
                    should be included by any C source files that want to implement the
                    interface.
- **local header file (local.h)** - local header file provides common
                    definitions for the client and server implementations. This file should only be
                    included by the client and server implementation files.
- **client implementation file (client.c)** - implements all of the interface
                    functions. These functions handle the details of sending messages to the server,
                    and processing the responses.
- **server implementation file (server.c)** - implements handlers for all the
                    interface functions. These handlers receive the message from the client side,
                    call the corresponding real implementation of the function, and generate any
                    responses back to the client side.

Note: Client and server implementation files are provided to support client/server
                        IPC implementations.

## Handler Parameters in C

A handler parameter can be used in both events and regular functions. This is how a
                handler parameter for a function in an interface file is mapped to actual C
                definitions (based on the [API File Sample Output](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html#concept.api_files_c__section_ec3_x3v_v5b)).

    FUNCTION int32 UseCallback
    (
        uint32 someParm IN,
        TestAHandler handler
    );Copy to clipboard

This results in the function definition:

    int32_t UseCallback
    (
        uint32_t someParm,
        TestAHandlerFunc_t handlerPtr,
        void* contextPtr
    );Copy to clipboard

A `contextPtr` parameter has been automatically added to the
                definition of the function. This `contextPtr` will be passed back to
                the specified handler function when it is invoked. If the
                    `contextPtr` is not needed, then NULL can be used.

## Events in C

This is how an event in an interface file is mapped to actual C definitions (based on
                the [API File Sample Output](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html#concept.api_files_c__section_ec3_x3v_v5b)).

    EVENT TestA
    (
        uint32 data,
        TestAHandler myHandler
    );Copy to clipboard

This results in one type definition and two function definitions:

    typedefstruct TestAHandler* TestAHandlerRef_t;
    
    TestAHandlerRef_t AddTestAHandler
    (
        uint32_t data,
        TestAHandlerFunc_t myHandlerPtr,
        void* contextPtr
    );
    
    void RemoveTestAHandler
    (
        TestAHandlerRef_t addHandlerRef
    );Copy to clipboard

The parameters from the event definition are used in the ADD\_HANDLER function. This
                is used to register the given handler for events. The REMOVE\_HANDLER function does
                not take any additional parameters, other than the reference returned by the
                ADD\_HANDLER function.

A `contextPtr` parameter has been automatically added to the
                definition of the ADD\_HANDLER function. The `contextPtr` passed to
                the ADD\_HANDLER function, will be passed back to the registered handler function. If
                the `contextPtr` is not needed, then NULL can be used.

## Handlers in C

This is how a handler in an interface file is mapped to actual C definitions (based
                on the [API File Sample Output](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html#concept.api_files_c__section_ec3_x3v_v5b)):

    HANDLER TestAHandler
    (
        int32 x
    );Copy to clipboard

This results in a type definition for the handler function pointer:

    typedef void (*TestAHandlerFunc_t)
    (
        int32_t x,
        void* contextPtr
    );Copy to clipboard

A `contextPtr` parameter has been automatically added to the
                definition of the handler function pointer. The `contextPtr` passed
                to a regular function or ADD\_HANDLER function (see section [Handler Parameters in C](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html#concept.api_files_c__section_pb3_x3v_v5b) or [Events in C](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files_c.html#concept.api_files_c__section_sb3_x3v_v5b), respectively) will be passed
                back to the handler function. If the `contextPtr` is not needed, then
                NULL can be used.

## Client Specific Functions

The API files provide the following client specific functions:

- `TryConnectService()`
- `ConnectService()`
- `DisconnectService()`
- `SetServerDisconnectHandler()`
- `SetNonExitServerDisconnectHandler()`

If you wish to check that the API that you are connecting to is available or not, use
                    `TryConnectService()` first. This function must be called first,
                and while the `ConnectServce()` function is called automatically for
                the main thread, all other threads should use this function to make sure that they
                can successfully connect before they open a connection.

To use a service, a client must connect to the server using
                    `ConnectService()`. This connection is only created for the
                current thread. Other threads must also call `ConnectService()` to
                use the service.

For the main thread, `ConnectService()` is usually automatically
                called when the client app is initialized. Disable this by using the .cdef provides
                    [\[manual-start\]](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_cdef.html#concept.def_files_cdef__section_twd_vz5_v5b).

If a client app uses multiple services, multiple `ConnectService()`
                functions need to be called; each function uses an appropriate prefix to distinguish
                these clients. If multiple client apps are used, each app must be initialized
                separately, using the appropriate `ConnectService()` function.

The `DisconnectService()` function closes a connection to the server.
                It only closes the current thread connection; it must be called separately for each
                thread using a service. If a thread wants to use the service again, it must call
                    `ConnectService()` to re-connect. When the app exits, all
                connections for all threads are automatically closed. A thread only needs to use
                    `DisconnectService()` when it wants to disconnect from a service
                while the app is still running (e.g., no longer needs the service so it can conserve
                resources). To handle disconnections, use
                    `SetServerDisconnectHandler()` to exit with LE\_FATAL. If an app
                wants to continue without exiting, use
                    `SetNonExitServerDisconnectHandler()` to register a handler to
                re-establish the connection when needed.

## Server Specific Functions

These are server specific functions:

    le_msg_ServiceRef_t GetServiceRef
    (
        void
    );
    
    le_msg_SessionRef_t GetClientSessionRef
    (
        void
    );
    
    void AdvertiseService(
        void
    );Copy to clipboard

To provide a service, the server must advertise the service to any interested clients
                using `AdvertiseService()`. This is usually automatically called
                during the initialization of the server daemon. This can be disabled using the .cdef
                provides [\[manual-start\]](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_cdef.html#concept.def_files_cdef__section_twd_vz5_v5b).

If a server provides multiple services, multiple `AdvertiseService()`
                functions need to be called; each function will have an appropriate prefix to
                distinguish each service.

The `GetServiceRef()` function is used to get the server session
                reference for the current service. It's required if the server uses any of the
                server-specific Low-level Messaging API functions for this
                service.

For example, le\_msg\_AddServiceCloseHandler can be used
                by the server to register a close handler whenever a client closes its connection.
                This may be needed to cleanup client specific data maintained by the server.

`GetClientSessionRef()` function is used to get the client session
                reference for the current service. This client session is only valid while executing
                the server-side function that implements an interface function. Once this
                server-side function returns, the client session can no longer be retrieved.
                    `GetClientSessionRef()` is needed if the server wants to call any
                of the client-specific Low-level Messaging API functions for this
                service.

For example, le\_msg\_GetClientUserId() can be used by
                the server to determine the UserId of the client using the service, which allows the
                server to perform any necessary UserId based authentication.

## Asynchronous Server

There are two alternatives to implement the server-side functionality.

The default case is where each server-side function has the same interface as the
                client-side function. The server-side function takes the IN parameters, and returns
                the OUT parameters and function result when the function exits.

In the async-server case, the server-side function doesn't necessarily return the OUT
                parameters and function result when it exits. Instead, there's a separate
                    `Respond` function for each server-side function. The OUT
                parameters and function result are returned by passing these values to the
                    `Respond` function. The `Respond` function can be
                called at any time, normally after the server-side function has exited.

Regardless of how the server-side functions are implemented, the client-side function
                waits until the OUT parameters and function result are returned.

The async-server functionality is not enabled by default. Enable it by using the
                .cdef provides [\[async\]](https://docs.qualcomm.com/doc/80-41102-3/topic/def_files_cdef.html#concept.def_files_cdef__section_vwd_vz5_v5b).

## Sending File Descriptors

If a file descriptor is sent over the TelAF IPC, the underlying messaging
                infrastructure would close the file descriptor. Therefore, after the file descriptor
                is passed as an "IN parameter" to a function that uses TelAF IPC, the file
                descriptor should not be explicitly closed. If the file descriptor is needed after
                calling such function, it should be duplicated before being passed to the
                function.

## API File Sample Output

Here's the generated client interface header file for the defn.api file.

    /*
     * ====================== WARNING ======================
     *
     * THE CONTENTS OF THIS FILE HAVE BEEN AUTO-GENERATED.
     * DO NOT MODIFY IN ANY WAY.
     *
     * ====================== WARNING ======================
     */

    #ifndef DEFN_H_INCLUDE_GUARD
    #define DEFN_H_INCLUDE_GUARD

    #include "legato.h"

    //---------------------------------------------------------
    /**
     * Example of nested .api file
     */
    //---------------------------------------------------------
    #define DEFN_SIX 6

    #endif // DEFN_H_INCLUDE_GUARD
    
    Copy to clipboard

Here's the generated client interface header file for the common.api file.

    /*
     * ====================== WARNING ======================
     *
     * THE CONTENTS OF THIS FILE HAVE BEEN AUTO-GENERATED.
     * DO NOT MODIFY IN ANY WAY.
     *
     * ====================== WARNING ======================
     */
    
    /**
     * Common definitions potentially used across multiple .api files
     */
    
    #ifndef COMMON_H_INCLUDE_GUARD
    #define COMMON_H_INCLUDE_GUARD

    #include "legato.h"
    
    // Interface specific includes
    #include "defn_interface.h"

    //------------------------------------------------------------
    /**
     * Definition example
     */
    //------------------------------------------------------------
    #define COMMON_FOUR 4

    //------------------------------------------------------------
    /**
     * Example of using previously DEFINEd symbol within an imported file.
     */
    //------------------------------------------------------------
    #define COMMON_TEN 10

    //------------------------------------------------------------
    /**
     * Reference example
     */
    //------------------------------------------------------------
    typedef struct common_OpaqueReference* common_OpaqueReferenceRef_t;

    //------------------------------------------------------------
    /**
     * ENUM example
     */
    //------------------------------------------------------------
    typedef enum
    {
        COMMON_ZERO,
            ///< first enum
    
        COMMON_ONE,
            ///< second enum
    
        COMMON_TWO,
            ///< third enum
    
        COMMON_THREE
            ///< fourth enum
    }
    common_EnumExample_t;

    //------------------------------------------------------------
    /**
     * BITMASK example
     */
    //------------------------------------------------------------
    typedef enum
    {
        COMMON_BIT0 = 0x1,
            ///< first
    
        COMMON_BIT1 = 0x2,
            ///< second
    
        COMMON_BIT2 = 0x4
            ///< third
    }
    common_BitMaskExample_t;

    #endif // COMMON_H_INCLUDE_GUARD
    
    Copy to clipboard

Here's the generated client interface header file for the example.api file.

    /*
     * ====================== WARNING ======================
     *
     * THE CONTENTS OF THIS FILE HAVE BEEN AUTO-GENERATED.
     * DO NOT MODIFY IN ANY WAY.
     *
     * ====================== WARNING ======================
     */
    
    /**
     * Example API file
     */
    
    #ifndef EXAMPLE_H_INCLUDE_GUARD
    #define EXAMPLE_H_INCLUDE_GUARD

    #include "legato.h"
    
    // Interface specific includes
    #include "defn_interface.h"
    #include "common_interface.h"

    //------------------------------------------------------------
    /**
     * Connect the client to the service
     */
    //------------------------------------------------------------
    void example_ConnectService
    (
        void
    );
    
    //------------------------------------------------------------
    /**
     * Disconnect the client from the service
     */
    //------------------------------------------------------------
    void example_DisconnectService
    (
        void
    );

    //------------------------------------------------------------
    
    //------------------------------------------------------------
    #define EXAMPLE_TEN 10

    //------------------------------------------------------------
    
    //------------------------------------------------------------
    #define EXAMPLE_TWENTY 20

    //------------------------------------------------------------
    
    //------------------------------------------------------------
    #define EXAMPLE_SOME_STRING "some string"

    //------------------------------------------------------------
    /**
     * Reference type used by Add/Remove functions for EVENT 'example_TestA'
     */
    //------------------------------------------------------------
    typedef struct example_TestAHandler* example_TestAHandlerRef_t;

    //------------------------------------------------------------
    /**
     * Handler definition
     *
     * @param x
     *        First parameter for the handler
     *        Second comment line
     * @param contextPtr
     */
    //------------------------------------------------------------
    typedef void (*example_TestAHandlerFunc_t)
    (
        int32_t x,
        void* contextPtr
    );
    
    //------------------------------------------------------------
    /**
     * Add handler function for EVENT 'example_TestA'
     *
     * This event provides an example of an EVENT definition
     */
    //------------------------------------------------------------
    example_TestAHandlerRef_t example_AddTestAHandler
    (
        uint32_t data,
            ///< [IN]
            ///< Used when registering the handler i.e. it is
            ///< passed into the generated ADD_HANDLER function.
    
        example_TestAHandlerFunc_t handlerPtr,
            ///< [IN]
    
        void* contextPtr
            ///< [IN]
    );
    
    //------------------------------------------------------------
    /**
     * Remove handler function for EVENT 'example_TestA'
     */
    //------------------------------------------------------------
    void example_RemoveTestAHandler
    (
        example_TestAHandlerRef_t addHandlerRef
            ///< [IN]
    );
    
    //------------------------------------------------------------
    /**
     * Function takes all the possible kinds of parameters, but returns nothing
     */
    //------------------------------------------------------------
    void example_AllParameters
    (
        common_EnumExample_t a,
            ///< [IN]
            ///< first one-line comment
            ///< second one-line comment
    
        uint32_t* bPtr,
            ///< [OUT]
    
        const uint32_t* dataPtr,
            ///< [IN]
    
        size_t dataNumElements,
            ///< [IN]
    
        uint32_t* outputPtr,
            ///< [OUT]
            ///< some more comments here
            ///< and some comments here as well
    
        size_t* outputNumElementsPtr,
            ///< [INOUT]
    
        const char* label,
            ///< [IN]
    
        char* response,
            ///< [OUT]
            ///< comments on final parameter, first line
            ///< and more comments
    
        size_t responseNumElements
            ///< [IN]
    );
    
    //------------------------------------------------------------
    /**
     * Test file descriptors as IN and OUT parameters
     */
    //------------------------------------------------------------
    void example_FileTest
    (
        int dataFile,
            ///< [IN]
            ///< file descriptor as IN parameter
    
        int* dataOutPtr
            ///< [OUT]
            ///< file descriptor as OUT parameter
    );
    
    //------------------------------------------------------------
    /**
     * Function that takes a handler parameter
     */
    //------------------------------------------------------------
    int32_t example_UseCallback
    (
        uint32_t someParm,
            ///< [IN]
    
        example_TestAHandlerFunc_t handlerPtr,
            ///< [IN]
    
        void* contextPtr
            ///< [IN]
    );

    #endif // EXAMPLE_H_INCLUDE_GUARDCopy to clipboard

**Parent Topic:** [API files](https://docs.qualcomm.com/doc/80-41102-3/topic/api_files.html)

Last Published: Apr 23, 2025

[Previous Topic
Syntax](https://docs.qualcomm.com/bundle/publicresource/80-41102-3/topics/api_files_syntax.md) [Next Topic
Logging](https://docs.qualcomm.com/bundle/publicresource/80-41102-3/topics/logging.md)