[Nut-upsdev] Serial Ports (Was Re: Common Power Management : NUT
and HAL (stage 1))
David Zeuthen
david at fubar.dk
Mon Aug 7 17:27:04 UTC 2006
On Thu, 2006-08-03 at 21:28 +0200, Arnaud Quette wrote:
> > > > * serial and snmp drivers are not yet managed,
>
> you once proposed me to sketch that one Dave ;-)
Indeed I did! So here goes:
So my proposal isn't really confined to serial ports but any port where
we cannot automatically detect a device. Here's a few statements
a) we need user input on configuring the port - this means the user
needs to choose what device sits on the port, be it a UPS, a
GPS receiver, modem, smart card reader, input device and so on.
After the user chooses the device type, we should check that the
device he chose is actually on the port before it is configured.
b) the stock install of HAL should leave the ports unconfigured
c) it needs to be easy for a program to configure the port - OS
installers and desktop programs come to mind.
d) once configured we should remember the configuration on hal restarts
e) the configuration is bound to the system scope, e.g. it doesn't
change when the user changes
f) the configuration is bound to the physical machine, e.g. if you
move the system disk to another system the port should be
unconfigured when you boot into the new system
(use-case: boot from USB)
g) it must be easy for external packages (like nut, gpsd etc.) to tell
HAL that it wants to participate in configuring a port.
h) we should provide a textual hal utility for configuring a port
So the serial port on my desktop system looks like this
udi = '/org/freedesktop/Hal/devices/pnp_PNP0501_serial_platform_0'
info.udi = '/org/freedesktop/Hal/devices/pnp_PNP0501_serial_platform_0' (string)
linux.device_file = '/dev/ttyS0' (string)
linux.subsystem = 'tty' (string)
linux.hotplug_type = 2 (0x2) (int)
info.product = '16550A-compatible COM port' (string)
serial.type = 'platform' (string)
serial.port = 0 (0x0) (int)
serial.device = '/dev/ttyS0' (string)
serial.physical_device = '/org/freedesktop/Hal/devices/pnp_PNP0501' (string)
info.capabilities = {'serial'} (string list)
info.category = 'serial' (string)
info.parent = '/org/freedesktop/Hal/devices/pnp_PNP0501' (string)
linux.sysfs_path = '/sys/class/tty/ttyS0' (string)
The proposal involves
1. all device objects representing legacy ports are tagged with the
capability "legacy_port". This is easy to do.
2. we introduce new properties
legacy_port.type (string)
that indicates the type of the port, e.g. "serial". Later on we can
add e.g. "parallel" or other types.
legacy_port.is_configured (bool)
this property is TRUE if, and only if, the port is configured.
legacy_port.configured_type (string)
if is_configured==TRUE, this is the ''type'' of device the device
is configured as. The ''type'' is defined below.
legacy_port.probers.type (strlist)
legacy_port.probers.capabilities (strlist)
legacy_port.probers.programs (strlist)
These three properties are filled by either in-tree HAL programs or
external packages like e.g. NUT that wants to participate in
configuring legacy ports. It may look like this
legacy_port.probers.type = {"nut-serial-ups", "gpsd-serial-gps", "hal-serial-modem", ...}
legacy_port.probers.capabilities = {"battery.ups", "gps", "modem", ...}
legacy_port.probers.programs = {"nut-hal-serial-prober", "gpsd-serial-probe", "hal-serial-modem-probe", ...}
where .type contains a opaque type specific to the provider,
.capabilities contains HAL capabilities that will be provided if
bound, and .programs is a program to actually test to see if there
is a device.
This is easy to provide for e.g. NUT, it simply includes a HAL FDI
file that looks somewhat like this
<deviceinfo version="0.2">
<device>
<match key="legacy_port.type" string="serial">
<append key="legacy_port.probers.type" type="strlist">nut-serial-ups</append>
<append key="legacy_port.probers.capabilities" type="strlist">battery.ups</append>
<append key="legacy_port.probers.programs" type="strlist">nut-hal-serial-prober</append>
</match>
</device>
</deviceinfo>
3. With the legacy_port.* properties we can now provide a sane UI
(both API and UI-wise) to provide probing for serial devices. Said
configuration programs would look at legacy_port.probers.
capabilities which contains well-defined HAL capabilities that can
be translated into the users language. So in addition to the
legacy_port capability we'd export an interface with methods called
org.freedesktop.Hal.Device.LegacyPort
with methods
UnconfigurePort()
to simply unconfigure a port and,
ConfigurePort (IN int proberNumber)
throws AlreadConfiguredException,
NoSuchProberException,
ProberDidNotFindDeviceException
where the latter method, ConfigurePort, will try to run the
requested prober. If that fails (e.g. return code is != 0) then
this exception is thrown. If it succeeds, then the properties
legacy_port.is_configured and legacy_port.configured_type
is set accordingly.
It should be trivial to write a textual based program that does
exactly this and we will do this and include it in tools/ along
with other smallish tools such as lshal. Similary, programs
such as gnome-volume-manager (which really should be gnome-hardware-
manager) would be able to provide the UI for this etc. etc.
4. To preserve the value of the properties
legacy_port.is_configured,
legacy_port.configured_type
across HAL restarts, the ConfigurePort() method simply saves
the values somewhere in /var/run/hald/blah and we have a callout
on the device object pick them up. The file name chosen to save
it under will include system.product and system.product from the
/o/fd/Hal/d/computer object to satisfy requirement f) above.
So now we have provided infrastructure for the user to configure the
legacy port. To actually do something with this, software such as NUT
simply includes an FDI file like this
<deviceinfo version="0.2">
<device>
<match key="legacy_port.configured_type" contains="nut-serial-ups">
<append key="info.addons" type="strlist">nut-addon-for-serial-ups</append>
</match>
</device>
</deviceinfo>
and since this is on the device object for the UDI
/org/freedesktop/Hal/devices/pnp_PNP0501_serial_platform_0
that I listed above you are guaranteed to have the device file in the
property serial.device and you can go from there.
There's a few gotchas in the implementation, but this is pretty much how
I envision we should do this. I'm pretty sure this would work and if
there is consensus I'm happy to do the work for this infrastructure as
well for the serial modem stuff (I don't have a serial UPS).
Of course, if someone wants to hack on this, I'm happy to review patches
also :-)
Thoughts?
David
More information about the Nut-upsdev
mailing list