# Introduction

## About

This document concerns the specification of HAL which is a piece of software that provides a view of the various hardware attached to a system. In addition to this, HAL keeps detailed metadata for each piece of hardware and provide hooks such that system- and desktop-level software can react to changes in the hardware configuration in order to maintain system policy.

HAL represents a piece of hardware as a device object. A device object is identified by a unique identifer and carries a set of key/value paris referred to as device properties. Some properties are derived from the actual hardware, some are merged from device information files and some are related to the actual device configuration. This document specifies the set of device properties and gives them well-defined meaning. This enable system and desktop level components to distinguish between the different device objects and discover and configure devices based on these properties.

HAL provides an easy-to-use API through D-Bus which is an IPC framework that, among other things, provides a system-wide message-bus that allows applications to talk to one another. Specifically, D-Bus provides asynchronous notification such that HAL can notify other peers on the message-bus when devices are added and removed as well as when properties on a device are changing.

The most important goal of HAL is to provide plug-and-play facilities for UNIX-like desktops with focus on providing a rich and extensible description of device characteristics and features. HAL has no other major dependencies apart from D-Bus which, given sufficient infrastructure, allows it to be implemented on many UNIX-like systems. The major focus, initially, is systems running the Linux 2.6 series kernels.

## Acknowledgements

Havoc Pennington's article ''Making Hardware Just Work'' motivated this work. The specification and software would not exist without all the useful ideas, suggestions, comments and patches from the Free Desktop and HAL mailing lists.

All trademarks mentioned belong to their respective owners.

## Architecture of HAL

The HAL consists of a number of components as outlined in the diagram below. Note that this diagram is high-level and doesn't capture all implementation details.

Details on each component

- HAL daemon

  A system-wide service that maintains a database of device objects. The daemon is responsible for merging information from device information files and managing the life cycle of device objects. The service is implemented as a daemon and uses helpers to query devices for specific information.

- Applications

  These are applications consuming services from HAL; this includes desktop-wide session daemons for maintaining policy such as power and disk/volume management.

- Callouts

  Callouts are programs that run when device objects are added and removed in the HAL daemon. This is useful for 3rd party software to merge additional information onto the device object before it is announced on D-Bus. Callouts are specified on a per-device basis with the `info.callouts.add` and `info.callouts.remove`. See device-properties-info for details.

- Methods

  It is possible to specify that a given HAL device object implements a specific D-Bus interface, e.g. `org.freedesktop.Hal.Device.Frob` with a set of methods `Foo`, `Bar` and `Baz` and have programs run when applications call into this interface. This is defined in the `info.interfaces` property, consult device-properties-info for details.

- Addons

  An addon can be characterized as a daemon whose life cycle is tied to a device object in HAL. And addon can also claim a specific interface on the device object to provide services to applications for configuring / using the device without having to spawn a new program for every method call. HAL provides a facility to launch/destroy one or more addons per device object using the `info.addons` property. See device-properties-info for details.

- Device Information Files

  A set of files that matches properties on device objects and merges additional information. These files are used, for among other things, to specify what callouts, methods and addons to associate with a device object. For example, for drives using removable media, HAL includes an add-on daemon which sole purpose is to continously poll the drive to detect media change.

The D-Bus system message bus is used to provide a ''network API'' to applications. As D-Bus is designed to be language independent, potentially many languages / runtime systems will be able to easily access the services offered by HAL.

## Device Objects

It is important to precisely define the term HAL device object. It's actually a bit blurry to define in general, it includes what most UNIX-like systems consider first class objects when it comes to hardware. In particular, a device object should represent the smallest unit of addressable hardware. This means there can be a one-to-many relationship between a physical device and the device objects exported by HAL. Specifically, a multi-function printer, which appear to users as a single device may show up as several device objects; e.g. one HAL device object for each of the printing, scanning, fax and storage interfaces. Conversely, some devices may be implemented such that the HAL device object represent several functional interfaces. HAL is not concerned with this duality of either one-to-many or many-to-one relationships between device objects and the actual iron constituting what users normally understand as a single piece of hardware; a device object represents the smallest addressable unit.

Device objects in HAL are organised on a by-connection basis, e.g. for a given device object X it is possible to find the device object Y where X is attached to Y. This gives structure to the device database of HAL; it is possible to map the devices out in a tree. Further, software emulation devices exported by the operating system kernel, such as SCSI emulation for USB Storage Devices, are also considered device objects in HAL. This implies that operating system kernel specific bits leak into the device object database. However applications using HAL will not notice this, such device objects are not referenced anywhere in the device objects that users are interested in; they are merely used as glue to build the device tree.

In addition to provide information about what kind of hardware a device object represents (such as a PCI or USB device) and how to address it, HAL merges information about the functional interfaces the operating system kernel provides in order to use the device; in most cases this is represented on the device object as a string property with the name of the special device file in `/dev`. In addition to the special device file, a number of other useful properties are merged. This means that both hardware and functional properties are on the same device object, which may prove to be useful for an application programmer. For example, an application might query HAL for the device object that exports the special device file `/dev/input/mouse2` and learn that this is provide by an USB mouse from a certain manufacturer by checking the properties that export the USB vendor and product identifiers. See device-capabilities and device-properties for details.

Finally, HAL provides one or more D-Bus interfaces for applications to configure and/or use the device. These interfaces are discussed in interfaces.

Summarizing, a device object is comprised by

- UDI

  This is the the Unique Device Identifer, that is unique for a device object - that is, no other device object can have the same UDI at the same time. The UDI is computed using bus-specific information and is meant to be unique across device insertions and independent of the physical port or slot the device may be plugged into.

- Properties

  Each device object got a set of properties which are key/value pairs. The key is an ASCII string while the value can be one of several types, see below. Properties are arranged into name spaces using ''.'' as a separator.

  - `string` - UTF8 string

  - `strlist` - ordered list with UTF8 strings

  - `int` - 32-bit signed integer

  - `uint64` - 64-bit unsigned integer

  - `bool` - truth value

  - `double` - IEEE754 double precision floating point number

- Interfaces

  Applications can configure and/or use a device using D-Bus interfaces. Typically, there's a one-to-one relationship between capabilities/namespaces and interfaces.

Properties of a device object carry all the important information about a device object. For organisational reasons properties are also namespaced using ''.'' as a separator.

It can be useful to classify properties into four groups

- Metadata - Information about how the devices are connected with respect to each other (parent/child relationships), what kind of device it is, what functionality it provides etc.

- Facts - vendor ID, product ID, disk serial numbers, number of buttons on a mouse, formats accepted by a mp3 player and so on.

- Usage specific information - Network link status, special device file name, filesystem mount location etc.

- Policy - How the device is to be used be users; usually defined by the system administrator.

The first category is determined by HAL, the second category includes information merged from either querying the hardware itself or from device information files. The third category is intercepted by monitoring the hardware and finally the last is merged from files under control of the system administrator. This document is concerned with precisely defining several properties; see device-properties and onwards for more information. As a complement to device properties, HAL also provides conditions on HAL device objects. Conditions are used to relay events that are happening on devices which are not easily expressed in properties. This includes events such as ''processor is overheating'' or ''block device unmounted''.

There is a special hal device object referred to as the ''root computer device object''. This device object represent the entire system as a whole and all other devices are either directly or indirectly childs of this device object. It has the UDI `/org/freedesktop/Hal/devices/computer`.

The fundamental idea about HAL is that all ''interesting'' information about hardware that a desktop application needs, can be obtained by querying HAL.

## Device Capabilities

Mainstream hardware isn't very good at reporting what it really is, it only reports, at best, how to interact with it. This is a problem; many devices, such as MP3 players or digital still cameras, appear to the operating system as plain USB Mass Storage devices when the device in fact is a lot more than just that. The core of the problem is that without external metadata, the operating system and desktop environment will present it to the user as just e.g. a mass storage device.

As HAL is concerned with merging of external metadata, through e.g. device information files, there needs to be some scheme on how to record what the device actually is. This is achieved by two textual properties, `info.category` and `info.capabilities`. The former describes what the device is (as a single alphanumeric keyword) and the latter describes what the device does (as a number of alphanumeric keywords separated by whitespace). The keywords available for use is defined in this document; we'll refer to them in following simply as capabilities.

HAL itself, assigns capabilities on device detection time by inspecting the device class (if available, it depends on the bus type) and looking at information from the operating system and the hardware itself.

User mode drivers such as `libgphoto2` and `sane` provides device information to merge information about devices they can drive. As such, device objects represent an USB interface gain additional properties such as ''scanner'' or ''camera''.

Having a capability also means that part of the property namespace, prefixed with the capability name, will be populated with more specific information about the capability. Indeed, some properties may even be required such that applications and device libraries have something to expect. For instance, the capability for being a MP3 player may require properties defining what audio formats the device support (e.g. Ogg and MP3), whether it support recording of audio, and how to interact with the device. For example, the latter may specify ''USB Storage Device'' or ''proprietary protocol, use libfooplayer''.

Finally, capabilities have an inheritance scheme, e.g. if a device has a capability `foo.bar`, it must also have the capability `foo`.