summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Kukawka <danny.kukawka@web.de>2008-11-28 19:30:19 +0100
committerDanny Kukawka <danny.kukawka@web.de>2008-11-28 19:30:19 +0100
commit33d15dd2d91f06c6eb629eae5694b4945ef1ba7d (patch)
treebfc92153e3b54311ad6828fe54c3551756e8467b
parenteef409dfc82433edb32c73ce352671ab7fb1f79d (diff)
add a new singleton addon to handle leds
Added a new singleton addon to handle led devices. The new interface is called org.freedesktop.Hal.Device.Leds and provide these methodes: - int SetBrightness (int brightness_value) - int GetBrightness ()
-rw-r--r--fdi/policy/10osvendor/10-leds.fdi15
-rw-r--r--fdi/policy/10osvendor/Makefile.am1
-rw-r--r--hald/linux/addons/Makefile.am3
-rw-r--r--hald/linux/addons/addon-leds.c347
-rw-r--r--policy/Makefile.am1
-rw-r--r--policy/org.freedesktop.hal.leds.policy28
6 files changed, 395 insertions, 0 deletions
diff --git a/fdi/policy/10osvendor/10-leds.fdi b/fdi/policy/10osvendor/10-leds.fdi
new file mode 100644
index 00000000..1d14545d
--- /dev/null
+++ b/fdi/policy/10osvendor/10-leds.fdi
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+
+ <device>
+ <match key="info.capabilities" contains="leds">
+ <match key="leds.device_name" exists="true">
+ <match key="leds.function" exists="true">
+ <append key="info.addons.singleton" type="strlist">hald-addon-leds</append>
+ </match>
+ </match>
+ </match>
+ </device>
+
+</deviceinfo>
diff --git a/fdi/policy/10osvendor/Makefile.am b/fdi/policy/10osvendor/Makefile.am
index a30aac04..67c021c3 100644
--- a/fdi/policy/10osvendor/Makefile.am
+++ b/fdi/policy/10osvendor/Makefile.am
@@ -5,6 +5,7 @@ dist_fdi_DATA = \
10-input-policy.fdi \
10-dockstation.fdi \
10-laptop-panel-mgmt-policy.fdi \
+ 10-leds.fdi \
10-power-mgmt-policy.fdi \
10-rfkill-switch.fdi \
10-tabletPCs.fdi \
diff --git a/hald/linux/addons/Makefile.am b/hald/linux/addons/Makefile.am
index ccfb6e65..b4a7ef95 100644
--- a/hald/linux/addons/Makefile.am
+++ b/hald/linux/addons/Makefile.am
@@ -14,6 +14,7 @@ libexec_PROGRAMS = \
hald-addon-hid-ups \
hald-addon-input \
hald-addon-ipw-killswitch \
+ hald-addon-leds \
hald-addon-rfkill-killswitch \
hald-addon-storage
@@ -105,3 +106,5 @@ hald_addon_ipw_killswitch_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@
hald_addon_rfkill_killswitch_SOURCES = addon-rfkill-killswitch.c ../../logger.c ../../util_helper.c ../../util_helper_priv.c
hald_addon_rfkill_killswitch_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@
+hald_addon_leds_SOURCES = addon-leds.c ../../logger.c ../../util_helper.c ../../util_helper_priv.c
+hald_addon_leds_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@
diff --git a/hald/linux/addons/addon-leds.c b/hald/linux/addons/addon-leds.c
new file mode 100644
index 00000000..86997b1c
--- /dev/null
+++ b/hald/linux/addons/addon-leds.c
@@ -0,0 +1,347 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * addon-leds.c:
+ * Copyright (C) 2008 Danny Kukawka <danny.kukawka@web.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gmain.h>
+#include <glib/gstdio.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "libhal/libhal.h"
+#include "../../logger.h"
+#include "../../util_helper.h"
+#include "../../util_helper_priv.h"
+
+static GMainLoop *gmain = NULL;
+static LibHalContext *ctx = NULL;
+static GHashTable *leds = NULL;
+
+/* Getting current brightness */
+static int
+get_leds_brightness (const char *udi)
+{
+ FILE *f;
+ char buf[64];
+ char path[256];
+ char *sysfs_path;
+ int brightness;
+
+ f = NULL;
+
+ if (!g_hash_table_lookup_extended (leds, udi, NULL, (gpointer) &sysfs_path)) {
+ return -1;
+ }
+
+ snprintf (path, sizeof (path), "%s/brightness", sysfs_path);
+
+ if ((f = fopen (path, "rb")) == NULL) {
+ HAL_WARNING(("Could not read brightness from '%s' for device '%s'", path, udi));
+ return -1;
+ }
+
+ if (fgets (buf, sizeof (buf), f) == NULL) {
+ HAL_ERROR (("Cannot read from '%s' for device '%s'", path, udi));
+ goto out;
+ }
+
+ errno = 0;
+ brightness = strtol (buf, NULL, 10);
+ if (errno != 0) {
+ brightness = -1;
+ }
+
+out:
+ if (f != NULL)
+ fclose (f);
+
+ return brightness;
+}
+
+/* Setting current brightness of the led */
+static int
+set_leds_brightness (const char *udi, int level)
+{
+ int fd, l, ret;
+ char path[256];
+ char buf[5]; /* Assume we don't need more */
+ char *sysfs_path;
+
+ ret = -1;
+
+ if (!g_hash_table_lookup_extended (leds, udi, NULL, (gpointer) &sysfs_path)) {
+ return -1;
+ }
+
+ snprintf (path, sizeof (path), "%s/brightness", sysfs_path);
+
+ fd = open (path, O_WRONLY);
+ if (fd < 0) {
+ HAL_WARNING(("Could not open '%s' for '%s', error='%s'", sysfs_path, udi, strerror(errno)));
+ goto out;
+ }
+
+ if ((l = snprintf (buf, 4, "%d", level)) < 4) {
+ if (write (fd, buf, l) < 0) {
+ HAL_WARNING(("Could not write '%s' to '%s'", buf , sysfs_path));
+ } else {
+ /* everything okay */
+ ret = level;
+ }
+ }
+
+out:
+ if (fd >= 0)
+ close (fd);
+
+ return ret;
+}
+
+/* DBus filter function */
+static DBusHandlerResult
+filter_function (DBusConnection *connection, DBusMessage *message, void *userdata)
+{
+ DBusError err;
+ DBusMessage *reply;
+ const char *_udi;
+ char *sysfs_path;
+
+ if ((_udi = dbus_message_get_path (message)) == NULL) {
+ HAL_DEBUG (("Couldn't get the udi for this call, ignore it."));
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else {
+ if(!g_hash_table_lookup_extended (leds, _udi, NULL, (gpointer *) &sysfs_path)) {
+ HAL_DEBUG (("This device (%s) isn't yet handled by the addon.", _udi));
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+
+ dbus_error_init (&err);
+
+ if (!check_priv (ctx, connection, message, dbus_message_get_path (message), "org.freedesktop.hal.leds.brightness")) {
+ HAL_DEBUG(("User don't have the permissions to call the interface"));
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ reply = NULL;
+
+ if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device.Leds",
+ "SetBrightness")) {
+ int brightness;
+
+ dbus_error_init (&err);
+ if (dbus_message_get_args (message,
+ &err,
+ DBUS_TYPE_INT32, &brightness,
+ DBUS_TYPE_INVALID)) {
+ int return_code = 0;
+ int set;
+
+ set = set_leds_brightness (_udi, brightness);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ goto error;
+
+ if (set == brightness)
+ return_code = 0;
+ else
+ return_code = 1;
+
+ dbus_message_append_args (reply,
+ DBUS_TYPE_INT32, &return_code,
+ DBUS_TYPE_INVALID);
+
+ dbus_connection_send (connection, reply, NULL);
+ }
+ } else if (dbus_message_is_method_call (message,
+ "org.freedesktop.Hal.Device.Leds",
+ "GetBrightness")) {
+ int brightness;
+
+ dbus_error_init (&err);
+ if (dbus_message_get_args (message,
+ &err,
+ DBUS_TYPE_INVALID)) {
+ brightness = get_leds_brightness(_udi);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ goto error;
+
+ dbus_message_append_args (reply,
+ DBUS_TYPE_INT32, &brightness,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ }
+ }
+
+error:
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void
+add_device (LibHalContext *ctx,
+ const char *udi,
+ const LibHalPropertySet *properties)
+{
+ DBusError err;
+ DBusConnection *dbus_connection;
+ const char* sysfs_path;
+ static gboolean initialized = FALSE;
+
+ if ((sysfs_path = libhal_ps_get_string (properties, "linux.sysfs_path")) == NULL) {
+ HAL_ERROR(("%s has no property linux.sysfs_path", udi));
+ return;
+ }
+
+ /* claim the interface */
+
+ if ((dbus_connection = libhal_ctx_get_dbus_connection(ctx)) == NULL) {
+ HAL_WARNING (("Cannot get DBus connection"));
+ return;
+ }
+
+ if (!initialized) {
+ dbus_connection_add_filter (dbus_connection, filter_function, NULL, NULL);
+ initialized = TRUE;
+ }
+
+ dbus_error_init (&err);
+
+ if (!libhal_device_claim_interface (ctx,
+ udi,
+ "org.freedesktop.Hal.Device.Leds",
+ " <method name=\"SetBrightness\">\n"
+ " <arg name=\"brightness_value\" direction=\"in\" type=\"i\"/>\n"
+ " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
+ " </method>\n"
+ " <method name=\"GetBrightness\">\n"
+ " <arg name=\"brightness_value\" direction=\"out\" type=\"i\"/>\n"
+ " </method>\n",
+ &err)) {
+ HAL_ERROR (("Cannot claim interface 'org.freedesktop.Hal.Device.Leds'"));
+ return;
+ }
+
+ g_hash_table_insert (leds, g_strdup(udi), g_strdup(sysfs_path));
+}
+
+static void
+remove_device (LibHalContext *ctx,
+ const char *udi,
+ const LibHalPropertySet *properties)
+{
+ gpointer sysfs_path;
+ gboolean handling_udi;
+
+ HAL_DEBUG (("Removing channel for '%s'", udi));
+
+ handling_udi = g_hash_table_lookup_extended (leds, udi, NULL, &sysfs_path);
+
+ if (!handling_udi) {
+ HAL_ERROR(("DeviceRemove called for unknown device: '%s'.", udi));
+ return;
+ }
+
+ g_hash_table_remove (leds, udi);
+
+ if (g_hash_table_size (leds) == 0) {
+ HAL_INFO(("no more devices, exiting"));
+ g_main_loop_quit (gmain);
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ DBusConnection *dbus_connection;
+ DBusError error;
+ const char *commandline;
+
+ hal_set_proc_title_init (argc, argv);
+
+ setup_logger ();
+
+ dbus_error_init (&error);
+ if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ HAL_WARNING (("Unable to init libhal context"));
+ goto out;
+ }
+
+ if ((dbus_connection = libhal_ctx_get_dbus_connection(ctx)) == NULL) {
+ HAL_WARNING (("Cannot get DBus connection"));
+ goto out;
+ }
+
+ if ((commandline = getenv ("SINGLETON_COMMAND_LINE")) == NULL) {
+ HAL_WARNING (("SINGLETON_COMMAND_LINE not set"));
+ goto out;
+ }
+
+ libhal_ctx_set_singleton_device_added (ctx, add_device);
+ libhal_ctx_set_singleton_device_removed (ctx, remove_device);
+
+ dbus_connection_setup_with_g_main (dbus_connection, NULL);
+ dbus_connection_set_exit_on_disconnect (dbus_connection, 0);
+
+ dbus_error_init (&error);
+
+ if (!libhal_device_singleton_addon_is_ready (ctx, commandline, &error)) {
+ goto out;
+ }
+
+ leds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ gmain = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (gmain);
+
+ return 0;
+
+out:
+ HAL_DEBUG (("An error occured, exiting cleanly"));
+ if (ctx != NULL) {
+ dbus_error_init (&error);
+ libhal_ctx_shutdown (ctx, &error);
+ libhal_ctx_free (ctx);
+ }
+
+ return 0;
+}
diff --git a/policy/Makefile.am b/policy/Makefile.am
index 28f31d41..b506a088 100644
--- a/policy/Makefile.am
+++ b/policy/Makefile.am
@@ -8,6 +8,7 @@ dist_polkit_policy_DATA = \
org.freedesktop.hal.power-management.policy \
org.freedesktop.hal.killswitch.policy \
org.freedesktop.hal.dockstation.policy \
+ org.freedesktop.hal.leds.policy \
org.freedesktop.hal.wol.policy
if HAVE_ACLMGMT
diff --git a/policy/org.freedesktop.hal.leds.policy b/policy/org.freedesktop.hal.leds.policy
new file mode 100644
index 00000000..c7d852e1
--- /dev/null
+++ b/policy/org.freedesktop.hal.leds.policy
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+
+<!--
+Policy definitions for HAL's ACL Management mechanism
+
+Copyright (c) 2008 Danny Kukawka <danny.kukawka@web.de>
+
+HAL is licensed to you under your choice of the the Academic Free
+License Version 2.1, or the GNU General Public License version 2. Some
+individual source files may be under the GPL only. See COPYING for
+details.
+-->
+
+<policyconfig>
+
+ <action id="org.freedesktop.hal.leds.brightness">
+ <description>Set the brightness of a led device</description>
+ <message>System policy prevents adjusting the led brightness</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
+</policyconfig>