For the C language, five files are generated from the component interface file:
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] [--file-prefix FILEPREFIX]
[--service-name SERVICENAME] [--output-dir OUTPUTDIR]
[--get-import-list] [--import-dir IMPORTDIRS]
[--no-default-prefix] [--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;
defaults to input filename
--file-prefix FILEPREFIX
optional prefix for generated files; defaults to input
file name
--service-name SERVICENAME
optional service instance name; defaults to input file
name
--output-dir OUTPUTDIR
optional output directory for generated files
--get-import-list print out the list of imported files
--import-dir IMPORTDIRS
optional directory for imported files; may be given
multiple times
--no-default-prefix do not use default file or name prefix if none is
specified
--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.
This is how a handler in an interface file is mapped to actual C definitions (based on the API 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.
These are client-specific functions:
void ConnectService
(
void
);
void DisconnectService
(
void
);
To use a service, a client must connect to the server using ConnectService(). This connection is only created for the current thread, so any other threads that want to use the service must also call ConnectService(). For the main thread, ConnectService() is usually automatically called during the initialization of the client application. This can be disabled using the manual-start option. See the .cdef Requires section for details.
If a client application uses multiple services, multiple ConnectService() 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 ConnectService() function.
The DisconnectService() 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 wants to use the service again, then it must call ConnectService() to re-connect the service.
These are server-specific functions:
le_msg_ServiceRef_t GetServiceRef
(
void
);
le_msg_SessionRef_t GetClientSessionRef
(
void
);
void AdvertiseService
(
void
);
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] Option.
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. 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.
Here's the generated client interface header file for the defn.api file from API File Sample
/* * ====================== 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
Here's the generated client interface header file for the common.api file from API File Sample
/*
* ====================== 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
Here's the generated client interface header file for the example.api file from API File Sample
/*
* ====================== 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 for example_TestA handler ADD/REMOVE functions
*/
//--------------------------------------------------------------------------------------------------
typedef struct example_TestA* example_TestARef_t;
//--------------------------------------------------------------------------------------------------
/**
* Handler definition
*
* @param x
* First parameter for the handler
* Second comment line
* @param contextPtr
*/
//--------------------------------------------------------------------------------------------------
typedef void (*example_TestAFunc_t)
(
int32_t x,
void* contextPtr
);
//--------------------------------------------------------------------------------------------------
/**
* example_TestA handler ADD function
*/
//--------------------------------------------------------------------------------------------------
example_TestARef_t example_AddTestA
(
example_TestAFunc_t handlerPtr,
///< [IN]
void* contextPtr
///< [IN]
);
//--------------------------------------------------------------------------------------------------
/**
* example_TestA handler REMOVE function
*/
//--------------------------------------------------------------------------------------------------
void example_RemoveTestA
(
example_TestARef_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
);
#endif // EXAMPLE_H_INCLUDE_GUARD
Copyright (C) Sierra Wireless, Inc. 2014. Use of this work is subject to license.