<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://lorwiki.zhbert.ru/index.php?action=history&amp;feed=atom&amp;title=HAL</id>
	<title>HAL - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://lorwiki.zhbert.ru/index.php?action=history&amp;feed=atom&amp;title=HAL"/>
	<link rel="alternate" type="text/html" href="http://lorwiki.zhbert.ru/index.php?title=HAL&amp;action=history"/>
	<updated>2026-10-12T23:39:37Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>http://lorwiki.zhbert.ru/index.php?title=HAL&amp;diff=87&amp;oldid=prev</id>
		<title>Admin: 1 версия импортирована</title>
		<link rel="alternate" type="text/html" href="http://lorwiki.zhbert.ru/index.php?title=HAL&amp;diff=87&amp;oldid=prev"/>
		<updated>2023-02-27T18:39:14Z</updated>

		<summary type="html">&lt;p&gt;1 версия импортирована&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 21:39, 27 февраля 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://lorwiki.zhbert.ru/index.php?title=HAL&amp;diff=86&amp;oldid=prev</id>
		<title>lor&gt;Cetjs2: архив архивов этот hal</title>
		<link rel="alternate" type="text/html" href="http://lorwiki.zhbert.ru/index.php?title=HAL&amp;diff=86&amp;oldid=prev"/>
		<updated>2018-10-25T12:57:53Z</updated>

		<summary type="html">&lt;p&gt;архив архивов этот hal&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;В этой статье мы рассмотрим способы общения с системным демоном HAL.&lt;br /&gt;
&lt;br /&gt;
== Введение ==&lt;br /&gt;
&lt;br /&gt;
'''HAL''' (''Hardware Abstraction Layer'') — это демон, хранящий информацию о системных устройствах, их типах, возможностях и другую информацию, которую&lt;br /&gt;
он в состоянии получить через интерфейсы ядра. Демон предоставляет более высокоуровневый доступ к информации об устройствах, нежели прямое общение с sysfs и др.&lt;br /&gt;
Используя HAL API мы может просканировать список системных устройств, найти в нём дисковые накопители, Audio CD, USB флеш карты, WiFi карты, клавиатуры,&lt;br /&gt;
мыши и т. д. HAL также содержит несколько полезных сигналов, основываясь на которых мы можем отследить момент появления новых устройств в системе (например, когда был вставлен новый USB флеш накопитель, DVD диск, поднят WiFi интерфейс и т. д.). HAL предоставляет также и некоторые полезные методы, которые можно вызывать удалённо через интерфейс [[D-Bus]].&lt;br /&gt;
&lt;br /&gt;
Структура данных, в которой HAL хранит всю информацию, можно представить как ассоциативный массив. Ключом в этом массиве будет являться т. н. уникальный идентификатор устройства, или '''UDI'''. Значением этого ключа будет ещё один ассоциативный массив, в котором в свою очередь ключом будет имя свойства данного устройства, а значением — значение этого свойства для данного устройства. Имена UDI зависят от системы, не стоит полагаться на них постоянство.&lt;br /&gt;
Чтобы было понятней, представим такую упрощённую структуру для некоего устройства:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UDI1&lt;br /&gt;
    |---block.device      /dev/sda1&lt;br /&gt;
    |---block.is_volume   1&lt;br /&gt;
    |---info.capabilities volume,block&lt;br /&gt;
    |---volume.label      WORK&lt;br /&gt;
    `---volume.uuid       0717-AD77&lt;br /&gt;
UDI2&lt;br /&gt;
    …&lt;br /&gt;
UDI3&lt;br /&gt;
    …&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь у некоего устройства с UDI, равным абстрактному UDI1, имеется 5 свойств. Имя каждого свойства строго определено.&lt;br /&gt;
Значение свойства зависит от имени. Для устройства UDI1 мы может сказать следущее:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;на основании block.device — что этому устройству сопоставлен файл ''/dev/sda1'' в файловой системе /dev;&lt;br /&gt;
&amp;lt;li&amp;gt;на основании block.is_volume — что это некий раздел;&lt;br /&gt;
&amp;lt;li&amp;gt;на основании info.capabilities — что это раздел на блочном устройстве хранения данных;&lt;br /&gt;
&amp;lt;li&amp;gt;на основании volume.label — что этот раздел имеет метку ''WORK'';&lt;br /&gt;
&amp;lt;li&amp;gt;на основании volume.uuid — что этот раздел имеет UUID ''0717-AD77''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Мы можем проверить эту информацию с помощью системной утилиты ''blkid'' (запускается от пользователя ''root''):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
# blkid | grep WORK&lt;br /&gt;
/dev/sda1: LABEL=&amp;quot;WORK&amp;quot; UUID=&amp;quot;0717-AD77&amp;quot; TYPE=&amp;quot;vfat&amp;quot;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Общение с HAL демоном происходит через [[D-Bus]]. Для D-Bus имеется множество биндингов для различных языков. Это значит, что для общения с HAL у нас не должно возникнуть трудностей. В этой статье мы постараемся рассказать о нескольких способах взаимодействия с HAL.&lt;br /&gt;
&lt;br /&gt;
Также отметим, что на шине D-Bus демон предоставляет интерфейсы и методы для прямого вызова любым D-Bus клиентом. Например, с помощью &amp;lt;tt&amp;gt;qdbusviewer&amp;lt;/tt&amp;gt; или любым консольным клиентом (qdbus, dbus-send).&lt;br /&gt;
&lt;br /&gt;
Каждое устройство в иерархии может иметь дочерние устройства (например, как шина USB и подключённые к ней устройства).&lt;br /&gt;
&lt;br /&gt;
== Подготовка ==&lt;br /&gt;
&lt;br /&gt;
Во всех современных дистрибутивах демон HAL уже должен быть установлен, настроен и запущен. Для программирования нам&lt;br /&gt;
понадобятся только заголовки HAL и D-Bus. Для справки по HAL понадобится пакет &amp;lt;tt&amp;gt;hal-doc&amp;lt;/tt&amp;gt;. В Debian-подобных системах их можно установить так:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
# aptitude install libhal-dev libhal-storage-dev hal-doc&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь мы готовы для общения с HAL.&lt;br /&gt;
&lt;br /&gt;
Для просмотра всех устройств и их свойств в графическом виде можно использовать утилиту &amp;lt;tt&amp;gt;hal-device-manager&amp;lt;/tt&amp;gt;. Она присутствует в Debian Etch, но в более поздних дистрибутивах (в т.ч. и последних Ubuntu) следует использовать &amp;lt;tt&amp;gt;gnome-device-manager&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства ==&lt;br /&gt;
&lt;br /&gt;
В качестве примера рассмотрим некоторые имена свойств.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;info.capabilities — список строк, описание того, что из себя представляет это устройство. Это важное свойство для отделения устройств друг от друга по типу; &lt;br /&gt;
&amp;lt;li&amp;gt;info.parent — содержит UDI родительского элемента в иерархии HAL;&lt;br /&gt;
&amp;lt;li&amp;gt;block.device — содержит файл устройства в системной иерархии (например, /dev/sda1);&lt;br /&gt;
&amp;lt;li&amp;gt;block.is_volume — содержит значение &amp;lt;tt&amp;gt;true&amp;lt;/tt&amp;gt;, если данное устройство — раздел и может быть смонтировано;&lt;br /&gt;
&amp;lt;li&amp;gt;volume.fstype — тип файловой системы раздела (если это раздел);&lt;br /&gt;
&amp;lt;li&amp;gt;volume.label — метка тома;&lt;br /&gt;
&amp;lt;li&amp;gt;volume.fsusage — как используется файловая система (обычная файловая система, RAID, неформатированная область и т.д.);&lt;br /&gt;
&amp;lt;li&amp;gt;linux.sysfs_path — путь к файлу устройства в иерархии sysfs.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
За полным списком возможных имён свойств обратитесь к документации HAL.&lt;br /&gt;
&lt;br /&gt;
== Консоль ==&lt;br /&gt;
&lt;br /&gt;
Мы можем общаться с HAL с помощью любого клиента D-Bus. Например, с помощью консольного &amp;lt;tt&amp;gt;dbus-send&amp;lt;/tt&amp;gt;. Для каждого устройства на шине D-Bus предусмотрен&lt;br /&gt;
интерфейс &amp;lt;tt&amp;gt;org.freedesktop.Hal.Device&amp;lt;/tt&amp;gt;, который предоставляет методы для получения и установки свойств данного конкретного устройства.&lt;br /&gt;
&lt;br /&gt;
Например, получим список облуживаемых устройств (похожий результат даст команда &amp;lt;tt&amp;gt;lshal&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ dbus-send --system --print-reply --dest=org.freedesktop.Hal \&lt;br /&gt;
            /org/freedesktop/Hal/Manager                      \&lt;br /&gt;
            org.freedesktop.Hal.Manager.GetAllDevices&lt;br /&gt;
method return sender=:1.1 -&amp;gt; dest=:1.28 reply_serial=2&lt;br /&gt;
   array [&lt;br /&gt;
      string &amp;quot;/org/freedesktop/Hal/devices/acpi_P001&amp;quot;&lt;br /&gt;
      string &amp;quot;/org/freedesktop/Hal/devices/acpi_P002&amp;quot;&lt;br /&gt;
      ...&lt;br /&gt;
      string &amp;quot;/org/freedesktop/Hal/devices/pci_10de_368&amp;quot;&lt;br /&gt;
      string &amp;quot;/org/freedesktop/Hal/devices/pci_10de_362&amp;quot;&lt;br /&gt;
      string &amp;quot;/org/freedesktop/Hal/devices/pci_10de_369&amp;quot;&lt;br /&gt;
   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждая строка в ответе — это UDI обслуживаемого устройства.&lt;br /&gt;
&lt;br /&gt;
Теперь получим свойство &amp;lt;tt&amp;gt;info.capabilities&amp;lt;/tt&amp;gt; для одного из дисковых разделов, основываясь на его UDI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ dbus-send --system --print-reply --dest=org.freedesktop.Hal  \&lt;br /&gt;
            /org/freedesktop/Hal/devices/volume_uuid_0717_AD77 \&lt;br /&gt;
            org.freedesktop.Hal.Device.GetProperty             \&lt;br /&gt;
            string:info.capabilities&lt;br /&gt;
method return sender=:1.1 -&amp;gt; dest=:1.31 reply_serial=2&lt;br /&gt;
   array [&lt;br /&gt;
      string &amp;quot;volume&amp;quot;&lt;br /&gt;
      string &amp;quot;block&amp;quot;&lt;br /&gt;
   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь получим свойство &amp;lt;tt&amp;gt;volume.label&amp;lt;/tt&amp;gt; (метка DOS) для этого же раздела:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ dbus-send --system --print-reply --dest=org.freedesktop.Hal  \&lt;br /&gt;
            /org/freedesktop/Hal/devices/volume_uuid_0717_AD77 \&lt;br /&gt;
            org.freedesktop.Hal.Device.GetProperty             \&lt;br /&gt;
            string:volume.label&lt;br /&gt;
method return sender=:1.1 -&amp;gt; dest=:1.33 reply_serial=2&lt;br /&gt;
   string &amp;quot;WORK&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Получим свойство &amp;lt;tt&amp;gt;volume.size&amp;lt;/tt&amp;gt; (размер раздела в байтах) для этого же раздела:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ dbus-send --system --print-reply --dest=org.freedesktop.Hal  \&lt;br /&gt;
            /org/freedesktop/Hal/devices/volume_uuid_0717_AD77 \&lt;br /&gt;
            org.freedesktop.Hal.Device.GetProperty             \&lt;br /&gt;
            string:volume.size&lt;br /&gt;
method return sender=:1.1 -&amp;gt; dest=:1.36 reply_serial=2&lt;br /&gt;
   uint64 15002878464&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== C/C++ ==&lt;br /&gt;
&lt;br /&gt;
В этом разделе мы напишем HAL клиента на оригинальной библиотеке libhal (на языке C, стандарта C99). Это необходимо прежде всего для&lt;br /&gt;
тулкитов, где нет высокоуровнего D-Bus клиента, либо для чисто консольной программы, которая не использует тулкиты вообще.&lt;br /&gt;
&lt;br /&gt;
Итак, всё что нам понадобится — это один исходный файл и элементарный скрипт компиляции. Makefile можете написать по своему усмотрению.&lt;br /&gt;
&lt;br /&gt;
Скрипт компиляции (назовём его &amp;lt;tt&amp;gt;mk&amp;lt;/tt&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sh&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
# компилируем исходник main.c. Не забываем о флагах и библиотеках HAL и D-Bus&lt;br /&gt;
gcc -o hal -O2 -std=c99                                        \&lt;br /&gt;
        `pkg-config --cflags hal` `pkg-config --cflags dbus-1` \&lt;br /&gt;
        main.c                                                 \&lt;br /&gt;
        `pkg-config --libs hal` `pkg-config --libs dbus-1`&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Стратегия написания простейшего клиента HAL сводится к следующему:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;создать новый HAL контекст, используемый в HAL API;&lt;br /&gt;
&amp;lt;li&amp;gt;создать соединение с D-Bus сессией;&lt;br /&gt;
&amp;lt;li&amp;gt;ассоциировать HAL контекст с D-Bus соединением;&lt;br /&gt;
&amp;lt;li&amp;gt;инициализировать HAL;&lt;br /&gt;
&amp;lt;li&amp;gt;использовать функции из HAL API для общения с демоном (например, получим список всех устройств);&lt;br /&gt;
&amp;lt;li&amp;gt;деинициализировать клиента HAL.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;libhal.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;dbus/dbus.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// функция обработки UDI&lt;br /&gt;
static void handleDevice(LibHalContext *ctx, const char *udi, DBusError *error)&lt;br /&gt;
{&lt;br /&gt;
    if(!udi)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;%s\n&amp;quot;, udi);&lt;br /&gt;
&lt;br /&gt;
    // нас интересуют только устройства, имеющие свойство info.capabilities&lt;br /&gt;
    if(!libhal_device_property_exists(ctx, udi, &amp;quot;info.capabilities&amp;quot;, NULL))&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // получим значение свойства (массив строк)&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    char **capabilities = libhal_device_get_property_strlist(ctx, udi, &amp;quot;info.capabilities&amp;quot;, NULL);&lt;br /&gt;
&lt;br /&gt;
    if(!capabilities)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // сейчас 'capabilities' представляет собой массив строк&lt;br /&gt;
&lt;br /&gt;
    // пройдёмся по всем строкам, выведем на экран значения&lt;br /&gt;
    while(*(capabilities+i))&lt;br /&gt;
    {&lt;br /&gt;
        printf(&amp;quot;\t%s\n&amp;quot;, *(capabilities+i));&lt;br /&gt;
        ++i;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // освободим память!&lt;br /&gt;
    libhal_free_string_array(capabilities);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static void die(const char *s)&lt;br /&gt;
{&lt;br /&gt;
    if(s)&lt;br /&gt;
        fprintf(stderr, &amp;quot;%s\n&amp;quot;, s);&lt;br /&gt;
&lt;br /&gt;
    exit(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    DBusConnection *dbus;&lt;br /&gt;
    LibHalContext *ctx;&lt;br /&gt;
    DBusError error;&lt;br /&gt;
&lt;br /&gt;
    // создаём новый контекст&lt;br /&gt;
    ctx = libhal_ctx_new();&lt;br /&gt;
&lt;br /&gt;
    if(!ctx)&lt;br /&gt;
        die(&amp;quot;Cannot initialize HAL context&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // инициализируем объект error, он нам понадобится в функциях HAL API&lt;br /&gt;
    dbus_error_init(&amp;amp;error);&lt;br /&gt;
&lt;br /&gt;
    // создаём соединение с D-Bus&lt;br /&gt;
    dbus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &amp;amp;error);&lt;br /&gt;
&lt;br /&gt;
    // ассоциируем D-Bus соединение с HAL контекстом&lt;br /&gt;
    libhal_ctx_set_dbus_connection(ctx, dbus);&lt;br /&gt;
&lt;br /&gt;
    // инициализируем HAL клиента с нашей стороны&lt;br /&gt;
    if(!libhal_ctx_init(ctx, &amp;amp;error))&lt;br /&gt;
        die(&amp;quot;Cannot initialize HAL&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // с помошью HAL API получаем список устройств, обслуживаемых демоном,&lt;br /&gt;
    // каждое устройство представляет собой строку с UDI&lt;br /&gt;
    int numDevices;&lt;br /&gt;
    char **halDevices = libhal_get_all_devices(ctx, &amp;amp;numDevices, NULL);&lt;br /&gt;
&lt;br /&gt;
    // нет устройств??&lt;br /&gt;
    if(!halDevices)&lt;br /&gt;
        die(&amp;quot;Cannot get device list&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Number of devices: %d\n&amp;quot;, numDevices);&lt;br /&gt;
&lt;br /&gt;
    // для каждого UDI вызываем функцию обработки&lt;br /&gt;
    for(int i = 0;i &amp;lt; numDevices;i++)&lt;br /&gt;
        handleDevice(ctx, halDevices[i], &amp;amp;error);&lt;br /&gt;
&lt;br /&gt;
    // освобождаем память!&lt;br /&gt;
    libhal_free_string_array(halDevices);&lt;br /&gt;
&lt;br /&gt;
    if(dbus_error_is_set(&amp;amp;error))&lt;br /&gt;
        dbus_error_free(&amp;amp;error);&lt;br /&gt;
&lt;br /&gt;
    // завершаем D-Bus соединение&lt;br /&gt;
    dbus_connection_close(dbus);&lt;br /&gt;
    dbus_connection_unref(dbus);&lt;br /&gt;
&lt;br /&gt;
    // завершаем клиента&lt;br /&gt;
    libhal_ctx_free(ctx);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта программа выдаст на консоль список всех обслуживаемых устройств, и свойство &amp;lt;tt&amp;gt;info.capabilities&amp;lt;/tt&amp;gt; каждого устройства.&lt;br /&gt;
&lt;br /&gt;
== Qt ==&lt;br /&gt;
&lt;br /&gt;
С помощью Qt общаться с HAL можно без особых трудностей, т.к. в 4-ю версию этого тулкита уже встроен D-Bus клиент (необходимы установленные пакеты &amp;lt;tt&amp;gt;libqt4-dbus&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;libqt4-dev&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Стратегия написания простейшего клиента HAL на Qt очень проста: с помощью D-Bus-клиента Qt подключиться к системной шине (именно там запущен демон HAL), и вызывать необходимые методы D-Bus. В примере с Qt используются два полезных сигнала, предоставляемых HAL —&lt;br /&gt;
&amp;lt;tt&amp;gt;DeviceAdded&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;DeviceRemoved&amp;lt;/tt&amp;gt;. Первый срабатывает когда добавляется какое-либо устройство, второй — когда удаляется. Наглядными примерами могут послужить USB-флешки или DVD-диски. Когда такой сигнал возникает, вызываются все подписанные на него удалённые методы. Подписаться на эти сигналы можно средствами того же Qt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;QDBusConnection&amp;gt;&lt;br /&gt;
#include &amp;lt;QDBusInterface&amp;gt;&lt;br /&gt;
#include &amp;lt;QDBusReply&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;QStringList&amp;gt;&lt;br /&gt;
#include &amp;lt;QDebug&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;hal.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
namespace&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
// функция вызова D-Bus методов, которые принимают один параметр и возвращают значение&lt;br /&gt;
template&amp;lt;typename T&amp;gt;&lt;br /&gt;
T dbusRequest(QDBusInterface &amp;amp;i, const QString &amp;amp;method, const QString &amp;amp;param)&lt;br /&gt;
{&lt;br /&gt;
    QDBusReply&amp;lt;T&amp;gt; reply = i.call(method, param);&lt;br /&gt;
    &lt;br /&gt;
    return reply.value();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
HAL::HAL() : QTextEdit()&lt;br /&gt;
{&lt;br /&gt;
    resize(640, 480);&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
     *  Используем сигналы DeviceAdded и DeviceRemoved за слежением&lt;br /&gt;
     *  за добавлением/удалением устройств. Следует помнить, что при добавлении,&lt;br /&gt;
     *  скажем, USB флешки, в системе возникает несколько устройств.&lt;br /&gt;
     *  Отделить нужные устройства от вспомогательных можно с помощью анализа&lt;br /&gt;
     *  их свойств.&lt;br /&gt;
     */&lt;br /&gt;
    QDBusConnection sys = QDBusConnection::systemBus();&lt;br /&gt;
&lt;br /&gt;
    sys.connect(&amp;quot;org.freedesktop.Hal&amp;quot;,&lt;br /&gt;
                &amp;quot;/org/freedesktop/Hal/Manager&amp;quot;,&lt;br /&gt;
                &amp;quot;org.freedesktop.Hal.Manager&amp;quot;,&lt;br /&gt;
                &amp;quot;DeviceAdded&amp;quot;,&lt;br /&gt;
                this,&lt;br /&gt;
                SLOT(slotAdded(const QString &amp;amp;)));&lt;br /&gt;
&lt;br /&gt;
    sys.connect(&amp;quot;org.freedesktop.Hal&amp;quot;,&lt;br /&gt;
                &amp;quot;/org/freedesktop/Hal/Manager&amp;quot;,&lt;br /&gt;
                &amp;quot;org.freedesktop.Hal.Manager&amp;quot;,&lt;br /&gt;
                &amp;quot;DeviceRemoved&amp;quot;,&lt;br /&gt;
                this,&lt;br /&gt;
                SLOT(slotRemoved(const QString &amp;amp;)));&lt;br /&gt;
&lt;br /&gt;
    // прочитаем список всех UDI устройств, и занесём этот список&lt;br /&gt;
    // в текстовое поле&lt;br /&gt;
    readDevices();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HAL::readDevices()&lt;br /&gt;
{&lt;br /&gt;
    // с помощью QDBusInterface устанавливаем соединение с D-Bus шиной&lt;br /&gt;
    QDBusInterface i(&amp;quot;org.freedesktop.Hal&amp;quot;,&lt;br /&gt;
                     &amp;quot;/org/freedesktop/Hal/Manager&amp;quot;,&lt;br /&gt;
                     &amp;quot;org.freedesktop.Hal.Manager&amp;quot;,&lt;br /&gt;
                     QDBusConnection::systemBus());&lt;br /&gt;
&lt;br /&gt;
    // вызываем стандартный HAL метод - GetAllDevices. Этот&lt;br /&gt;
    // метод возвращает список всех обслуживаемых UDI в виде массива строк&lt;br /&gt;
    QDBusReply&amp;lt;QStringList&amp;gt; reply = i.call(&amp;quot;GetAllDevices&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // ответ битый?&lt;br /&gt;
    if(reply.isValid())&lt;br /&gt;
    {&lt;br /&gt;
        // получаем список строк из ответа&lt;br /&gt;
        QStringList l = reply.value();&lt;br /&gt;
        QStringList::iterator itEnd = l.end();&lt;br /&gt;
&lt;br /&gt;
        // проходим по списку строк (UDI) и заносим каждую строку&lt;br /&gt;
        // в текстовое поле&lt;br /&gt;
        for(QStringList::iterator it = l.begin();it != itEnd;++it)&lt;br /&gt;
            append(*it);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
        append(&amp;quot;Failed to get device list&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HAL::slotAdded(const QString &amp;amp;udi)&lt;br /&gt;
{&lt;br /&gt;
    /* &lt;br /&gt;
     *  при добавлении устройства попробуем определить, что оно из себя&lt;br /&gt;
     *  представляет (попробуем определить устройства с разделами, например USB&lt;br /&gt;
     *  флеш накопители или DVD диски)&lt;br /&gt;
     */&lt;br /&gt;
    QDBusInterface i(&amp;quot;org.freedesktop.Hal&amp;quot;,&lt;br /&gt;
                     udi,&lt;br /&gt;
                     &amp;quot;org.freedesktop.Hal.Device&amp;quot;,&lt;br /&gt;
                     QDBusConnection::systemBus());&lt;br /&gt;
&lt;br /&gt;
    QStringList caps = dbusRequest&amp;lt;QStringList&amp;gt;(i, &amp;quot;GetProperty&amp;quot;, &amp;quot;info.capabilities&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; &amp;quot;Added device with UDI&amp;quot; &amp;lt;&amp;lt; udi &amp;lt;&amp;lt; caps;&lt;br /&gt;
&lt;br /&gt;
    // устройство не имеет файловой системы, оно нас не интересует&lt;br /&gt;
    if(dbusRequest&amp;lt;QString&amp;gt;(i, &amp;quot;GetProperty&amp;quot;, &amp;quot;volume.fsusage&amp;quot;) != &amp;quot;filesystem&amp;quot; &amp;amp;&amp;amp;&lt;br /&gt;
            !dbusRequest&amp;lt;bool&amp;gt;(i, &amp;quot;GetProperty&amp;quot;, &amp;quot;volume.disc.has_audio&amp;quot;))&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    QDBusMessage reply = i.call(&amp;quot;GetProperty&amp;quot;, &amp;quot;volume.size&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // получаем другие данные по устройству&lt;br /&gt;
    QString product = dbusRequest&amp;lt;QString&amp;gt;(i, &amp;quot;GetProperty&amp;quot;, &amp;quot;info.product&amp;quot;);&lt;br /&gt;
    QString size = reply.arguments().first().toString();&lt;br /&gt;
    QString parent = dbusRequest&amp;lt;QString&amp;gt;(i, &amp;quot;GetProperty&amp;quot;, &amp;quot;block.storage_device&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // родитель содержит параметры устройства, как модель и шину,&lt;br /&gt;
    // к которой оно подключено&lt;br /&gt;
    QDBusInterface iParent(&amp;quot;org.freedesktop.Hal&amp;quot;,&lt;br /&gt;
                parent,&lt;br /&gt;
                &amp;quot;org.freedesktop.Hal.Device&amp;quot;,&lt;br /&gt;
                QDBusConnection::systemBus());&lt;br /&gt;
&lt;br /&gt;
    QString model = dbusRequest&amp;lt;QString&amp;gt;(iParent, &amp;quot;GetProperty&amp;quot;, &amp;quot;storage.model&amp;quot;);&lt;br /&gt;
    QString vendor = dbusRequest&amp;lt;QString&amp;gt;(iParent, &amp;quot;GetProperty&amp;quot;, &amp;quot;storage.vendor&amp;quot;);&lt;br /&gt;
    QString bus = dbusRequest&amp;lt;QString&amp;gt;(iParent, &amp;quot;GetProperty&amp;quot;, &amp;quot;storage.bus&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    append(QString(&amp;quot;Added device, model (%1), vendor (%2), bus (%3), product (%4), size (%5)&amp;quot;)&lt;br /&gt;
            .arg(model).arg(vendor).arg(bus).arg(product).arg(size));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HAL::slotRemoved(const QString &amp;amp;udi)&lt;br /&gt;
{&lt;br /&gt;
    append(QString(&amp;quot;Removed device with UDI %1&amp;quot;).arg(udi));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При вставке DVD-диска в текстовом поле должно появится сообщение типа:&lt;br /&gt;
&amp;lt;pre&amp;gt;Added device, model (_NEC DVD_RW ND-3540A), vendor (), bus (ide), product (Мой диск), size (4644896768)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tcl ==&lt;br /&gt;
&lt;br /&gt;
Не менее просто чем из Qt, с HAL можно работать и из Tcl. Пример можно посмотреть в разделе [[D-Bus]].&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://people.freedesktop.org/~david/hal-spec/hal-spec.html Документация HAL].&lt;br /&gt;
* [http://rusfolder.com/34174696 Примеры Qt, C, Python].&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/HAL_(freedesktop.org) Статья на Wikipedia].&lt;br /&gt;
&lt;br /&gt;
[[Category:Системное ПО]]&lt;br /&gt;
[[Category:Программирование]]&lt;br /&gt;
[[Category:Архив]]&lt;/div&gt;</summary>
		<author><name>lor&gt;Cetjs2</name></author>
	</entry>
</feed>