All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Hello IPC

Lets explore how to use IPC between components:

  • Define a simple interface protocol that clients can use to ask servers to "Greet".
  • Create a server that prints "Hello world" whenever a client asks it to "Greet",
  • Create a client that asks the server to "Greet",

Here's what it looks like at runtime:

HelloIPC.png

When we show the static view of components inside executables, it looks like this:

HelloIPCWithComponents.png

Note that each interface has

  • an interface protocol
  • a friendly name.

In our example, the client and server both use the same friendly name "hello" for their interfaces, and of course, they both must use the same protocol, or they wouldn't be able to communicate with each other.

Getting Started

First, let's create a directory for our little project and change directories into there:

$ mkdir helloIPC
$ cd helloIPC

Defining the Interface Protocol

Next, we define the interface protocol to be used between the client and the server.

To create our function-call API, we create a definition file called "greet.api".

$ gedit greet.api

Put the following inside greet.api:

FUNCTION Greet
(
);

This declares a function called "Greet" that takes no arguments and returns nothing.

Creating the Server

Next we create a server component called "greetServer" that offers a greeting service called "hello" that can be accessed using our simple "greet" API. We do this by creating a file called "Component.cdef" in a new directory called "greetServer".

$ mkdir greetServer
$ gedit greetServer/Component.cdef
Note
Keeping components in separate directories from each other is a requirement of the framework.

greetServer/Component.cdef should contain the following:

export:
hello = greet.api
sources:
greetServer.c

This declares that the component named "greetServer" (the name of the directory is the name of the component) exports a service called "hello" that is accessed using the API defined in "greet.api", where the source code can be found in the file greetServer.c.

Note
The source code file name extension is used to determine the programming language that it is written in.

To implement the server (in C), create a file "greetServer/greetServer.c":

$ gedit greetServer/greetServer.c

Make it contain the following:

#include "legato.h"
#include "interfaces.h"
void hello_Greet(void)
{
LE_INFO("Hello world.");
}
COMPONENT_INIT
{
}

The file "interfaces.h" will be auto-generated based on the contents of greet.api and greetServer's Component.cdef. It will contain a prototype of the function hello_Greet(), which we implemented in greetServer.c.

The function hello_Greet() will be called when a client binds to our "hello" service and calls the function Greet(). The name "hello_Greet" follows this pattern:

<export-name> '_' <api-function-name>

The <export-name> is the name given to the exported interface. In our example, it is the name "hello" before the '=' in the line "hello = greet.api".

Note
If you forget to implement a service function on the server or if you give it the wrong name, the link stage will fail and complain that the symbol is unresolved, so you'll know that you missed a function and you'll be able to see what the correct name of the function should be.

Creating the Client

Now that we have a server, let's create a client to use its service. First, create a directory for the greetClient component and a file in it called "Component.cdef".

$ mkdir greetClient
$ gedit greetClient/Component.cdef

greetClient/Component.cdef should contain:

import:

    hello = greet.api

sources:

    greetClient.c

To implement the client using C, create a file called "greetClient/greetClient.c":

$ gedit greetClient/greetClient.c

Make it contain the following:

#include "legato.h"
#include "interfaces.h"
COMPONENT_INIT
{
hello_Greet();
}

The "interfaces.h" file that the client includes is a different one than the one that the server uses. This one is specially generated for the client based on the contents of greetClient/Component.cdef and greet.api.

In the client, we use the component initializer to call hello_Greet() at start-up.


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