Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Section 1: Overview

...


IARM-Bus is a platform agnostic Inter-process communication (IPC) interface. It allows applications to communicate with each other by sending Events or invoking Remote Procedure Calls. The common programming APIs offered by the RDK IARM-Bus interface is independent of the operating system or the underlying IPC mechanism.

Two applications connected to a same instance of IARM-Bus are able to exchange events or RPC calls. On a typical system, only one instance of IARM-Bus instance is needed. If desired, it is possible to have multiple IARM-Bus instances. However, applications connected to different buses will not be able to communicate with each other.Image Removed


 Image Added

1.1 Bus Daemon

Each Bus Instance is managed by a single Bus Daemon Process. The Bus Daemon oversees the activities on the bus and manage common resources competed by all connected applications. Applications requesting a shared resource must first firstly acquire Ownership from the Bus Daemon. Once it is done with the resource, the application it must release the ownership back to the Bus Daemon so that other applications can use the resource. The IARM Bus Daemon offers standard APIs to request and release ownership of a resource. In essenceEssence, a Bus Daemon itself is a regular application applications connected to the IARM-Bus with special privileges. It is the only entity that has knowledge of all applications connected to the bus, and has the authority of granting or denying resources.

1.2 Well-Known Name

Each application that connects connected to the bus must identify itself with a unique name. This name is considered well-known in that it is used by other applications to send events or invoke RPC calls published by the application. The well-known name thus is considered part of the public API interface published by the application. The Bus daemon's well-known name is "Daemon".

An application's well-known name is only visible to the connected bus that it connects to. When concatenated with the IARM-bus name com.comcast.rdk.iarm.bus, it becomes the application's universally unique identifier.

Section 2: Programming Guidelines

As explained above, IARM-Managers are IARM applications that provide a set of services. Bus Daemon is a special case of IARM-Manager. Other IARM managers include IR Manager, Power Manager, Manufacturer Manager, Device Settings Manager, System Manager.

Capabilities

  • Invoke methods in other processes via Remote Procedure Call (RPC).
  • Send interprocess messages.
  • Manage shared and exclusive access to resources.
  • Register for event notification.
  • Publish event notification to registered listeners.

Uses

fusion.ko – Kernel module. Provides communication channels via shared memory.

fusion.so – User Module. A primitive set of APIs for processes to communicate via IOCTL.

fusiondale.so – Application module. A high level IPC library built on fusion.so.

direct.so – Utility module.

Programming Guide

As explained above, IARM-Bus offers two basic functions:

Bus offers two basic functionalities:

  • Send Events to application.
  • Send events to application.
  • Invoke application's RPC methods.

Important note When developing IARM APIs, it is strongly recommended developers adopt the naming conventions suggested in this guideline.


 An IARM application Application that runs as a Linux linux daemon process is considered a manager componentManager Component. The IARM-Bus Daemon is a special manager Manager component that belongs to the IARM core. Such manager components normally register events Events and RPC methods for other applications to use.

 Important note Under iarm/template, a template implementation of a generic manager component Manager Component is provided. Developers Developer can make a copy of the templates and modify from it to suit their application needs. The template conforms to the guidelines explained in this section.

...

Directory

Files

$iarm

IARM Core, IARM Bus Daemon, and all IARM Manager Components

core

Core implementation of IARM framework. It is built into a shared library for all IARM applications to use.

core/include

Public headers exposed by IARM core. IARM application should only reference header files located here to use IARM-Bus APIs.

<mgr>

Manager's internal implementation. Header files listed here should NOT be referenced by any external components outside the <mgr> directory.

<mgr>/include

Public headers exposed by the managerManager. IARM applications uses the managerManager's events or RPC methods should only reference header files located here.

template

A Sample implementation of an a IARM manager componentManager Component. This provides a good starting point for developers to create their manager components. The developer can make a copy of the template and modify it to suit their application needs.

...


The IARM-Bus Library is ./core/libIARMBus.so. All IARM applications Applications must link to this library. 
In this document we use the implementation of IR Manager as our example. The source code of IR Manager is available at iarm/ir/. 
IR Manager is an application that publishes Remote Key events to other applications.

  • IR manager sends these IR events to other applications.
    • IARM_BUS_IRMGR_EVENT_IRKEY
  • The Event Data contains Key Code and Key Type of the pressed IR key.
    • int keyType;
    • int keyCode;
  • IR manager publishes two RPC Methods:
    • SetRepeatKeyInterval
    • GetRepeatKeyInterval
  • Other applications application can invoke these methods to determine how often a repeat key is sent when the IR key is held down own by the user.


We will use IR Manager's implementation to illustrate how to use IARM-Bus APIs to publish, send, receive and handle eventsEvents, as well as publish and invoke RPC Methods. 
This document explains the usage of IARM-Bus APIs with examplesby example. For a full API specification please refer to IARM's public header files or doxygen document.

2.1 How to Create, Send, and Receive Events

Declare Well-Known Name in Header File

Since all the events published by the application are tied to its well-known name, the application must make its well-known name available to other applications that wish to use its service. The well-known name can be thought of as the namespace. The the Namespace within which the application's events and RPC methods live within the namespace. This name must be declared in the application's public header file. In our example, this file is irMgr.h

 #define IARM_BUS_IRMGR_NAME "IRMgr"
  Naming Convention: IARM_BUS_<Manager>_NAME "Manager"

When the application initializes initialize with IARM-Bus, it provides its well-known name:

...

Considering the application's well-known name as a namespace name, an Event ID is used to uniquely identify the Event within the namespace. The Event IDs must be declared in the application's public header file, using C enumerations Enumerations and must start with value 0.

...

_EVENT_MAX must have the value of (Number Of Events Published + 1). This MAX value is used when registering all events to the IARM –Bus. 
An event may or may not have Event Data. If an event has event data, the data types must be declared so that the listeners of the events can process the data properly. The data structure should be a union of event data for all events that the application would send. For example, IR Manager's IR Event Data contains akeyType and KeyCode field.

...

Register Event to IARM-Bus

Before an event An Event must be Registered with IARM-Bus first before it can be sent out or listened to, it must be registered with IARM-Bus. The application that registers the event is considered the Owner of the event. During initialization, the owner can register all the events it will send to the bus. Once  
Now that both the event and event data are declared, the application can register all its events to the IARM-Bus. Note how _EVENT_MAX constant is used here to register all events in a single call.

...


 An application can listen for different events event with different event handlers. If a same event handler is used to listen for different events from different applications, a simple switch block can be used to further dispatch the events to their target processing.

  • use strcmp() to dispatch event by the sending application's name.
  • use switch to dispatch event by Event Id.

 The event handler in our example would contain the following block to dispatch IR key events:

 _My_Event_Handler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
{

/* Dispatch By Owner first */
if(strcmp(owner, IARM_BUS_IRMGR_NAME) == 0) {
/* Then Dispatch by Event ID */
switch(eventID) {
case IARM_BUS_IRMGR_EVENT_IRKEY:
/*Cast data to its target type */
IARM_Bus_IRMgr_EventData_t * = (IARM_Bus_IRMgr_EventData_t *) data;
/* Processing of Data */

}
}
else if(strcmp(owner, /some other application/) == 0) {
}
else {
}
}

Summary Of Events

 If an application wants to

...

Send events, it needs to

...

  • Follow the naming conventions recommended.
  • Register to IARM-Bus with its well-known name during initialization.
	IARM_Result_t IARM_Bus_Init(const char name);*
IARM_Result_t IARM_Bus_Connect(void);
  • Declare its event enumerations and event data types in public header file.
  • Register all its events during initialization using _EVENT_MAX:
	IARM_Result_t IARM_Bus_RegisterEvent(IARM_EventId_t maxEventId);
  • Send/Broadcast Events:
	IARM_Result_t IARM_Bus_BroadcastEvent(const char *ownerName, IARM_EventId_t eventId, void *data, size_t len); 


 If an application wants to receive and handle events , it needs to :

  • Register to IARM-Bus with its well-known name during initialization.
        IARM_Result_t IARM_Bus_Init(const char *name);
        IARM_Result_t IARM_Bus_Connect(void);
  • Register event handler :
        IARM_Result_t IARM_Bus_RegisterEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler);
  • Implement the handler.

2.2 How to Create and Invoke RPC Methods

Declare Well-Known Name in Header File

...

 #define IARM_BUS_IRMGR_NAME "IRMgr"
Naming Convention: IARM_BUS_<Manager>_NAME "Manager"

 When the application initializes initialize with IARM-Bus, it provides its well-known name:

...

Considering the application's well-known name as a namespace name, the method Method name is used to identify the RPC method within the namespace. Each method from a same owner has unique string name. This name must be declared in the application's public header file, so other applications may can refer to this method by its method name.

...

Register RPC Methods to IARM-Bus

A RPC method Method must be registered Registered with IARM-Bus first before it can be invoked. The application which that registers the RPC method is considered to be the Owner of the method. During initialization, the application can register all of the RPC methods it implements

...

 Here _SetRepeatInterval () is the actual implementation of the RPC method. All RPC methods take takes the signature of IARM_BusCall_t:

 typedef IARM_Result_t (*IARM_BusCall_t) (void *arg); 

 The owner of the RPC method Method provides its implementation. In irMgr.c, the implementation takes the following form:

...

Once an RPC is registered, other applications may application can invoke the method synchronously. For example, this invocation sets the key repeat interval to 200ms.

...

In summary, if an application wants to publish RPC methodsMethods, it needs to:

  • Follow the naming conventions recommended.
  • Register to IARM-Bus with its well-known name during initialization.
        IARM_Result_t IARM_Bus_Init(const char name);*
IARM_Result_t IARM_Bus_Connect(void);
  • Declare its RPC method names and argument types in public header file:
  • Register all its RPC methods during initialization:
        IARM_Result_t IARM_Bus_RegisterCall(const char *name, IARM_BusCall_t handler);
  • Invoke RPC Methods:
        IARM_Result_t IARM_Bus_Call(const char *ownerName, const char *methodName, void *arg, size_t argLen);

...

 Section 3: Decouples Applications from IARM


The RPC methods exposed via IARM can be called by multiple applications, so they are also named Multiple-App APIs. In contrast, Single-App APIs are regular C functions which may contract, the regular C functions that can only be invoked from within the same Linux process that implements the functionC functions are named Single-App APIs. Sometimes, it is desirable to decouple that the application is decoupled from such API differencesdifference. In this case, the developer should provide a generic API that can be linked to either a local C method or a RPC method at build time.
In our example, IR Manager exports RPC API "SetRepeatInterval". To invoke this method, the application executes:

...


 IRMgr_SetRepeatInterval(int newInterval)
{
IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
param.timeoutNewValue = 200;
IARM_Bus_Call (
IARM_BUS_IRMGR_NAME, /* Owner of the Method */
IARM_BUS_IRMGR_API_SetRepeatInterval,/* Name of Method */
(void )&param, / Parameter of Method */
sizeof(param)); /* Length of the Parameter */
)
}

3.1 Short-Term Approach

To invoke the same API, the application now calls IRMgr_SetRepeatInterval().
A quick approach to decouple the application from IARM is to define the generic API IRMgr_SetRepeatInterval() as an inline function. In our example, we would include this in the irMgr.h.

...


 In this approach, the application is decoupled from IARM. However, the application cannot use the same API for a Single-App version. This may be enough for most applications , which do who at this point does not need a single-app version of the same API.

3.2 Long-Term Approach

If an application may use the same API's Singlesingle-App app version, the following changes are required:needed.
To invoke the same API, application now calls IRMgr_SetRepeatInterval(), which must be implemented as an actual function that has external linkage.


 IRMgr_SetRepeatInterval(int newInterval)
{
IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
param. timeoutNewValue = 200;
IARM_Bus_Call (
IARM_BUS_IRMGR_NAME, /* Owner of the Method */
IARM_BUS_IRMGR_API_SetRepeatInterval,/* Name of Method */
(void )&param, / Parameter of Method */
sizeof(param)); /* Length of the Parameter */
)
}
In the IR Manager's implementation of RPC Method, we have already learned from previous )
sections }

...

that this RPC method is registered with
 
 IARM_Result_t IARM_Bus_RegisterCall(
_BUS_IRMGR_API_SetRepeatInterval, /* RPC Method Name */
_SetRepeatInterval /* RPC Method Implementation*/
)

...


 static IARM_Result_t _SetRepeatInterval(void *arg)
{
/* First cast the argument to its target type */
IARM_Bus_IRMgr_SetRepeatInterval_Param_t
*param = (IARM_Bus_IRMgr_SetRepeatInterval_Param_t *)arg;
IRMgr_SetRepeatInterval(parma->newInterval);
}


Where  Where IRMgr_SetRepeatInterval()changes the actual settings. 
Now, we have at our hands two implementations of a same generic API IRMgr_SetRepeatInterval:

...


 This function is linked into library libirMgrCli.so.


 The Manager Version/Single-App version:

 IRMgr_SetRepeatInterval(int newInterval) 
{
     /* Change the Actual Settings */
}


This  This function is linked into library libirMgr.so.


The  The application can then choose which implementation to link to at build time , based on its needs. To use the Multimulti-App app version of API, the application links to libirMgrCli.so. To use the Singlesingle-App app version of the API, the application links to libirMgr.so. In either choice, the application is no longer coupled to IARM. The following diagrams demonstrate the linkage relationship between applications and the generic API.

TODO: INSERT A GOOD DIAGRAMRedraw the diagram


 Image RemovedImage Added 
Image RemovedImage Added

Section 4: Porting layer of IARM-Bus


Most IARM Applications are not manager componentsManager Components. Rather , they are connected to IARM bus only to utilize the service provided by various IARM-Bus Managers. These applications can maximize maximum their platform independence independency by interfacing to only the common APIs of the IARM Bus.


Meanwhile Meanwhile, depending on the events being published or the dependency that an RPC method implementation may have, some part of an IARM manager component Manager Component may be platform specific.
It is up to the developer of the manager component to design craft out and abstract the platform specific portion of the manager implementation. In the IR Manager example previously we used, the manager receives IR signals from PIC drivers in different ways on different platforms. This difference is abstract to a PLAT_API interface defined in an internal header file plat.h. It , and allows most of IR Manager implementation to remain platform agnostic. 

Section 5: Core IARM-Bus Manager Components


By default, the IARM-Bus has the following manager componentsManager Components. The published events and RPC methods from these manager components can be found in their public header files.
On a standard system, you should see the following 3 processes running before executing your own application.

ps -aef|grep Mgr*
root 1042 1 0 00:00 ? 00:00:00 ./IARMDaemonMain
root 1083 1 0 00:00 ? 00:00:00 ./irMgrMain
root 1117 1 0 00:00 ? 00:00:00 ./pwrMgrMainIARM

Bus Daemon

The executable name of the bus daemon Executable name is IARMDaemonMain. The IARM bus daemon Bus Daemon is a manager component Manager Component with special privilegespreviledges
It is important to note that this Important note:This Daemon component must be run before any other IARM-Bus application. The IR Manager's executable ManagerExecutable name is irMgrMain. This manager receives IR signals from the driver and dispatches dispatch it to all registered listeners on IARM Bus. The standard IR key codes sent by IR Manager are listed in core/ir/comcastIRKeyCodes.h.

Power Manager

The power manager's executable Executable name is pwrMgrMain. This manager monitors Power IR key events and reacts react to power state changes based on Comcast on RDK Power Management Specification. It dispatches Power Mode Change Events events to IARM-Bus. All listeners should release releases resources when entering POWER OFF/STANDBY state and will reacquire them when entering POWER ON state.

Section 6: Troubleshooting


 Before you try out a new IARM-Application, please make sure the following components are properly running on your box:

...

  • libIARMBus.so is at a known library path.
  • Daemon process IARMDaemonMain is running.
  • ps –aef|grep IARMDaemonMain

You see log message "Bus Daemon HeartBeat" on console or /opt/logs/uimgr_log.txt.