mbox series

[libgpiod,RFC/RFT,00/18] dbus: add GLib-based DBus daemon and command-line client

Message ID 20240412122804.109323-1-brgl@bgdev.pl
Headers show
Series dbus: add GLib-based DBus daemon and command-line client | expand

Message

Bartosz Golaszewski April 12, 2024, 12:27 p.m. UTC
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

This has been in the works for a long time but I'm finally ready to share it
with the world. This introduces the DBus API definition and its implementation
in the form of a GPIO manager daemon and a companion command-line client as
well as GLib bindings to libgpiod which form the base on which the former are
built.

Please note that while the functionality is complete, the dbus part still
requires some work (bug fixing, corner-cases, general ironing out of all the
wrinkles, a lot of code could be refactored too). This is why the series is
marked as RFC/RFT. I want to get it out for reviews and first tests before I
leave for EOSS and later on vacation. I am aware of some instabilities so don't
be surprised by an occasional segfault.

While I split the GLib and DBus code into several commits for easier review,
I intend to apply all changes to bindings/glib/ and dbus/ as two big commits
in the end as otherwise the split commits are not buildable until all of them
are applied.

The main point of interest is the DBus interface definition XML at
dbus/lib/io.gpiod1.xml as it is what defines the actual DBus API. Everything
else can be considered as implementation details as it's easier to change
later than the API that's supposed to be stable once released.

The first two patches expose the test infrastructure we use for the core
library and tools to the GLib bindings and dbus code. Next we add the GLib
bindings themselves. Not much to discuss here, they cover the entire libgpiod
API but wrap it in GObject abstractions and plug into the GLib event loop.

Finally we add the DBus code that's split into the daemon and command-line
client. I added some examples to the README and documented the behavior in
the help text of the programs as well as documented the interface file with
XML comments that gdbus-codegen can parse and use to generate docbook output.

For DBus, most of the testing happens in the command-line client bash tests.
It has a very good coverage of the daemon's code and also allows to run the
daemon through valgrind and verify there are no memory leaks and invalid
accesses. I still intend to extend the C test-suite for DBus with some corner
cases but didn't not have enough time for it.

Bartosz Golaszewski (18):
  tests: split out reusable test code into a local static library
  tests: split out the common test code for bash scripts
  bindings: glib: add build files
  bindings: glib: add public headers
  bindings: glib: add core code
  bindings: glib: add examples
  bindings: glib: add tests
  README: document GLib bindings
  dbus: add build files
  dbus: add the API definitions
  dbus: add a wrapper around the gdbus-codegen generated header
  dbus: add data files
  dbus: add gpio-manager code
  dbus: add tests
  dbus: add a command-line client
  dbus: client: add tests
  README: document the DBus API
  TODO: drop the DBus daemon from the list

 .gitignore                                    |    2 +
 Doxyfile.in                                   |    4 +-
 Makefile.am                                   |    7 +
 README                                        |   73 +-
 TODO                                          |   17 -
 bindings/Makefile.am                          |    7 +
 bindings/glib/Makefile.am                     |   78 +
 bindings/glib/chip-info.c                     |  118 ++
 bindings/glib/chip.c                          |  396 +++++
 bindings/glib/edge-event.c                    |  158 ++
 bindings/glib/error.c                         |   67 +
 bindings/glib/examples/.gitignore             |   14 +
 bindings/glib/examples/Makefile.am            |   22 +
 .../glib/examples/find_line_by_name_glib.c    |   72 +
 bindings/glib/examples/get_chip_info_glib.c   |   39 +
 bindings/glib/examples/get_line_info_glib.c   |   79 +
 bindings/glib/examples/get_line_value_glib.c  |   67 +
 .../examples/get_multiple_line_values_glib.c  |   72 +
 .../reconfigure_input_to_output_glib.c        |  103 ++
 .../glib/examples/toggle_line_value_glib.c    |   99 ++
 .../toggle_multiple_line_values_glib.c        |  132 ++
 bindings/glib/examples/watch_line_info_glib.c |   63 +
 .../glib/examples/watch_line_value_glib.c     |   91 ++
 .../watch_multiple_edge_rising_glib.c         |   95 ++
 bindings/glib/generated-enums.c.template      |   43 +
 bindings/glib/generated-enums.h.template      |   30 +
 bindings/glib/gpiod-glib.h                    |   33 +
 bindings/glib/gpiod-glib.pc.in                |   14 +
 bindings/glib/gpiod-glib/Makefile.am          |   18 +
 bindings/glib/gpiod-glib/chip-info.h          |   84 +
 bindings/glib/gpiod-glib/chip.h               |  164 ++
 bindings/glib/gpiod-glib/edge-event.h         |  114 ++
 bindings/glib/gpiod-glib/error.h              |   67 +
 bindings/glib/gpiod-glib/info-event.h         |   97 ++
 bindings/glib/gpiod-glib/line-config.h        |  116 ++
 bindings/glib/gpiod-glib/line-info.h          |  171 ++
 bindings/glib/gpiod-glib/line-request.h       |  182 +++
 bindings/glib/gpiod-glib/line-settings.h      |  202 +++
 bindings/glib/gpiod-glib/line.h               |  114 ++
 bindings/glib/gpiod-glib/misc.h               |   51 +
 bindings/glib/gpiod-glib/request-config.h     |  107 ++
 bindings/glib/info-event.c                    |  150 ++
 bindings/glib/internal.c                      |  334 ++++
 bindings/glib/internal.h                      |   54 +
 bindings/glib/line-config.c                   |  186 +++
 bindings/glib/line-info.c                     |  274 ++++
 bindings/glib/line-request.c                  |  434 +++++
 bindings/glib/line-settings.c                 |  359 ++++
 bindings/glib/misc.c                          |   17 +
 bindings/glib/request-config.c                |  155 ++
 bindings/glib/tests/.gitignore                |    4 +
 bindings/glib/tests/Makefile.am               |   29 +
 bindings/glib/tests/helpers.c                 |   12 +
 bindings/glib/tests/helpers.h                 |  139 ++
 bindings/glib/tests/tests-chip-info.c         |   55 +
 bindings/glib/tests/tests-chip.c              |  183 +++
 bindings/glib/tests/tests-edge-event.c        |  226 +++
 bindings/glib/tests/tests-info-event.c        |  321 ++++
 bindings/glib/tests/tests-line-config.c       |  186 +++
 bindings/glib/tests/tests-line-info.c         |   98 ++
 bindings/glib/tests/tests-line-request.c      |  704 ++++++++
 bindings/glib/tests/tests-line-settings.c     |  252 +++
 bindings/glib/tests/tests-misc.c              |   88 +
 bindings/glib/tests/tests-request-config.c    |   58 +
 configure.ac                                  |   72 +
 dbus/Makefile.am                              |   10 +
 dbus/client/.gitignore                        |    4 +
 dbus/client/Makefile.am                       |   30 +
 dbus/client/common.c                          |  644 ++++++++
 dbus/client/common.h                          |  203 +++
 dbus/client/detect.c                          |   53 +
 dbus/client/find.c                            |   66 +
 dbus/client/get.c                             |  210 +++
 dbus/client/gpiocli-test.bash                 | 1439 +++++++++++++++++
 dbus/client/gpiocli.c                         |  174 ++
 dbus/client/info.c                            |  184 +++
 dbus/client/monitor.c                         |  191 +++
 dbus/client/notify.c                          |  295 ++++
 dbus/client/reconfigure.c                     |   74 +
 dbus/client/release.c                         |   62 +
 dbus/client/request.c                         |  249 +++
 dbus/client/requests.c                        |   71 +
 dbus/client/set.c                             |  170 ++
 dbus/client/wait.c                            |  188 +++
 dbus/data/Makefile.am                         |   13 +
 dbus/data/gpio-manager.service                |   14 +
 dbus/data/io.gpiod1.conf                      |   29 +
 dbus/lib/Makefile.am                          |   28 +
 dbus/lib/gpiodbus.h                           |    9 +
 dbus/lib/io.gpiod1.xml                        |  318 ++++
 dbus/manager/.gitignore                       |    4 +
 dbus/manager/Makefile.am                      |   20 +
 dbus/manager/daemon.c                         |  821 ++++++++++
 dbus/manager/daemon.h                         |   22 +
 dbus/manager/gpio-manager.c                   |  167 ++
 dbus/manager/helpers.c                        |  420 +++++
 dbus/manager/helpers.h                        |   24 +
 dbus/tests/.gitignore                         |    4 +
 dbus/tests/Makefile.am                        |   25 +
 dbus/tests/daemon-process.c                   |  129 ++
 dbus/tests/daemon-process.h                   |   20 +
 dbus/tests/helpers.c                          |  107 ++
 dbus/tests/helpers.h                          |  112 ++
 dbus/tests/tests-chip.c                       |  133 ++
 dbus/tests/tests-line.c                       |  213 +++
 dbus/tests/tests-request.c                    |  116 ++
 tests/Makefile.am                             |   14 +-
 tests/bash/Makefile.am                        |    4 +
 tests/bash/gpiod-bash-test-helper.inc         |  328 ++++
 tests/gpiod-test-helpers.c                    |   41 -
 tests/gpiosim-glib/Makefile.am                |   13 +
 .../gpiosim-glib.c}                           |   30 +-
 .../gpiosim-glib.h}                           |   14 +
 tests/harness/Makefile.am                     |   12 +
 tests/harness/gpiod-test-common.h             |   23 +
 tests/{ => harness}/gpiod-test.c              |    0
 tests/{ => harness}/gpiod-test.h              |    0
 tests/{gpiod-test-helpers.h => helpers.h}     |   36 +-
 tests/tests-chip-info.c                       |    7 +-
 tests/tests-chip.c                            |   15 +-
 tests/tests-edge-event.c                      |    7 +-
 tests/tests-info-event.c                      |    7 +-
 tests/tests-line-config.c                     |    7 +-
 tests/tests-line-info.c                       |   11 +-
 tests/tests-line-request.c                    |    7 +-
 tests/tests-line-settings.c                   |    5 +-
 tests/tests-misc.c                            |    7 +-
 tests/tests-request-config.c                  |    5 +-
 tools/gpio-tools-test.bash                    |  559 ++-----
 129 files changed, 15510 insertions(+), 579 deletions(-)
 create mode 100644 bindings/glib/Makefile.am
 create mode 100644 bindings/glib/chip-info.c
 create mode 100644 bindings/glib/chip.c
 create mode 100644 bindings/glib/edge-event.c
 create mode 100644 bindings/glib/error.c
 create mode 100644 bindings/glib/examples/.gitignore
 create mode 100644 bindings/glib/examples/Makefile.am
 create mode 100644 bindings/glib/examples/find_line_by_name_glib.c
 create mode 100644 bindings/glib/examples/get_chip_info_glib.c
 create mode 100644 bindings/glib/examples/get_line_info_glib.c
 create mode 100644 bindings/glib/examples/get_line_value_glib.c
 create mode 100644 bindings/glib/examples/get_multiple_line_values_glib.c
 create mode 100644 bindings/glib/examples/reconfigure_input_to_output_glib.c
 create mode 100644 bindings/glib/examples/toggle_line_value_glib.c
 create mode 100644 bindings/glib/examples/toggle_multiple_line_values_glib.c
 create mode 100644 bindings/glib/examples/watch_line_info_glib.c
 create mode 100644 bindings/glib/examples/watch_line_value_glib.c
 create mode 100644 bindings/glib/examples/watch_multiple_edge_rising_glib.c
 create mode 100644 bindings/glib/generated-enums.c.template
 create mode 100644 bindings/glib/generated-enums.h.template
 create mode 100644 bindings/glib/gpiod-glib.h
 create mode 100644 bindings/glib/gpiod-glib.pc.in
 create mode 100644 bindings/glib/gpiod-glib/Makefile.am
 create mode 100644 bindings/glib/gpiod-glib/chip-info.h
 create mode 100644 bindings/glib/gpiod-glib/chip.h
 create mode 100644 bindings/glib/gpiod-glib/edge-event.h
 create mode 100644 bindings/glib/gpiod-glib/error.h
 create mode 100644 bindings/glib/gpiod-glib/info-event.h
 create mode 100644 bindings/glib/gpiod-glib/line-config.h
 create mode 100644 bindings/glib/gpiod-glib/line-info.h
 create mode 100644 bindings/glib/gpiod-glib/line-request.h
 create mode 100644 bindings/glib/gpiod-glib/line-settings.h
 create mode 100644 bindings/glib/gpiod-glib/line.h
 create mode 100644 bindings/glib/gpiod-glib/misc.h
 create mode 100644 bindings/glib/gpiod-glib/request-config.h
 create mode 100644 bindings/glib/info-event.c
 create mode 100644 bindings/glib/internal.c
 create mode 100644 bindings/glib/internal.h
 create mode 100644 bindings/glib/line-config.c
 create mode 100644 bindings/glib/line-info.c
 create mode 100644 bindings/glib/line-request.c
 create mode 100644 bindings/glib/line-settings.c
 create mode 100644 bindings/glib/misc.c
 create mode 100644 bindings/glib/request-config.c
 create mode 100644 bindings/glib/tests/.gitignore
 create mode 100644 bindings/glib/tests/Makefile.am
 create mode 100644 bindings/glib/tests/helpers.c
 create mode 100644 bindings/glib/tests/helpers.h
 create mode 100644 bindings/glib/tests/tests-chip-info.c
 create mode 100644 bindings/glib/tests/tests-chip.c
 create mode 100644 bindings/glib/tests/tests-edge-event.c
 create mode 100644 bindings/glib/tests/tests-info-event.c
 create mode 100644 bindings/glib/tests/tests-line-config.c
 create mode 100644 bindings/glib/tests/tests-line-info.c
 create mode 100644 bindings/glib/tests/tests-line-request.c
 create mode 100644 bindings/glib/tests/tests-line-settings.c
 create mode 100644 bindings/glib/tests/tests-misc.c
 create mode 100644 bindings/glib/tests/tests-request-config.c
 create mode 100644 dbus/Makefile.am
 create mode 100644 dbus/client/.gitignore
 create mode 100644 dbus/client/Makefile.am
 create mode 100644 dbus/client/common.c
 create mode 100644 dbus/client/common.h
 create mode 100644 dbus/client/detect.c
 create mode 100644 dbus/client/find.c
 create mode 100644 dbus/client/get.c
 create mode 100755 dbus/client/gpiocli-test.bash
 create mode 100644 dbus/client/gpiocli.c
 create mode 100644 dbus/client/info.c
 create mode 100644 dbus/client/monitor.c
 create mode 100644 dbus/client/notify.c
 create mode 100644 dbus/client/reconfigure.c
 create mode 100644 dbus/client/release.c
 create mode 100644 dbus/client/request.c
 create mode 100644 dbus/client/requests.c
 create mode 100644 dbus/client/set.c
 create mode 100644 dbus/client/wait.c
 create mode 100644 dbus/data/Makefile.am
 create mode 100644 dbus/data/gpio-manager.service
 create mode 100644 dbus/data/io.gpiod1.conf
 create mode 100644 dbus/lib/Makefile.am
 create mode 100644 dbus/lib/gpiodbus.h
 create mode 100644 dbus/lib/io.gpiod1.xml
 create mode 100644 dbus/manager/.gitignore
 create mode 100644 dbus/manager/Makefile.am
 create mode 100644 dbus/manager/daemon.c
 create mode 100644 dbus/manager/daemon.h
 create mode 100644 dbus/manager/gpio-manager.c
 create mode 100644 dbus/manager/helpers.c
 create mode 100644 dbus/manager/helpers.h
 create mode 100644 dbus/tests/.gitignore
 create mode 100644 dbus/tests/Makefile.am
 create mode 100644 dbus/tests/daemon-process.c
 create mode 100644 dbus/tests/daemon-process.h
 create mode 100644 dbus/tests/helpers.c
 create mode 100644 dbus/tests/helpers.h
 create mode 100644 dbus/tests/tests-chip.c
 create mode 100644 dbus/tests/tests-line.c
 create mode 100644 dbus/tests/tests-request.c
 create mode 100644 tests/bash/Makefile.am
 create mode 100644 tests/bash/gpiod-bash-test-helper.inc
 delete mode 100644 tests/gpiod-test-helpers.c
 create mode 100644 tests/gpiosim-glib/Makefile.am
 rename tests/{gpiod-test-sim.c => gpiosim-glib/gpiosim-glib.c} (93%)
 rename tests/{gpiod-test-sim.h => gpiosim-glib/gpiosim-glib.h} (86%)
 create mode 100644 tests/harness/Makefile.am
 create mode 100644 tests/harness/gpiod-test-common.h
 rename tests/{ => harness}/gpiod-test.c (100%)
 rename tests/{ => harness}/gpiod-test.h (100%)
 rename tests/{gpiod-test-helpers.h => helpers.h} (87%)

Comments

Andy Shevchenko April 23, 2024, 5:41 p.m. UTC | #1
On Fri, Apr 12, 2024 at 02:27:46PM +0200, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> This has been in the works for a long time but I'm finally ready to share it
> with the world. This introduces the DBus API definition and its implementation
> in the form of a GPIO manager daemon and a companion command-line client as
> well as GLib bindings to libgpiod which form the base on which the former are
> built.
> 
> Please note that while the functionality is complete, the dbus part still
> requires some work (bug fixing, corner-cases, general ironing out of all the
> wrinkles, a lot of code could be refactored too). This is why the series is
> marked as RFC/RFT. I want to get it out for reviews and first tests before I
> leave for EOSS and later on vacation. I am aware of some instabilities so don't
> be surprised by an occasional segfault.
> 
> While I split the GLib and DBus code into several commits for easier review,
> I intend to apply all changes to bindings/glib/ and dbus/ as two big commits
> in the end as otherwise the split commits are not buildable until all of them
> are applied.
> 
> The main point of interest is the DBus interface definition XML at
> dbus/lib/io.gpiod1.xml as it is what defines the actual DBus API. Everything
> else can be considered as implementation details as it's easier to change
> later than the API that's supposed to be stable once released.
> 
> The first two patches expose the test infrastructure we use for the core
> library and tools to the GLib bindings and dbus code. Next we add the GLib
> bindings themselves. Not much to discuss here, they cover the entire libgpiod
> API but wrap it in GObject abstractions and plug into the GLib event loop.
> 
> Finally we add the DBus code that's split into the daemon and command-line
> client. I added some examples to the README and documented the behavior in
> the help text of the programs as well as documented the interface file with
> XML comments that gdbus-codegen can parse and use to generate docbook output.
> 
> For DBus, most of the testing happens in the command-line client bash tests.
> It has a very good coverage of the daemon's code and also allows to run the
> daemon through valgrind and verify there are no memory leaks and invalid
> accesses. I still intend to extend the C test-suite for DBus with some corner
> cases but didn't not have enough time for it.

I might have time to briefly look at this code, but I can't test right away as
I have no setup that uses D-Bus, all what I use is a simplest Buildroot +
Busybox.
Bartosz Golaszewski April 23, 2024, 5:44 p.m. UTC | #2
On Tue, Apr 23, 2024 at 7:41 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Fri, Apr 12, 2024 at 02:27:46PM +0200, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > For DBus, most of the testing happens in the command-line client bash tests.
> > It has a very good coverage of the daemon's code and also allows to run the
> > daemon through valgrind and verify there are no memory leaks and invalid
> > accesses. I still intend to extend the C test-suite for DBus with some corner
> > cases but didn't not have enough time for it.
>
> I might have time to briefly look at this code, but I can't test right away as
> I have no setup that uses D-Bus, all what I use is a simplest Buildroot +
> Busybox.
>

It's my long-term plan to also have some hand-written, binary protocol
and a simpler daemon that implements it. But it's going to be a couple
years most likely before it happens.

For now: this is aimed at people who use proper distros which
typically include systemd and dbus.

Bart
A. Sverdlin June 28, 2024, 4:16 p.m. UTC | #3
Hello Bartosz!

On Fri, 2024-04-12 at 14:27 +0200, Bartosz Golaszewski wrote:
> This has been in the works for a long time but I'm finally ready to share it
> with the world. This introduces the DBus API definition and its implementation
> in the form of a GPIO manager daemon and a companion command-line client as
> well as GLib bindings to libgpiod which form the base on which the former are
> built.

Thanks a lot for your efforts!

> Finally we add the DBus code that's split into the daemon and command-line
> client. I added some examples to the README and documented the behavior in
> the help text of the programs as well as documented the interface file with
> XML comments that gdbus-codegen can parse and use to generate docbook output.

To me it looks like the long time anticipated replacement of [persistent]
SYSFS userspace API finally landed and one can start thinking about phasing
out the API declared obsolete in Linux v4.8 ;-)

I've compiled gpio-manager and gpiocli for TI am625 (arm64) and tested on
some HW one may compare to Beagle Play.

To me it looks solid, no problems whatsoever noticed up to now, even though
some non-obvious limitations do exist
("gpiocli request: all requested lines must belong to the same chip"), but
this probably can either be justified in documentation or improved even
after merging.

Will be happy to provide Tested-by: as soon as you send the series for
merging!
Bartosz Golaszewski June 28, 2024, 7:04 p.m. UTC | #4
On Fri, Jun 28, 2024 at 6:16 PM Sverdlin, Alexander
<alexander.sverdlin@siemens.com> wrote:
>
> Hello Bartosz!
>
> On Fri, 2024-04-12 at 14:27 +0200, Bartosz Golaszewski wrote:
> > This has been in the works for a long time but I'm finally ready to share it
> > with the world. This introduces the DBus API definition and its implementation
> > in the form of a GPIO manager daemon and a companion command-line client as
> > well as GLib bindings to libgpiod which form the base on which the former are
> > built.
>
> Thanks a lot for your efforts!
>
> > Finally we add the DBus code that's split into the daemon and command-line
> > client. I added some examples to the README and documented the behavior in
> > the help text of the programs as well as documented the interface file with
> > XML comments that gdbus-codegen can parse and use to generate docbook output.
>
> To me it looks like the long time anticipated replacement of [persistent]
> SYSFS userspace API finally landed and one can start thinking about phasing
> out the API declared obsolete in Linux v4.8 ;-)
>

That's precisely the goal.

> I've compiled gpio-manager and gpiocli for TI am625 (arm64) and tested on
> some HW one may compare to Beagle Play.
>
> To me it looks solid, no problems whatsoever noticed up to now, even though
> some non-obvious limitations do exist
> ("gpiocli request: all requested lines must belong to the same chip"), but
> this probably can either be justified in documentation or improved even
> after merging.
>

Awesome, thank you!

> Will be happy to provide Tested-by: as soon as you send the series for
> merging!

Thanks, please take a look at v2 as well[1]!

Bart

[1] https://lore.kernel.org/linux-gpio/20240628-dbus-v2-0-c1331ac17cb8@linaro.org/