Device Manager Bundle

The Device Manager Bundle attaches appropriate drivers to the devices currently available in the framework. This bundle provides an implementation of a device manager and complies with the Device Access Specification which is a part of the OSGi Service Platform Service Compendium Release 4.

Contents:


Bundle Information

Bundle JAR

The Device Manager Bundle JAR file is called devicem.jar, and is found in bundles.

Import

Package Exporter Description
com.prosyst.mbs.framework.event System Bundle/
ProSyst Util Full Bundle
The event thread utility for asynchronous notification of listeners.
com.prosyst.mbs.services.db DB Bundle The DB Manager service for storing data in a database.
com.prosyst.util.hash System Bundle/
ProSyst Util Full Bundle
The hashtable utilities for storage of numeric data.
com.prosyst.util.pcommands ProSyst Util Bundle /
ProSyst Util Full Bundle
The pluggable commands API to plug commands in the framework console.
com.prosyst.util.ref The log utility that redirects log messages to the OSGi Log Service and to the system output.
com.prosyst.util.time  
com.prosyst.util.timer ProSyst Util Bundle /
ProSyst Util Full Bundle
The Timer service which is capable of sending notifications over a certain period of time.
org.osgi.service.cm OSGi Library Bundle The API for developing configurable properties through the OSGi Configuration Admin, implemented by the Config Bundle.
org.osgi.service.device The API interfaces of the Device Access Specification.
org.osgi.util.tracker The OSGi Service Tracker utility for enhanced tracking of services.

Export

com.prosyst.mbs.services.device - contains components for receiving events related to the device attachment process.

Principles of Work

The Device Manager Bundle implements the device manager functionality defined by the OSGi Device Access Specification.

The device manager functionality can be conveniently applied to systems requiring hot device plug-and-play. The device manager allows for automated device detection as well as for automatic driver download and attachment of drivers to devices. The device manager paradigm delivers vendor neutrality, ability for an OSGi platform to run continuously without the need of restart, and possibility for dynamic driver update. The device manager operation model can be used in a variety of low-level network technologies - USB, EHS, X10, LON, etc.

Device Service

A Device service stands for a representation of a physical device in a LAN. A single device may have multiple Device services.

A bundle developer has two options for registering a Device service:

The following properties, declared as org.osgi.service.device.Constants fields, can be defined at Device service registration:

A Device service should also provide the org.osgi.framework.Constants.SERVICE_PID registration property, which represents the Service Persistent ID (PID), which must be unique within the scope of the parent OSGi framework.

Driver Service

A physical device may have one or more valid representations. Drivers are responsible for supplying such representations within the OSGi framework. Drivers are several types: base, refining, network, composite, referring, bridging, multiplexing and pure consuming. This classification is abstract and more information about the features of each type is available in the OSGi Device Access Specification.

A driver should be registered as a service in the framework under the org.osgi.service.device.Driver interface. Each Driver service should specify an org.osgi.service.device.Constants.DRIVER_ID property with a unique value. This ID should be associated with the behavior of the driver and it should start with the reverse form of the domain name of its vendor.

Driver Locator Service

Driver locators enable dynamic downloading of drivers and are one of the essential units that the device manager manipulates. They are capable of finding and loading drivers for a specific Device service. To declare a driver locator, a bundle developer should implement the org.osgi.service.device.DriverLocator interface and register it as a service in the framework.

Driver Selector Service

A driver selector chooses the best driver for a device by using a specific algorithm for selection. The device manager has a default selection mechanism, but sometimes it is not sufficient to pick up the driver that matches best a device. In such a case, the device manager looks for a device selector to refine its choice. The device manager contacts only one driver selector. A driver selector should be registered as a service in the framework under the org.osgi.service.device.DriverSelector interface.

Device Attachment Mechanism

To clarify the interaction between a driver manager, a driver locator, drivers, and a device, consider the following mechanism for registering a newly plugged device in a LAN:

Prerequisites:

Requirements
Figure 1: Required elements.

Step 1. Device Detection. The base driver discovers the presence of the newly plugged device by using a specific device technology (USB, X10, etc.) and registers it as a Device service in the OSGi framework.

Detection
Figure 2: Detecting a device.

Step 2. Notification Phase. A service event informs the device manager that a Device service has been registered.

Notification
Figure 3: Notifying the device manager.

Step 3. Driver Location Phase. The device manager consults the driver locator about the DRIVER_IDs of drivers that match the new device. If such drivers are present, the device manager forces the device locator to download those that are not already registered in the framework. After the drivers are downloaded, the driver manager installs and starts them. Next, these bundles register Driver services in the framework.

Driver Location
Figure 4: Locating drivers.

Step 4: Driver Selection Phase. The device manager inspects the matches of all registered Driver services and records all successful ones in a list. If a driver selector presents in the service registry, the device manager passes these matches to the selector that returns the best driver according to its selection algorithm. Otherwise, the device manager chooses a driver according to the default choice mechanism.

Step 5: Attaching Phase. The device manager tells the driver to attach to the device. If the operation succeeds, a dependence between the device and the driver is settled. As a result of the attachment, the driver may return null for success or pass a string representing the ID of a more suitable driver. In the second situation, the device manager returns at Step 3 of the detection process.

After the attachment process completes, optionally the driver may register a new device-specific service. The service receives the best representation in the local network. The relation between the Device service and the attached driver is stored in a custom database, called "DEVICEM", in the DB Bundle. At future restarts, the Device Manager Bundle reads the data from the database, checks if the driver recorded for a particular Device service is present in the framework and directly attaches it. In this way, a significant part of the device attachment mechanism is skipped and system resources are saved.

Attachment
Figure 5: Attaching the appropriate driver.

The device manager of the ProSyst mBS encapsulates all the features that are discussed above: managing discovery of newly plugged devices, loading and attaching drivers to such devices.

The device manager keeps all device-driver attachments in the DEVICEM custom database of the DB Bundle. When a Device service reappears in the framework, by using the information from the database the driver manager checks whether this Device was previously attached to a driver. If there is a match, then the driver manager inspects the service registry for the corresponding Driver service and if available it directly attaches the driver to the Device. In this way, most of the steps in the device attachment mechanism are skipped.

Management of Idle Drivers

The device manager keeps the IDs of installed drivers in the DEVICEM custom database so that when the framework is restarted and in the meanwhile some of these drivers has become idle, the device manager uninstalls the idle driver. In addition, each 100 seconds the device manager checks again for idle drivers and uninstalls the matching ones.

Services

Managed Service

The Device Manager Bundle registers an org.osgi.service.cm.ManagedService service in the framework, exporting basic configuration properties related to the device manager operation. The configuration can be accessed through the OSGi Configuration Admin service (registered by the Config Bundle) under PID mbs.devicem.pid.

Pluggable Commands

The Device Manager Bundle registers a com.prosyst.util.pcommands.PluggableCommands service. This service contains a group of console commands, called dm, to use for monitoring the device attachment process. These commands are stored in the command collection of the Parser Service.

Device Manager Listener API

The ProSyst device manager is capable to notify interested bundles of events related to the device attachment mechanism, mainly to its beginning and end. Such bundles should implement the com.prosyst.mbs.services.device.DeviceManagerListener and register the implementation as a service in the framework.

Example Device and Driver

Overview

The following code examples form a device-driver chain, joined together by the device manager of the mBS.

The example device represents a simple abstraction of a "tuner" device, which has a single runtime numeric parameter - "state". In an OSGi framework, the "tuner" device is available as a Device service, which implements org.osgi.service.device.Device and has DEVICE_CATEGORY "tuner". In addition, the tuner Device service has registration properties DEVICE_SERIAL equal to "AB12" and SERVICE_PID equal to "my.device.tuner".

Example driver represents a simple driver, which can be attached to the "tuner" device. When attached, the driver simply changes the tuner's state to 5. The driver implements and registers an org.osgi.service.device.Driver service with a registration property DRIVER_ID equal to "my.driver.tuner".

When the tuner Device service appears in the OSGi framework, the device manager locates the tuner driver by its Driver service and attaches the driver to the tuner device.

Example Device

The example tuner device consists of the two parts - an interface, device.TunerDevice, and an implementation, device.impl.TunerDeviceImpl. Besides under the org.osgi.service.device.Device interface, the Device service of the tuner device is also available under device.TunerDevice.

A potential driver can get/set the state of the tuner by using the getState/setState method of the TunerDevice service interface.

package device; 
import org.osgi.service.device.Device;
public interface TunerDevice extends Device {
   
  // Sets the state of the tuner to the specified value
public void setState(int state); // Returns the current value of the state device parameter
public int getState();
}
Listing 1.1: The service interface of the example tuner device.

 

package device.impl; 
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.device.Device;
import device.TunerDevice;
public class TunerDeviceImpl implements TunerDevice, BundleActivator {
  ServiceRegistration sReg = null;
  private int state = -1;
  public TunerDeviceImpl() {
    state = 0;
  }
  // Method inherited from Device
  public void noDriverFound() {
    state = -1;
}
  // Methods inherited from BundleActivator
public void start(BundleContext bc) throws Exception { Hashtable deviceProps = new Hashtable(); deviceProps.put(org.osgi.service.device.Constants.DEVICE_CATEGORY, "tuner"); deviceProps.put(org.osgi.service.device.Constants.DEVICE_SERIAL, "AB12"); deviceProps.put(org.osgi.framework.Constants.SERVICE_PID, "my.device.tuner"); sReg = bc.registerService(new String[] {Device.class.getName(),
TunerDevice.class.getName()},
this,
deviceProps);
}
  public void stop(BundleContext bc) throws Exception {
    if (sReg != null) {
      sReg.unregister();
     }
  }
  // Methods inherited from TunerDevice
public void setState(int state) { dump("State is set to " + state); this.state = state; }
  public int getState() {
    dump("State = " + state);
    return state;
} // Prints the specified message to the system output
private void dump(String msg) { System.out.println("[TUNER DEVICE] " + msg); }
}
Listing 1.2: The implementation of the example tuner device.

Example Driver

The example driver for management of the tuner device is driver.TunerDriver, which implements a org.osgi.service.device.Driver service. In the body of the match method, it returns a match value of 1 for Device services of DEVICE_CATEGORY "tuner". For all other Device service, the example driver returns Device.MATCH_NONE.

When the device manager calls the Driver's attach method in order to attach the driver to the registered tuner Device service, the driver prints the current state of the tuner device and changes the state to 5.

package driver;       
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.device.Constants;
import org.osgi.service.device.Device;
import org.osgi.service.device.Driver;
import java.util.Hashtable;
import device.TunerDevice;
public class TunerDriver implements BundleActivator, Driver {
  static final String TUNER_DEVICE_CATEGORY = "tuner";
  static final String TUNER_DRIVER_ID = "my.driver.tuner";
  private BundleContext bc = null;
  private ServiceRegistration sReg = null;
  // Methods inherited from BundleActivator
public void start(BundleContext bc) throws Exception { this.bc = bc; Hashtable props = new Hashtable(); props.put(Constants.DRIVER_ID, TUNER_DRIVER_ID); sReg = bc.registerService(Driver.class.getName(), this, props);
}
  public void stop(BundleContext bc) throws Exception {
    if (sReg != null) {
      sReg.unregister();
    }
  }
  // Methods inherited from Driver
public int match(ServiceReference sRef) throws Exception { if (sRef != null) { String deviceCategory = (String) sRef.getProperty(Constants.DEVICE_CATEGORY); if (deviceCategory.equals(TUNER_DEVICE_CATEGORY)) { return 1; } } return Device.MATCH_NONE; }
  public String attach(ServiceReference sRef) throws Exception {
    if (sRef != null) {
      TunerDevice device = (TunerDevice) bc.getService(sRef);
      dump("Initial State = " + device.getState());
      device.setState(5);
    }
    return null;
  }
  // Prints the specified message to the system output
private void dump(String msg) { System.out.println("[MY TUNER DRIVER] " + msg);
}
}
Listing 2: The example tuner driver.

Console Commands

The Device Manager Bundle introduces a separate command group called dm. These commands can be invoked from the framework runtime console or from a Telnet client.

To enter the dm commands, type cd dm or dm/.

Command Shortcut Description
drivers dr Lists all drivers available in the framework.
devices dev Lists all devices available in the framework.
devr - Prints all registered drivers and the devices registered by them.
locators l Shows all active Device Locator services.
idledevices idev Prints all idle devices, that is, devices which do not have attached drivers.
attachlogs a Shows all device-driver attachments found in the DB Bundle's database.
attachments at Prints information about all attachments done by the device manager.
info i Shows the current values of the device manager system properties.

Tip: To get the parameters and descriptions of dm commands, type help. To view command shortcuts, use help -s. To view detailed help for a single command, for example the devices command, type devices?.

Configuration

Configuration Resources

The mbs.devicem.pid configuration, provided by the Device Manager Bundle, contains the following properties:

Configuration Property Name Type Description
devicem.attachment.timeout Attachment Timeout [ms] Integer Defines the timeout in milliseconds for performing the device attachment procedure - if a device attachment procedure is not completed after this timeout has passed, the device manager kills the engaged attachment threads and starts a new one for attaching another devices. Possible values are between 1 000 and 300 000 ms. Default is 30 000 ms.
devicem.check.dirty.drivers Check Dirty Drivers Configuration Property Boolean When true, makes the device manager check the drivers, previously installed. This is done once on every [re]start of the device manager bundle (restart of the framework). If some of these drivers becomes idle, the device manager will uninstall it. Otherwise, the idle driver will remain installed. Default is true.
devicem.check.locators.identical.drvid Check Locators Boolean

Deprecated. Use devicem.uninstall.driver_id.driver instead.

DriverLocator's method loadDriver(String id) returns an InputStream object that can be used to download the bundle containing the Driver service as specified by the driver ID argument. Once this bundle is downloaded and installed in the framework, it must register a Driver service with the DRIVER_ID property set to the value of the String argument.
When this property is true, makes the device manager check the DRIVER_ID properties. If they are not identical, the corresponding driver bundle is uninstalled. Otherwise, the device manager does not perform this check.

Default is false.

devicem.idle.timeout Idle Timeout [ms] Integer Defines the timeout in milliseconds for the attachment thread to wait for devices, candidates for attachment. If this timeout passes without a device, which needs attachment to appear, the device manager stops the attachment threads in order to free resources. Possible values are between 1 000 and 300 000 ms. Default is 10 000 ms.
devicem.idledriver.uninstall.timeout Idle Drivers Uninstall Timeout [ms] Integer

Indicates how long the device manager should wait to uninstall an idle driver bundle - as the device manager uninstalls the bundles that it has installed and are idle, sometimes removing driver bundles too soon, however, may cause unnecessary installs and delays when the same driver bundles are needed again.

Minimum is 0 ms, default is 100 000 ms.

devicem.uninstall.driver_id.driver Uninstall Wrong DRIVER_ID Drivers Boolean DriverLocator's method loadDriver(String id) returns an InputStream object that can be used to download the bundle containing the Driver service as specified by the driver ID argument. Once this bundle is downloaded and installed in the framework, it must register a Driver service with the DRIVER_ID property set to the value of the id argument of the loadDriver method.
When this property is true, it makes the device manager check the DRIVER_ID properties. If they are not identical, the corresponding driver bundle is uninstalled. Otherwise, the device manager will not perform this check. Default is false.
devicem.unlog.attachments Device Manager Unlog Attachment Property Boolean When true (the default value), defines that the attachments for a device should be deleted from the database when the corresponding device becomes idle. Otherwise, when the property is false, the attachment information is constantly preserved, which may lead to problems mainly during driver development.

The above configuration properties can be configured through the OSGi Configuration Admin service. You can conveniently do this by using the general property editor of the mConsole or by using the config group console commands.

Visual Administration

You can use the mConsole to conveniently configure the Device Manager Bundle by using a general property editor for the mbs.devicem.pid configuration dictionary (see the properties from the previous section, "Configuration Resources").

To activate the property editor:

  1. Start ProSyst mBS if it is on the same machine, or if it is residing on a distant computer, make sure it is on.
  2. Start mConsole and log in the mBS.
  3. Extends the Device Manager Bundle node within the osgi category in the bundle tree.
  4. Select the Device Manager Configuration node from the extended Device Manager Bundle parent node.


Figure 1: Configuring the Device Manager Bundle from the mConsole.

Use the Set button to apply modifications on the configuration and Defaults to load the default property values in the configuration dictionary. In case, another administrator has changed some properties in the meanwhile, use Refresh to get the changes.

System Properties

System Property Default Value Description
mbs.devicem.debug false Turns on/off generation of debug information about the runtime operation of the Device Manager Bundle.
mbs.measurements.full false Enables generation of debug measurement information about the startup time of Device Manager's functional parts.
mbs.measurements.bundles
mbs.devicem.printOnConsole false Enables the display of produced debug output into the framework's text console.

To successfully use the Device Manager Bundle's system properties, you have to specify them:

References


OSGi Bundles