The OSGi Device Manager Bundle implements the device manager functionality defined by the OSGi Device Access Specification.
Overview
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.
Registering Bundle
The services are registered by OSGi Device Manager Bundle and for more details refer to the system and configuration properties of the bundle.
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
All steps required for the registration of a new device into the local network are illustrated in the Device Attachment Mechanism document.
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.
Device Attachment Mechanism
To clarify the interaction between a driver manager, a driver locator, drivers, and a device, consider the mechanism for registering a newly plugged device in a LAN.
Prerequisites:



.
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.

The device manager of the OSGi Runtime 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.
Example Device and Driver
The following code examples form a device-driver chain, joined together by the device manager.
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.
Listing 1. The service interface of the example tuner device.
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 2. The implementation of the example tuner device.
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);
}
}
Example Driver
The example driver for management of the tuner device is driver.TunerDriver, which implements an 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.
Listing 3. The example tuner driver.
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);
}
}