C Language Support

Interface Generation Tool
Handlers in C
Client Specific Functions
Server Specific Functions

For the C language, five files are generated 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.

Interface Generation Tool

The ifgen usage details are generated by the -h or --help options:

usage: ifgen [-h] [--gen-all] [--gen-interface] [--gen-local] [--gen-client]
             [--gen-server-interface] [--gen-server] [--async-server]
             [--name-prefix NAMEPREFIX] [--service-tag SERVICETAG]
             [--file-prefix FILEPREFIX] [--user-include USERINCLUDE]
             [--output-dir OUTPUTDIR] [--hash] [--dump]
             FILE

Interface Code Generator

positional arguments:
  FILE                  name of interface file

optional arguments:
  -h, --help            show this help message and exit
  --gen-all             generate all files; overrides individual file options
  --gen-interface       generate interface header file
  --gen-local           generate local header file
  --gen-client          generate client IPC implementation file
  --gen-server-interface
                        generate server interface header file
  --gen-server          generate server IPC implementation file
  --async-server        generate asynchronous-style server functions
  --name-prefix NAMEPREFIX
                        optional prefix for generated functions/types
  --service-tag SERVICETAG
                        optional short name for service
  --file-prefix FILEPREFIX
                        optional prefix for generated files
  --user-include USERINCLUDE
                        optional C include file for extra definitions
  --output-dir OUTPUTDIR
                        optional output directory for generated files
  --hash                print SHA256 hash for interface; NO files are
                        generated
  --dump                print info on parsed functions; NO files are generated

--async-server option

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 when the function exits.

In the async-server case, the server-side function doesn't necessarily return the OUT parameters when it exits. Instead, there's a separate Respond function for each server-side function. The OUT parameters are returned by passing these OUT parameters 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 are returned.

Note:
In the async-server option only, OUT parameters are both the function return value and any explicit OUT parameters defined for the function.

Handlers in C

This is how a handler in an interface file is mapped to actual C definitions (based on the Interface File Sample).

HANDLER TestA
{
    HANDLER_PARAMS
    (
        int32 x
    );
        
    ADD_HANDLER_PARAMS ();
};

This results in two type definitions and two function definitions:

typedef void (*TestAFunc_t)
(
    int32_t x,
    void* contextPtr
);

typedef struct TestA* TestARef_t;

TestARef_t AddTestA
(
    TestAFunc_t handlerPtr,
    void* contextPtr
);

void RemoveTestA
(
    TestARef_t addHandlerRef
);

Required parameters for the two functions are added automatically. Since ADD_HANDLER_PARAMS parameterList wasn't given, additional parameters weren't added to the ADD_HANDLER function.

A contextPtr parameter has been automatically added to both the definition of the function pointer, and the definition of the ADD_HANDLER function. The contextPtr passed to the ADD_HANDLER function, will be passed back to the HANDLER function. If the contextPtr is not needed, then NULL can be used.

Client Specific Functions

These are client-specific functions:

void StartClient
(
    const char* serviceInstanceName
);

void StopClient
(
    void
);

To use a service, an initial connection to the server must be created using StartClient(). Only needs to be called once per process; normally done in the COMPONENT_INIT function of the client application. This creates the connection for the main thread. Connections used by other threads are created automatically if other threads use a function provided by a service.

If a client application uses multiple services, multiple StartClient() functions need to be called; each function will have an appropriate prefix to distinguish these clients. If multiple client applications are used, each application must be initialized separately, using the appropriate StartClient() function.

The StopClient() function is used to close a connection to the server. It only closes the connection for the current thread, so must be called separately for each thread that uses a service. At some point later, if a thread starts to use a service, then the connection will be automatically re-created for that thread.

Server Specific Functions

These are server-specific functions:

le_msg_ServiceRef_t GetServiceRef
(
    void
);

le_msg_SessionRef_t GetClientSessionRef
(
    void
);

void StartServer
(
    const char* serviceInstanceName
);

To provide a service, the server must advertise the service to any interested clients using StartServer(). Should be called in the COMPONENT_INIT function of the server daemon implementation.

If a server provides multiple services, multiple StartServer() 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. Required if the server uses any of the server-specfic Low-Level Messaging API functions for this service.

For example, le_msg_SetServiceCloseHandler 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.


Copyright (C) Sierra Wireless, Inc. 2014. All rights reserved. Use of this work is subject to license.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines