12912Sartem /***************************************************************************
22912Sartem * CVSID: $Id$
32912Sartem *
42912Sartem * libhal.c : HAL daemon C convenience library
52912Sartem *
62912Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
76293Sartem * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
82912Sartem *
92912Sartem * Licensed under the Academic Free License version 2.1
102912Sartem *
112912Sartem * This program is free software; you can redistribute it and/or modify
122912Sartem * it under the terms of the GNU General Public License as published by
132912Sartem * the Free Software Foundation; either version 2 of the License, or
142912Sartem * (at your option) any later version.
152912Sartem *
162912Sartem * This program is distributed in the hope that it will be useful,
172912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of
182912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
192912Sartem * GNU General Public License for more details.
202912Sartem *
212912Sartem * You should have received a copy of the GNU General Public License
222912Sartem * along with this program; if not, write to the Free Software
232912Sartem * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
242912Sartem *
252912Sartem **************************************************************************/
262912Sartem
272912Sartem #ifdef HAVE_CONFIG_H
282912Sartem # include <config.h>
292912Sartem #endif
302912Sartem
312912Sartem #include <stdio.h>
322912Sartem #include <stdlib.h>
332912Sartem #include <string.h>
342912Sartem #include <dbus/dbus.h>
352912Sartem
362912Sartem #include "libhal.h"
372912Sartem
382912Sartem #ifdef ENABLE_NLS
392912Sartem # include <libintl.h>
402912Sartem # define _(String) dgettext (GETTEXT_PACKAGE, String)
412912Sartem # ifdef gettext_noop
422912Sartem # define N_(String) gettext_noop (String)
432912Sartem # else
442912Sartem # define N_(String) (String)
452912Sartem # endif
462912Sartem #else
472912Sartem /* Stubs that do something close enough. */
482912Sartem # define textdomain(String) (String)
492912Sartem # define gettext(String) (String)
502912Sartem # define dgettext(Domain,Message) (Message)
512912Sartem # define dcgettext(Domain,Message,Type) (Message)
522912Sartem # define bindtextdomain(Domain,Directory) (Domain)
532912Sartem # define _(String)
542912Sartem # define N_(String) (String)
552912Sartem #endif
562912Sartem
576293Sartem /**
586293Sartem * LIBHAL_CHECK_PARAM_VALID:
596293Sartem * @_param_: the prameter to check for
606293Sartem * @_name_: the name of the prameter (for debug output)
616293Sartem * @_ret_: what to use for return value if the prameter is NULL
626293Sartem *
636293Sartem * Handy macro for checking whether a parameter is valid and not NULL.
646293Sartem */
656293Sartem #define LIBHAL_CHECK_PARAM_VALID(_param_,_name_,_ret_) \
666293Sartem do { \
676293Sartem if (_param_ == NULL) { \
686293Sartem fprintf (stderr, \
696293Sartem "%s %d : invalid paramater. %s is NULL.\n", \
706293Sartem __FILE__, __LINE__, _name_); \
716293Sartem return _ret_; \
726293Sartem } \
736293Sartem } while(0)
746293Sartem
756293Sartem
762912Sartem static char **libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements);
772912Sartem
782912Sartem static dbus_bool_t libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter);
792912Sartem
802912Sartem
812912Sartem
822912Sartem /**
832912Sartem * libhal_free_string_array:
842912Sartem * @str_array: the array to be freed
852912Sartem *
862912Sartem * Frees a NULL-terminated array of strings. If passed NULL, does nothing.
872912Sartem */
882912Sartem void
libhal_free_string_array(char ** str_array)892912Sartem libhal_free_string_array (char **str_array)
902912Sartem {
912912Sartem if (str_array != NULL) {
922912Sartem int i;
932912Sartem
942912Sartem for (i = 0; str_array[i] != NULL; i++) {
952912Sartem free (str_array[i]);
962912Sartem str_array[i] = NULL;
972912Sartem }
982912Sartem free (str_array);
992912Sartem str_array = NULL;
1002912Sartem }
1012912Sartem }
1022912Sartem
1032912Sartem
1042912Sartem /**
1052912Sartem * libhal_get_string_array_from_iter:
1062912Sartem * @iter: the message iterator to extract the strings from
1072912Sartem * @num_elements: pointer to an integer where to store number of elements (can be NULL)
1082912Sartem *
1092912Sartem * Creates a NULL terminated array of strings from a dbus message iterator.
1102912Sartem *
1112912Sartem * Returns: pointer to the string array
1122912Sartem */
1132912Sartem static char **
libhal_get_string_array_from_iter(DBusMessageIter * iter,int * num_elements)1142912Sartem libhal_get_string_array_from_iter (DBusMessageIter *iter, int *num_elements)
1152912Sartem {
1162912Sartem int count;
1172912Sartem char **buffer;
1182912Sartem
1192912Sartem count = 0;
1202912Sartem buffer = (char **)malloc (sizeof (char *) * 8);
1212912Sartem
1222912Sartem if (buffer == NULL)
1232912Sartem goto oom;
1242912Sartem
1252912Sartem buffer[0] = NULL;
1262912Sartem while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING) {
1272912Sartem const char *value;
1282912Sartem char *str;
1292912Sartem
1302912Sartem if ((count % 8) == 0 && count != 0) {
1312912Sartem buffer = realloc (buffer, sizeof (char *) * (count + 8));
1322912Sartem if (buffer == NULL)
1332912Sartem goto oom;
1342912Sartem }
1352912Sartem
1362912Sartem dbus_message_iter_get_basic (iter, &value);
1372912Sartem str = strdup (value);
1382912Sartem if (str == NULL)
1392912Sartem goto oom;
1402912Sartem
1412912Sartem buffer[count] = str;
1422912Sartem
1432912Sartem dbus_message_iter_next(iter);
1442912Sartem count++;
1452912Sartem }
1462912Sartem
1472912Sartem if ((count % 8) == 0) {
1482912Sartem buffer = realloc (buffer, sizeof (char *) * (count + 1));
1492912Sartem if (buffer == NULL)
1502912Sartem goto oom;
1512912Sartem }
1522912Sartem
1532912Sartem buffer[count] = NULL;
1542912Sartem if (num_elements != NULL)
1552912Sartem *num_elements = count;
1562912Sartem return buffer;
1572912Sartem
1582912Sartem oom:
1592912Sartem fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
1602912Sartem return NULL;
1612912Sartem
1622912Sartem }
1632912Sartem
1642912Sartem /**
1652912Sartem * libhal_free_string:
1662912Sartem * @str: the nul-terminated sting to free
1672912Sartem *
1682912Sartem * Used to free strings returned by libhal.
1692912Sartem */
1702912Sartem void
libhal_free_string(char * str)1712912Sartem libhal_free_string (char *str)
1722912Sartem {
1732912Sartem if (str != NULL) {
1742912Sartem free (str);
1752912Sartem str = NULL;
1762912Sartem }
1772912Sartem }
1782912Sartem
1792912Sartem
1802912Sartem /**
1812912Sartem * LibHalPropertySet:
1822912Sartem *
1832912Sartem * Represents a set of properties. Opaque; use the
1842912Sartem * libhal_property_set_*() family of functions to access it.
1852912Sartem */
1862912Sartem struct LibHalPropertySet_s {
1872912Sartem unsigned int num_properties; /**< Number of properties in set */
1882912Sartem LibHalProperty *properties_head;
1892912Sartem /**< Pointer to first property or NULL
1902912Sartem * if there are no properties */
1912912Sartem };
1922912Sartem
1932912Sartem /**
1942912Sartem * LibHalProperty:
1952912Sartem *
1962912Sartem * Represents a property. Opaque.
1972912Sartem */
1982912Sartem struct LibHalProperty_s {
1992912Sartem int type; /**< Type of property */
2002912Sartem char *key; /**< ASCII string */
2012912Sartem
2022912Sartem /** Possible values of the property */
2032912Sartem union {
2042912Sartem char *str_value; /**< UTF-8 zero-terminated string */
2052912Sartem dbus_int32_t int_value;
2062912Sartem /**< 32-bit signed integer */
2072912Sartem dbus_uint64_t uint64_value;
2082912Sartem /**< 64-bit unsigned integer */
2092912Sartem double double_value; /**< IEEE754 double precision float */
2102912Sartem dbus_bool_t bool_value;
2112912Sartem /**< Truth value */
2122912Sartem
2132912Sartem char **strlist_value; /**< List of UTF-8 zero-terminated strings */
2142912Sartem } v;
2152912Sartem
2162912Sartem LibHalProperty *next; /**< Next property or NULL if this is
2172912Sartem * the last */
2182912Sartem };
2192912Sartem
2202912Sartem /**
2212912Sartem * LibHalContext:
2222912Sartem *
2232912Sartem * Context for connection to the HAL daemon. Opaque, use the
2242912Sartem * libhal_ctx_*() family of functions to access it.
2252912Sartem */
2262912Sartem struct LibHalContext_s {
2272912Sartem DBusConnection *connection; /**< D-BUS connection */
2282912Sartem dbus_bool_t is_initialized; /**< Are we initialised */
2292912Sartem dbus_bool_t is_shutdown; /**< Have we been shutdown */
2302912Sartem dbus_bool_t cache_enabled; /**< Is the cache enabled */
2312912Sartem dbus_bool_t is_direct; /**< Whether the connection to hald is direct */
2322912Sartem
2332912Sartem /** Device added */
2342912Sartem LibHalDeviceAdded device_added;
2352912Sartem
2362912Sartem /** Device removed */
2372912Sartem LibHalDeviceRemoved device_removed;
2382912Sartem
2392912Sartem /** Device got a new capability */
2402912Sartem LibHalDeviceNewCapability device_new_capability;
2412912Sartem
2422912Sartem /** Device got a new capability */
2432912Sartem LibHalDeviceLostCapability device_lost_capability;
2442912Sartem
2452912Sartem /** A property of a device changed */
2462912Sartem LibHalDevicePropertyModified device_property_modified;
2472912Sartem
2482912Sartem /** A non-continous event on the device occured */
2492912Sartem LibHalDeviceCondition device_condition;
2502912Sartem
2512912Sartem void *user_data; /**< User data */
2522912Sartem };
2532912Sartem
2542912Sartem /**
2552912Sartem * libhal_ctx_set_user_data:
2562912Sartem * @ctx: the context for the connection to hald
2572912Sartem * @user_data: user data
2582912Sartem *
2592912Sartem * Set user data for the context.
2602912Sartem *
2612912Sartem * Returns: TRUE if user data was successfully set, FALSE if otherwise
2622912Sartem */
2632912Sartem dbus_bool_t
libhal_ctx_set_user_data(LibHalContext * ctx,void * user_data)2642912Sartem libhal_ctx_set_user_data(LibHalContext *ctx, void *user_data)
2652912Sartem {
2662912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
2672912Sartem ctx->user_data = user_data;
2682912Sartem return TRUE;
2692912Sartem }
2702912Sartem
2712912Sartem /**
2722912Sartem * libhal_ctx_get_user_data:
2732912Sartem * @ctx: the context for the connection to hald
2742912Sartem *
2752912Sartem * Get user data for the context.
2762912Sartem *
2772912Sartem * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set.
2782912Sartem */
2792912Sartem void*
libhal_ctx_get_user_data(LibHalContext * ctx)2802912Sartem libhal_ctx_get_user_data(LibHalContext *ctx)
2812912Sartem {
2822912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
2832912Sartem return ctx->user_data;
2842912Sartem }
2852912Sartem
2862912Sartem
2872912Sartem /**
2882912Sartem * libhal_property_fill_value_from_variant:
2892912Sartem * @p: the property to fill in
2902912Sartem * @var_iter: variant iterator to extract the value from
2912912Sartem *
2922912Sartem * Fills in the value for the LibHalProperty given a variant iterator.
2932912Sartem *
2942912Sartem * Returns: Whether the value was put in.
2952912Sartem */
2962912Sartem static dbus_bool_t
libhal_property_fill_value_from_variant(LibHalProperty * p,DBusMessageIter * var_iter)2972912Sartem libhal_property_fill_value_from_variant (LibHalProperty *p, DBusMessageIter *var_iter)
2982912Sartem {
2992912Sartem DBusMessageIter iter_array;
3002912Sartem switch (p->type) {
3012912Sartem case DBUS_TYPE_ARRAY:
3022912Sartem if (dbus_message_iter_get_element_type (var_iter) != DBUS_TYPE_STRING)
3032912Sartem return FALSE;
3042912Sartem
3052912Sartem dbus_message_iter_recurse (var_iter, &iter_array);
3062912Sartem p->v.strlist_value = libhal_get_string_array_from_iter (&iter_array, NULL);
3072912Sartem
3082912Sartem p->type = LIBHAL_PROPERTY_TYPE_STRLIST;
3092912Sartem
3102912Sartem break;
3112912Sartem case DBUS_TYPE_STRING:
3122912Sartem {
3132912Sartem const char *v;
3142912Sartem
3152912Sartem dbus_message_iter_get_basic (var_iter, &v);
3162912Sartem
3172912Sartem p->v.str_value = strdup (v);
3182912Sartem if (p->v.str_value == NULL)
3192912Sartem return FALSE;
3202912Sartem p->type = LIBHAL_PROPERTY_TYPE_STRING;
3212912Sartem
3222912Sartem break;
3232912Sartem }
3242912Sartem case DBUS_TYPE_INT32:
3252912Sartem {
3262912Sartem dbus_int32_t v;
3272912Sartem
3282912Sartem dbus_message_iter_get_basic (var_iter, &v);
3292912Sartem
3302912Sartem p->v.int_value = v;
3312912Sartem p->type = LIBHAL_PROPERTY_TYPE_INT32;
3322912Sartem
3332912Sartem break;
3342912Sartem }
3352912Sartem case DBUS_TYPE_UINT64:
3362912Sartem {
3372912Sartem dbus_uint64_t v;
3382912Sartem
3392912Sartem dbus_message_iter_get_basic (var_iter, &v);
3402912Sartem
3412912Sartem p->v.uint64_value = v;
3422912Sartem p->type = LIBHAL_PROPERTY_TYPE_UINT64;
3432912Sartem
3442912Sartem break;
3452912Sartem }
3462912Sartem case DBUS_TYPE_DOUBLE:
3472912Sartem {
3482912Sartem double v;
3492912Sartem
3502912Sartem dbus_message_iter_get_basic (var_iter, &v);
3512912Sartem
3522912Sartem p->v.double_value = v;
3532912Sartem p->type = LIBHAL_PROPERTY_TYPE_DOUBLE;
3542912Sartem
3552912Sartem break;
3562912Sartem }
3572912Sartem case DBUS_TYPE_BOOLEAN:
3582912Sartem {
3592912Sartem double v;
3602912Sartem
3612912Sartem dbus_message_iter_get_basic (var_iter, &v);
3622912Sartem
3632912Sartem p->v.double_value = v;
3642912Sartem p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
3652912Sartem
3662912Sartem break;
3672912Sartem }
3682912Sartem default:
3692912Sartem /** @todo report error */
3702912Sartem break;
3712912Sartem }
3722912Sartem
3732912Sartem return TRUE;
3742912Sartem }
3752912Sartem
3762912Sartem /**
3772912Sartem * libhal_device_get_all_properties:
3782912Sartem * @ctx: the context for the connection to hald
3792912Sartem * @udi: the Unique id of device
3802912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
3812912Sartem *
3822912Sartem * Retrieve all the properties on a device.
3832912Sartem *
3842912Sartem * Returns: An object represent all properties. Must be freed with libhal_free_property_set().
3852912Sartem */
3862912Sartem LibHalPropertySet *
libhal_device_get_all_properties(LibHalContext * ctx,const char * udi,DBusError * error)3872912Sartem libhal_device_get_all_properties (LibHalContext *ctx, const char *udi, DBusError *error)
3882912Sartem {
3892912Sartem DBusMessage *message;
3902912Sartem DBusMessage *reply;
3912912Sartem DBusMessageIter reply_iter;
3922912Sartem DBusMessageIter dict_iter;
3932912Sartem LibHalPropertySet *result;
3942912Sartem LibHalProperty *p_last;
3952912Sartem DBusError _error;
3962912Sartem
3972912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
3982912Sartem
3992912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
4002912Sartem "org.freedesktop.Hal.Device",
4012912Sartem "GetAllProperties");
4022912Sartem
4032912Sartem if (message == NULL) {
4042912Sartem fprintf (stderr,
4052912Sartem "%s %d : Couldn't allocate D-BUS message\n",
4062912Sartem __FILE__, __LINE__);
4072912Sartem return NULL;
4082912Sartem }
4092912Sartem
4102912Sartem dbus_error_init (&_error);
4112912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
4122912Sartem message, -1,
4132912Sartem &_error);
4142912Sartem
4152912Sartem dbus_move_error (&_error, error);
4162912Sartem if (error != NULL && dbus_error_is_set (error)) {
4172912Sartem fprintf (stderr,
4182912Sartem "%s %d : %s\n",
4192912Sartem __FILE__, __LINE__, error->message);
4202912Sartem
4212912Sartem dbus_message_unref (message);
4222912Sartem return NULL;
4232912Sartem }
4242912Sartem
4252912Sartem if (reply == NULL) {
4262912Sartem dbus_message_unref (message);
4272912Sartem return NULL;
4282912Sartem }
4292912Sartem
4302912Sartem dbus_message_iter_init (reply, &reply_iter);
4312912Sartem
4322912Sartem result = malloc (sizeof (LibHalPropertySet));
4332912Sartem if (result == NULL)
4342912Sartem goto oom;
4352912Sartem /*
4362912Sartem result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
4372912Sartem if( result->properties==NULL )
4382912Sartem {
4392912Sartem /// @todo cleanup
4402912Sartem return NULL;
4412912Sartem }
4422912Sartem */
4432912Sartem
4442912Sartem result->properties_head = NULL;
4452912Sartem result->num_properties = 0;
4462912Sartem
4472912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY &&
4482912Sartem dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
4492912Sartem fprintf (stderr, "%s %d : error, expecting an array of dict entries\n",
4502912Sartem __FILE__, __LINE__);
4512912Sartem dbus_message_unref (message);
4522912Sartem dbus_message_unref (reply);
4532912Sartem return NULL;
4542912Sartem }
4552912Sartem
4562912Sartem dbus_message_iter_recurse (&reply_iter, &dict_iter);
4572912Sartem
4582912Sartem p_last = NULL;
4592912Sartem
4602912Sartem while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY)
4612912Sartem {
4622912Sartem DBusMessageIter dict_entry_iter, var_iter;
4632912Sartem const char *key;
4642912Sartem LibHalProperty *p;
4652912Sartem
4662912Sartem dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
4672912Sartem
4682912Sartem dbus_message_iter_get_basic (&dict_entry_iter, &key);
4692912Sartem
4702912Sartem p = malloc (sizeof (LibHalProperty));
4712912Sartem if (p == NULL)
4722912Sartem goto oom;
4732912Sartem
4742912Sartem p->next = NULL;
4752912Sartem
4762912Sartem if (result->num_properties == 0)
4772912Sartem result->properties_head = p;
4782912Sartem
4792912Sartem if (p_last != NULL)
4802912Sartem p_last->next = p;
4812912Sartem
4822912Sartem p_last = p;
4832912Sartem
4842912Sartem p->key = strdup (key);
4852912Sartem if (p->key == NULL)
4862912Sartem goto oom;
4872912Sartem
4882912Sartem dbus_message_iter_next (&dict_entry_iter);
4892912Sartem
4902912Sartem dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
4912912Sartem
4922912Sartem
4932912Sartem p->type = dbus_message_iter_get_arg_type (&var_iter);
4942912Sartem
4952912Sartem result->num_properties++;
4962912Sartem
4972912Sartem if(!libhal_property_fill_value_from_variant (p, &var_iter))
4982912Sartem goto oom;
4992912Sartem
5002912Sartem dbus_message_iter_next (&dict_iter);
5012912Sartem }
5022912Sartem
5032912Sartem dbus_message_unref (message);
5042912Sartem dbus_message_unref (reply);
5052912Sartem
5062912Sartem return result;
5072912Sartem
5082912Sartem oom:
5092912Sartem fprintf (stderr,
5102912Sartem "%s %d : error allocating memory\n",
5112912Sartem __FILE__, __LINE__);
5122912Sartem /** @todo FIXME cleanup */
5132912Sartem return NULL;
5142912Sartem }
5152912Sartem
5162912Sartem /**
5172912Sartem * libhal_free_property_set:
5182912Sartem * @set: property-set to free
5192912Sartem *
5202912Sartem * Free a property set earlier obtained with libhal_device_get_all_properties().
5212912Sartem */
5222912Sartem void
libhal_free_property_set(LibHalPropertySet * set)5232912Sartem libhal_free_property_set (LibHalPropertySet * set)
5242912Sartem {
5252912Sartem LibHalProperty *p;
5262912Sartem LibHalProperty *q;
5272912Sartem
5282912Sartem if (set == NULL)
5292912Sartem return;
5302912Sartem
5312912Sartem for (p = set->properties_head; p != NULL; p = q) {
5322912Sartem free (p->key);
5332912Sartem if (p->type == DBUS_TYPE_STRING)
5342912Sartem free (p->v.str_value);
5352912Sartem if (p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
5362912Sartem libhal_free_string_array (p->v.strlist_value);
5372912Sartem q = p->next;
5382912Sartem free (p);
5392912Sartem }
5402912Sartem free (set);
5412912Sartem }
5422912Sartem
5432912Sartem /**
5442912Sartem * libhal_property_set_get_num_elems:
5452912Sartem * @set: property set to consider
5462912Sartem *
5472912Sartem * Get the number of properties in a property set.
5482912Sartem *
5492912Sartem * Returns: number of properties in given property set
5502912Sartem */
5512912Sartem unsigned int
libhal_property_set_get_num_elems(LibHalPropertySet * set)5522912Sartem libhal_property_set_get_num_elems (LibHalPropertySet *set)
5532912Sartem {
5542912Sartem unsigned int num_elems;
5552912Sartem LibHalProperty *p;
5562912Sartem
5572912Sartem if (set == NULL)
5582912Sartem return 0;
5592912Sartem
5602912Sartem num_elems = 0;
5612912Sartem for (p = set->properties_head; p != NULL; p = p->next)
5622912Sartem num_elems++;
5632912Sartem
5642912Sartem return num_elems;
5652912Sartem }
5662912Sartem
5676293Sartem static LibHalProperty *
property_set_lookup(const LibHalPropertySet * set,const char * key)5686293Sartem property_set_lookup (const LibHalPropertySet *set, const char *key)
5696293Sartem {
5706293Sartem LibHalProperty *p;
5716293Sartem
5726293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", NULL);
5736293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", NULL);
5746293Sartem
5756293Sartem for (p = set->properties_head; p != NULL; p = p->next)
5766293Sartem if (strcmp (key, p->key) == 0)
5776293Sartem return p;
5786293Sartem
5796293Sartem return NULL;
5806293Sartem }
5816293Sartem
5826293Sartem /**
5836293Sartem * libhal_ps_get_type:
5846293Sartem * @set: property set
5856293Sartem * @key: name of property to inspect
5866293Sartem *
5876293Sartem * Get the type of a given property.
5886293Sartem *
5896293Sartem * Returns: the #LibHalPropertyType of the given property,
5906293Sartem * LIBHAL_PROPERTY_TYPE_INVALID if property is not in the set
5916293Sartem */
5926293Sartem LibHalPropertyType
libhal_ps_get_type(const LibHalPropertySet * set,const char * key)5936293Sartem libhal_ps_get_type (const LibHalPropertySet *set, const char *key)
5946293Sartem {
5956293Sartem LibHalProperty *p = property_set_lookup (set, key);
5966293Sartem
5976293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", LIBHAL_PROPERTY_TYPE_INVALID);
5986293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", LIBHAL_PROPERTY_TYPE_INVALID);
5996293Sartem
6006293Sartem p = property_set_lookup (set, key);
6016293Sartem if (p) return p->type;
6026293Sartem else return LIBHAL_PROPERTY_TYPE_INVALID;
6036293Sartem }
6046293Sartem
6056293Sartem /**
6066293Sartem * libhal_ps_get_string:
6076293Sartem * @set: property set
6086293Sartem * @key: name of property to inspect
6096293Sartem *
6106293Sartem * Get the value of a property of type string.
6116293Sartem *
6126293Sartem * Returns: UTF8 nul-terminated string. This pointer is only valid
6136293Sartem * until libhal_free_property_set() is invoked on the property set
6146293Sartem * this property belongs to. NULL if property is not in the set or not a string
6156293Sartem */
6166293Sartem const char *
libhal_ps_get_string(const LibHalPropertySet * set,const char * key)6176293Sartem libhal_ps_get_string (const LibHalPropertySet *set, const char *key)
6186293Sartem {
6196293Sartem LibHalProperty *p;
6206293Sartem
6216293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", NULL);
6226293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", NULL);
6236293Sartem
6246293Sartem p = property_set_lookup (set, key);
6256293Sartem if (p && p->type == LIBHAL_PROPERTY_TYPE_STRING)
6266293Sartem return p->v.str_value;
6276293Sartem else return NULL;
6286293Sartem }
6296293Sartem
6306293Sartem /**
6316293Sartem * libhal_ps_get_int:
6326293Sartem * @set: property set
6336293Sartem * @key: name of property to inspect
6346293Sartem *
6356293Sartem * Get the value of a property of type signed integer.
6366293Sartem *
6376293Sartem * Returns: property value (32-bit signed integer)
6386293Sartem */
6396293Sartem dbus_int32_t
libhal_ps_get_int32(const LibHalPropertySet * set,const char * key)6406293Sartem libhal_ps_get_int32 (const LibHalPropertySet *set, const char *key)
6416293Sartem {
6426293Sartem LibHalProperty *p;
6436293Sartem
6446293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", 0);
6456293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", 0);
6466293Sartem
6476293Sartem p = property_set_lookup (set, key);
6486293Sartem if (p && p->type == LIBHAL_PROPERTY_TYPE_INT32)
6496293Sartem return p->v.int_value;
6506293Sartem else return 0;
6516293Sartem }
6526293Sartem
6536293Sartem /**
6546293Sartem * libhal_ps_get_uint64:
6556293Sartem * @set: property set
6566293Sartem * @key: name of property to inspect
6576293Sartem *
6586293Sartem * Get the value of a property of type unsigned integer.
6596293Sartem *
6606293Sartem * Returns: property value (64-bit unsigned integer)
6616293Sartem */
6626293Sartem dbus_uint64_t
libhal_ps_get_uint64(const LibHalPropertySet * set,const char * key)6636293Sartem libhal_ps_get_uint64 (const LibHalPropertySet *set, const char *key)
6646293Sartem {
6656293Sartem LibHalProperty *p;
6666293Sartem
6676293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", 0);
6686293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", 0);
6696293Sartem
6706293Sartem p = property_set_lookup (set, key);
6716293Sartem if (p && p->type == LIBHAL_PROPERTY_TYPE_UINT64)
6726293Sartem return p->v.uint64_value;
6736293Sartem else return 0;
6746293Sartem }
6756293Sartem
6766293Sartem /**
6776293Sartem * libhal_ps_get_double:
6786293Sartem * @set: property set
6796293Sartem * @key: name of property to inspect
6806293Sartem *
6816293Sartem * Get the value of a property of type double.
6826293Sartem *
6836293Sartem * Returns: property value (IEEE754 double precision float)
6846293Sartem */
6856293Sartem double
libhal_ps_get_double(const LibHalPropertySet * set,const char * key)6866293Sartem libhal_ps_get_double (const LibHalPropertySet *set, const char *key)
6876293Sartem {
6886293Sartem LibHalProperty *p;
6896293Sartem
6906293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", 0.0);
6916293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", 0.0);
6926293Sartem
6936293Sartem p = property_set_lookup (set, key);
6946293Sartem if (p && p->type == LIBHAL_PROPERTY_TYPE_DOUBLE)
6956293Sartem return p->v.double_value;
6966293Sartem else return 0.0;
6976293Sartem }
6986293Sartem
6996293Sartem /**
7006293Sartem * libhal_ps_get_bool:
7016293Sartem * @set: property set
7026293Sartem * @key: name of property to inspect
7036293Sartem *
7046293Sartem * Get the value of a property of type bool.
7056293Sartem *
7066293Sartem * Returns: property value (bool)
7076293Sartem */
7086293Sartem dbus_bool_t
libhal_ps_get_bool(const LibHalPropertySet * set,const char * key)7096293Sartem libhal_ps_get_bool (const LibHalPropertySet *set, const char *key)
7106293Sartem {
7116293Sartem LibHalProperty *p;
7126293Sartem
7136293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", FALSE);
7146293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", FALSE);
7156293Sartem
7166293Sartem p = property_set_lookup (set, key);
7176293Sartem if (p && p->type == LIBHAL_PROPERTY_TYPE_BOOLEAN)
7186293Sartem return p->v.bool_value;
7196293Sartem else return FALSE;
7206293Sartem }
7216293Sartem
7226293Sartem /**
7236293Sartem * libhal_ps_get_strlist:
7246293Sartem * @set: property set
7256293Sartem * @key: name of property to inspect
7266293Sartem *
7276293Sartem * Get the value of a property of type string list.
7286293Sartem *
7296293Sartem * Returns: pointer to array of strings, this is owned by the property set
7306293Sartem */
7316293Sartem const char *const *
libhal_ps_get_strlist(const LibHalPropertySet * set,const char * key)7326293Sartem libhal_ps_get_strlist (const LibHalPropertySet *set, const char *key)
7336293Sartem {
7346293Sartem LibHalProperty *p;
7356293Sartem
7366293Sartem LIBHAL_CHECK_PARAM_VALID(set, "*set", NULL);
7376293Sartem LIBHAL_CHECK_PARAM_VALID(key, "*key", NULL);
7386293Sartem
7396293Sartem p = property_set_lookup (set, key);
7406293Sartem if (p && p->type == LIBHAL_PROPERTY_TYPE_STRLIST)
7416293Sartem return (const char *const *) p->v.strlist_value;
7426293Sartem else return NULL;
7436293Sartem }
7446293Sartem
7452912Sartem
7462912Sartem /**
7472912Sartem * libhal_psi_init:
7482912Sartem * @iter: iterator object
7492912Sartem * @set: property set to iterate over
7502912Sartem *
7512912Sartem * Initialize a property set iterator.
7522912Sartem *
7532912Sartem */
7542912Sartem void
libhal_psi_init(LibHalPropertySetIterator * iter,LibHalPropertySet * set)7552912Sartem libhal_psi_init (LibHalPropertySetIterator * iter, LibHalPropertySet * set)
7562912Sartem {
7572912Sartem if (set == NULL)
7582912Sartem return;
7592912Sartem
7602912Sartem iter->set = set;
7612912Sartem iter->idx = 0;
7622912Sartem iter->cur_prop = set->properties_head;
7632912Sartem }
7642912Sartem
7652912Sartem
7662912Sartem /**
7672912Sartem * libhal_psi_has_more:
7682912Sartem * @iter: iterator object
7692912Sartem *
7702912Sartem * Determine whether there are more properties to iterate over.
7712912Sartem *
7722912Sartem * Returns: TRUE if there are more properties, FALSE otherwise.
7732912Sartem */
7742912Sartem dbus_bool_t
libhal_psi_has_more(LibHalPropertySetIterator * iter)7752912Sartem libhal_psi_has_more (LibHalPropertySetIterator * iter)
7762912Sartem {
7772912Sartem return iter->idx < iter->set->num_properties;
7782912Sartem }
7792912Sartem
7802912Sartem /**
7812912Sartem * libhal_psi_next:
7822912Sartem * @iter: iterator object
7832912Sartem *
7842912Sartem * Advance iterator to next property.
7852912Sartem */
7862912Sartem void
libhal_psi_next(LibHalPropertySetIterator * iter)7872912Sartem libhal_psi_next (LibHalPropertySetIterator * iter)
7882912Sartem {
7892912Sartem iter->idx++;
7902912Sartem iter->cur_prop = iter->cur_prop->next;
7912912Sartem }
7922912Sartem
7932912Sartem /**
7942912Sartem * libhal_psi_get_type:
7952912Sartem * @iter: iterator object
7962912Sartem *
7972912Sartem * Get type of property.
7982912Sartem *
7992912Sartem * Returns: the property type at the iterator's position
8002912Sartem */
8012912Sartem LibHalPropertyType
libhal_psi_get_type(LibHalPropertySetIterator * iter)8022912Sartem libhal_psi_get_type (LibHalPropertySetIterator * iter)
8032912Sartem {
8042912Sartem return iter->cur_prop->type;
8052912Sartem }
8062912Sartem
8072912Sartem /**
8082912Sartem * libhal_psi_get_key:
8092912Sartem * @iter: iterator object
8102912Sartem *
8112912Sartem * Get the key of a property.
8122912Sartem *
8132912Sartem * Returns: ASCII nul-terminated string. This pointer is only valid
8142912Sartem * until libhal_free_property_set() is invoked on the property set
8152912Sartem * this property belongs to.
8162912Sartem */
8172912Sartem char *
libhal_psi_get_key(LibHalPropertySetIterator * iter)8182912Sartem libhal_psi_get_key (LibHalPropertySetIterator * iter)
8192912Sartem {
8202912Sartem return iter->cur_prop->key;
8212912Sartem }
8222912Sartem
8232912Sartem /**
8242912Sartem * libhal_psi_get_string:
8252912Sartem * @iter: iterator object
8262912Sartem *
8272912Sartem * Get the value of a property of type string.
8282912Sartem *
8292912Sartem * Returns: UTF8 nul-terminated string. This pointer is only valid
8302912Sartem * until libhal_free_property_set() is invoked on the property set
8312912Sartem * this property belongs to.
8322912Sartem */
8332912Sartem char *
libhal_psi_get_string(LibHalPropertySetIterator * iter)8342912Sartem libhal_psi_get_string (LibHalPropertySetIterator * iter)
8352912Sartem {
8362912Sartem return iter->cur_prop->v.str_value;
8372912Sartem }
8382912Sartem
8392912Sartem /**
8402912Sartem * libhal_psi_get_int:
8412912Sartem * @iter: iterator object
8422912Sartem *
8432912Sartem * Get the value of a property of type signed integer.
8442912Sartem *
8452912Sartem * Returns: property value (32-bit signed integer)
8462912Sartem */
8472912Sartem dbus_int32_t
libhal_psi_get_int(LibHalPropertySetIterator * iter)8482912Sartem libhal_psi_get_int (LibHalPropertySetIterator * iter)
8492912Sartem {
8502912Sartem return iter->cur_prop->v.int_value;
8512912Sartem }
8522912Sartem
8532912Sartem /**
8542912Sartem * libhal_psi_get_uint64:
8552912Sartem * @iter: iterator object
8562912Sartem *
8572912Sartem * Get the value of a property of type unsigned integer.
8582912Sartem *
8592912Sartem * Returns: property value (64-bit unsigned integer)
8602912Sartem */
8612912Sartem dbus_uint64_t
libhal_psi_get_uint64(LibHalPropertySetIterator * iter)8622912Sartem libhal_psi_get_uint64 (LibHalPropertySetIterator * iter)
8632912Sartem {
8642912Sartem return iter->cur_prop->v.uint64_value;
8652912Sartem }
8662912Sartem
8672912Sartem /**
8682912Sartem * libhal_psi_get_double:
8692912Sartem * @iter: iterator object
8702912Sartem *
8712912Sartem * Get the value of a property of type double.
8722912Sartem *
8732912Sartem * Returns: property value (IEEE754 double precision float)
8742912Sartem */
8752912Sartem double
libhal_psi_get_double(LibHalPropertySetIterator * iter)8762912Sartem libhal_psi_get_double (LibHalPropertySetIterator * iter)
8772912Sartem {
8782912Sartem return iter->cur_prop->v.double_value;
8792912Sartem }
8802912Sartem
8812912Sartem /**
8822912Sartem * libhal_psi_get_bool:
8832912Sartem * @iter: iterator object
8842912Sartem *
8852912Sartem * Get the value of a property of type bool.
8862912Sartem *
8872912Sartem * Returns: property value (bool)
8882912Sartem */
8892912Sartem dbus_bool_t
libhal_psi_get_bool(LibHalPropertySetIterator * iter)8902912Sartem libhal_psi_get_bool (LibHalPropertySetIterator * iter)
8912912Sartem {
8922912Sartem return iter->cur_prop->v.bool_value;
8932912Sartem }
8942912Sartem
8952912Sartem /**
8962912Sartem * libhal_psi_get_strlist:
8972912Sartem * @iter: iterator object
8982912Sartem *
8992912Sartem * Get the value of a property of type string list.
9002912Sartem *
9012912Sartem * Returns: pointer to array of strings
9022912Sartem */
9032912Sartem char **
libhal_psi_get_strlist(LibHalPropertySetIterator * iter)9042912Sartem libhal_psi_get_strlist (LibHalPropertySetIterator * iter)
9052912Sartem {
9062912Sartem return iter->cur_prop->v.strlist_value;
9072912Sartem }
9082912Sartem
9092912Sartem
9102912Sartem static DBusHandlerResult
filter_func(DBusConnection * connection,DBusMessage * message,void * user_data)9112912Sartem filter_func (DBusConnection * connection,
9122912Sartem DBusMessage * message, void *user_data)
9132912Sartem {
9142912Sartem const char *object_path;
9152912Sartem DBusError error;
9162912Sartem LibHalContext *ctx = (LibHalContext *) user_data;
9172912Sartem
9182912Sartem if (ctx->is_shutdown)
9192912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
9202912Sartem
9212912Sartem dbus_error_init (&error);
9222912Sartem
9232912Sartem object_path = dbus_message_get_path (message);
9242912Sartem
9252912Sartem /*printf("*** in filter_func, object_path=%s\n", object_path);*/
9262912Sartem
9272912Sartem if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager",
9282912Sartem "DeviceAdded")) {
9292912Sartem char *udi;
9302912Sartem if (dbus_message_get_args (message, &error,
9312912Sartem DBUS_TYPE_STRING, &udi,
9322912Sartem DBUS_TYPE_INVALID)) {
9332912Sartem if (ctx->device_added != NULL) {
9342912Sartem ctx->device_added (ctx, udi);
9352912Sartem }
9362912Sartem } else {
9372912Sartem LIBHAL_FREE_DBUS_ERROR(&error);
9382912Sartem }
9392912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
9402912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
9412912Sartem char *udi;
9422912Sartem if (dbus_message_get_args (message, &error,
9432912Sartem DBUS_TYPE_STRING, &udi,
9442912Sartem DBUS_TYPE_INVALID)) {
9452912Sartem if (ctx->device_removed != NULL) {
9462912Sartem ctx->device_removed (ctx, udi);
9472912Sartem }
9482912Sartem } else {
9492912Sartem LIBHAL_FREE_DBUS_ERROR(&error);
9502912Sartem }
9512912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
9522912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Manager","NewCapability")) {
9532912Sartem char *udi;
9542912Sartem char *capability;
9552912Sartem if (dbus_message_get_args (message, &error,
9562912Sartem DBUS_TYPE_STRING, &udi,
9572912Sartem DBUS_TYPE_STRING, &capability,
9582912Sartem DBUS_TYPE_INVALID)) {
9592912Sartem if (ctx->device_new_capability != NULL) {
9602912Sartem ctx->device_new_capability (ctx, udi, capability);
9612912Sartem }
9622912Sartem } else {
9632912Sartem LIBHAL_FREE_DBUS_ERROR(&error);
9642912Sartem }
9652912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
9662912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "Condition")) {
9672912Sartem char *condition_name;
9682912Sartem char *condition_detail;
9692912Sartem if (dbus_message_get_args (message, &error,
9702912Sartem DBUS_TYPE_STRING, &condition_name,
9712912Sartem DBUS_TYPE_STRING, &condition_detail,
9722912Sartem DBUS_TYPE_INVALID)) {
9732912Sartem if (ctx->device_condition != NULL) {
9742912Sartem ctx->device_condition (ctx, object_path, condition_name, condition_detail);
9752912Sartem }
9762912Sartem } else {
9772912Sartem LIBHAL_FREE_DBUS_ERROR(&error);
9782912Sartem }
9792912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
9802912Sartem } else if (dbus_message_is_signal (message, "org.freedesktop.Hal.Device", "PropertyModified")) {
9812912Sartem if (ctx->device_property_modified != NULL) {
9822912Sartem int i;
9832912Sartem char *key;
9842912Sartem dbus_bool_t removed;
9852912Sartem dbus_bool_t added;
9862912Sartem int num_modifications;
9872912Sartem DBusMessageIter iter;
9882912Sartem DBusMessageIter iter_array;
9892912Sartem
9902912Sartem dbus_message_iter_init (message, &iter);
9912912Sartem dbus_message_iter_get_basic (&iter, &num_modifications);
9922912Sartem dbus_message_iter_next (&iter);
9932912Sartem
9942912Sartem dbus_message_iter_recurse (&iter, &iter_array);
9952912Sartem
9962912Sartem for (i = 0; i < num_modifications; i++) {
9972912Sartem DBusMessageIter iter_struct;
9982912Sartem
9992912Sartem dbus_message_iter_recurse (&iter_array, &iter_struct);
10002912Sartem
10012912Sartem dbus_message_iter_get_basic (&iter_struct, &key);
10022912Sartem dbus_message_iter_next (&iter_struct);
10032912Sartem dbus_message_iter_get_basic (&iter_struct, &removed);
10042912Sartem dbus_message_iter_next (&iter_struct);
10052912Sartem dbus_message_iter_get_basic (&iter_struct, &added);
10062912Sartem
10072912Sartem ctx->device_property_modified (ctx,
10082912Sartem object_path,
10092912Sartem key, removed,
10102912Sartem added);
10112912Sartem
10122912Sartem dbus_message_iter_next (&iter_array);
10132912Sartem }
10142912Sartem
10152912Sartem }
10162912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
10172912Sartem }
10182912Sartem
10192912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
10202912Sartem }
10212912Sartem
10222912Sartem /* for i18n purposes */
10232912Sartem static dbus_bool_t libhal_already_initialized_once = FALSE;
10242912Sartem
10252912Sartem
10262912Sartem /**
10272912Sartem * libhal_get_all_devices:
10282912Sartem * @ctx: the context for the connection to hald
10292912Sartem * @num_devices: the number of devices will be stored here
10302912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
10312912Sartem *
10322912Sartem * Get all devices in the Global Device List (GDL).
10332912Sartem *
10342912Sartem * Returns: An array of device identifiers terminated with NULL. It is
10352912Sartem * the responsibility of the caller to free with
10362912Sartem * libhal_free_string_array(). If an error occurs NULL is returned.
10372912Sartem */
10382912Sartem char **
libhal_get_all_devices(LibHalContext * ctx,int * num_devices,DBusError * error)10392912Sartem libhal_get_all_devices (LibHalContext *ctx, int *num_devices, DBusError *error)
10402912Sartem {
10412912Sartem DBusMessage *message;
10422912Sartem DBusMessage *reply;
10432912Sartem DBusMessageIter iter_array, reply_iter;
10442912Sartem char **hal_device_names;
10452912Sartem DBusError _error;
10462912Sartem
10472912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
10482912Sartem
10492912Sartem *num_devices = 0;
10502912Sartem
10512912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
10522912Sartem "/org/freedesktop/Hal/Manager",
10532912Sartem "org.freedesktop.Hal.Manager",
10542912Sartem "GetAllDevices");
10552912Sartem if (message == NULL) {
10562912Sartem fprintf (stderr, "%s %d : Could not allocate D-BUS message\n", __FILE__, __LINE__);
10572912Sartem return NULL;
10582912Sartem }
10592912Sartem
10602912Sartem dbus_error_init (&_error);
10612912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection, message, -1, &_error);
10622912Sartem
10632912Sartem dbus_move_error (&_error, error);
10642912Sartem if (error != NULL && dbus_error_is_set (error)) {
10652912Sartem dbus_message_unref (message);
10662912Sartem return NULL;
10672912Sartem }
10682912Sartem if (reply == NULL) {
10692912Sartem dbus_message_unref (message);
10702912Sartem return NULL;
10712912Sartem }
10722912Sartem
10732912Sartem /* now analyze reply */
10742912Sartem dbus_message_iter_init (reply, &reply_iter);
10752912Sartem
10762912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
10772912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
10782912Sartem return NULL;
10792912Sartem }
10802912Sartem
10812912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array);
10822912Sartem
10832912Sartem hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
10842912Sartem
10852912Sartem dbus_message_unref (reply);
10862912Sartem dbus_message_unref (message);
10872912Sartem
10882912Sartem return hal_device_names;
10892912Sartem }
10902912Sartem
10912912Sartem /**
10922912Sartem * libhal_device_get_property_type:
10932912Sartem * @ctx: the context for the connection to hald
10942912Sartem * @udi: the Unique Device Id
10952912Sartem * @key: name of the property
10962912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
10972912Sartem *
10982912Sartem * Query a property type of a device.
10992912Sartem *
11002912Sartem * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is
11012912Sartem * return if the property doesn't exist.
11022912Sartem */
11032912Sartem LibHalPropertyType
libhal_device_get_property_type(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)11042912Sartem libhal_device_get_property_type (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
11052912Sartem {
11062912Sartem DBusMessage *message;
11072912Sartem DBusMessage *reply;
11082912Sartem DBusMessageIter iter, reply_iter;
11092912Sartem int type;
11102912Sartem DBusError _error;
11112912Sartem
11122912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, LIBHAL_PROPERTY_TYPE_INVALID); /* or return NULL? */
11132912Sartem
11142912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
11152912Sartem "org.freedesktop.Hal.Device",
11162912Sartem "GetPropertyType");
11172912Sartem if (message == NULL) {
11182912Sartem fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
11192912Sartem return LIBHAL_PROPERTY_TYPE_INVALID;
11202912Sartem }
11212912Sartem
11222912Sartem dbus_message_iter_init_append (message, &iter);
11232912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
11242912Sartem
11252912Sartem dbus_error_init (&_error);
11262912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
11272912Sartem message, -1,
11282912Sartem &_error);
11292912Sartem
11302912Sartem dbus_move_error (&_error, error);
11312912Sartem if (error != NULL && dbus_error_is_set (error)) {
11322912Sartem dbus_message_unref (message);
11332912Sartem return LIBHAL_PROPERTY_TYPE_INVALID;
11342912Sartem }
11352912Sartem if (reply == NULL) {
11362912Sartem dbus_message_unref (message);
11372912Sartem return LIBHAL_PROPERTY_TYPE_INVALID;
11382912Sartem }
11392912Sartem
11402912Sartem dbus_message_iter_init (reply, &reply_iter);
11412912Sartem dbus_message_iter_get_basic (&reply_iter, &type);
11422912Sartem
11432912Sartem dbus_message_unref (message);
11442912Sartem dbus_message_unref (reply);
11452912Sartem
11462912Sartem return type;
11472912Sartem }
11482912Sartem
11492912Sartem /**
11502912Sartem * libhal_device_get_property_strlist:
11512912Sartem * @ctx: the context for the connection to hald
11522912Sartem * @udi: unique Device Id
11532912Sartem * @key: name of the property
11542912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
11552912Sartem *
11562912Sartem * Get the value of a property of type string list.
11572912Sartem *
11582912Sartem * Returns: Array of pointers to UTF8 nul-terminated strings
11592912Sartem * terminated by NULL. The caller is responsible for freeing this
11602912Sartem * string array with the function libhal_free_string_array(). Returns
11612912Sartem * NULL if the property didn't exist or we are OOM
11622912Sartem */
11632912Sartem char **
libhal_device_get_property_strlist(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)11642912Sartem libhal_device_get_property_strlist (LibHalContext *ctx, const char *udi, const char *key, DBusError *error)
11652912Sartem {
11662912Sartem DBusMessage *message;
11672912Sartem DBusMessage *reply;
11682912Sartem DBusMessageIter iter, iter_array, reply_iter;
11692912Sartem char **our_strings;
11702912Sartem DBusError _error;
11712912Sartem
11722912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
11732912Sartem
11742912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
11752912Sartem "org.freedesktop.Hal.Device",
11762912Sartem "GetPropertyStringList");
11772912Sartem if (message == NULL) {
11782912Sartem fprintf (stderr,
11792912Sartem "%s %d : Couldn't allocate D-BUS message\n",
11802912Sartem __FILE__, __LINE__);
11812912Sartem return NULL;
11822912Sartem }
11832912Sartem
11842912Sartem dbus_message_iter_init_append (message, &iter);
11852912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
11862912Sartem
11872912Sartem dbus_error_init (&_error);
11882912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
11892912Sartem message, -1,
11902912Sartem &_error);
11912912Sartem
11922912Sartem dbus_move_error (&_error, error);
11932912Sartem if (error != NULL && dbus_error_is_set (error)) {
11942912Sartem dbus_message_unref (message);
11952912Sartem return NULL;
11962912Sartem }
11972912Sartem if (reply == NULL) {
11982912Sartem dbus_message_unref (message);
11992912Sartem return NULL;
12002912Sartem }
12012912Sartem /* now analyse reply */
12022912Sartem dbus_message_iter_init (reply, &reply_iter);
12032912Sartem
12042912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
12052912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
12062912Sartem return NULL;
12072912Sartem }
12082912Sartem
12092912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array);
12102912Sartem
12112912Sartem our_strings = libhal_get_string_array_from_iter (&iter_array, NULL);
12122912Sartem
12132912Sartem dbus_message_unref (reply);
12142912Sartem dbus_message_unref (message);
12152912Sartem
12162912Sartem return our_strings;
12172912Sartem }
12182912Sartem
12192912Sartem /**
12202912Sartem * libhal_device_get_property_string:
12212912Sartem * @ctx: the context for the connection to hald
12222912Sartem * @udi: the Unique Device Id
12232912Sartem * @key: the name of the property
12242912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
12252912Sartem *
12262912Sartem * Get the value of a property of type string.
12272912Sartem *
12282912Sartem * Returns: UTF8 nul-terminated string. The caller is responsible for
12292912Sartem * freeing this string with the function libhal_free_string(). Returns
12302912Sartem * NULL if the property didn't exist or we are OOM.
12312912Sartem */
12322912Sartem char *
libhal_device_get_property_string(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)12332912Sartem libhal_device_get_property_string (LibHalContext *ctx,
12342912Sartem const char *udi, const char *key, DBusError *error)
12352912Sartem {
12362912Sartem DBusMessage *message;
12372912Sartem DBusMessage *reply;
12382912Sartem DBusMessageIter iter, reply_iter;
12392912Sartem char *value;
12402912Sartem char *dbus_str;
12412912Sartem DBusError _error;
12422912Sartem
12432912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
12442912Sartem
12452912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
12462912Sartem "org.freedesktop.Hal.Device",
12472912Sartem "GetPropertyString");
12482912Sartem
12492912Sartem if (message == NULL) {
12502912Sartem fprintf (stderr,
12512912Sartem "%s %d : Couldn't allocate D-BUS message\n",
12522912Sartem __FILE__, __LINE__);
12532912Sartem return NULL;
12542912Sartem }
12552912Sartem
12562912Sartem dbus_message_iter_init_append (message, &iter);
12572912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
12582912Sartem
12592912Sartem dbus_error_init (&_error);
12602912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
12612912Sartem message, -1,
12622912Sartem &_error);
12632912Sartem
12642912Sartem dbus_move_error (&_error, error);
12652912Sartem if (error != NULL && dbus_error_is_set (error)) {
12662912Sartem dbus_message_unref (message);
12672912Sartem return NULL;
12682912Sartem }
12692912Sartem if (reply == NULL) {
12702912Sartem dbus_message_unref (message);
12712912Sartem return NULL;
12722912Sartem }
12732912Sartem
12742912Sartem dbus_message_iter_init (reply, &reply_iter);
12752912Sartem
12762912Sartem /* now analyze reply */
12772912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
12782912Sartem DBUS_TYPE_STRING) {
12792912Sartem dbus_message_unref (message);
12802912Sartem dbus_message_unref (reply);
12812912Sartem return NULL;
12822912Sartem }
12832912Sartem
12842912Sartem dbus_message_iter_get_basic (&reply_iter, &dbus_str);
12852912Sartem value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
12862912Sartem if (value == NULL) {
12872912Sartem fprintf (stderr, "%s %d : error allocating memory\n",
12882912Sartem __FILE__, __LINE__);
12892912Sartem /** @todo FIXME cleanup */
12902912Sartem return NULL;
12912912Sartem }
12922912Sartem
12932912Sartem dbus_message_unref (message);
12942912Sartem dbus_message_unref (reply);
12952912Sartem return value;
12962912Sartem }
12972912Sartem
12982912Sartem /**
12992912Sartem * libhal_device_get_property_int:
13002912Sartem * @ctx: the context for the connection to hald
13012912Sartem * @udi: the Unique Device Id
13022912Sartem * @key: name of the property
13032912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
13042912Sartem *
13052912Sartem * Get the value of a property of type integer.
13062912Sartem *
13072912Sartem * Returns: Property value (32-bit signed integer)
13082912Sartem */
13092912Sartem dbus_int32_t
libhal_device_get_property_int(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)13102912Sartem libhal_device_get_property_int (LibHalContext *ctx,
13112912Sartem const char *udi, const char *key, DBusError *error)
13122912Sartem {
13132912Sartem DBusMessage *message;
13142912Sartem DBusMessage *reply;
13152912Sartem DBusMessageIter iter, reply_iter;
13162912Sartem dbus_int32_t value;
13172912Sartem DBusError _error;
13182912Sartem
13192912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
13202912Sartem
13212912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
13222912Sartem "org.freedesktop.Hal.Device",
13232912Sartem "GetPropertyInteger");
13242912Sartem if (message == NULL) {
13252912Sartem fprintf (stderr,
13262912Sartem "%s %d : Couldn't allocate D-BUS message\n",
13272912Sartem __FILE__, __LINE__);
13282912Sartem return -1;
13292912Sartem }
13302912Sartem
13312912Sartem dbus_message_iter_init_append (message, &iter);
13322912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
13332912Sartem
13342912Sartem dbus_error_init (&_error);
13352912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
13362912Sartem message, -1,
13372912Sartem &_error);
13382912Sartem
13392912Sartem dbus_move_error (&_error, error);
13402912Sartem if (error != NULL && dbus_error_is_set (error)) {
13412912Sartem dbus_message_unref (message);
13422912Sartem return -1;
13432912Sartem }
13442912Sartem if (reply == NULL) {
13452912Sartem dbus_message_unref (message);
13462912Sartem return -1;
13472912Sartem }
13482912Sartem
13492912Sartem dbus_message_iter_init (reply, &reply_iter);
13502912Sartem
13512912Sartem /* now analyze reply */
13522912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
13532912Sartem DBUS_TYPE_INT32) {
13542912Sartem fprintf (stderr,
13552912Sartem "%s %d : property '%s' for device '%s' is not "
13562912Sartem "of type integer\n", __FILE__, __LINE__, key,
13572912Sartem udi);
13582912Sartem dbus_message_unref (message);
13592912Sartem dbus_message_unref (reply);
13602912Sartem return -1;
13612912Sartem }
13622912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
13632912Sartem
13642912Sartem dbus_message_unref (message);
13652912Sartem dbus_message_unref (reply);
13662912Sartem return value;
13672912Sartem }
13682912Sartem
13692912Sartem /**
13702912Sartem * libhal_device_get_property_uint64:
13712912Sartem * @ctx: the context for the connection to hald
13722912Sartem * @udi: the Unique Device Id
13732912Sartem * @key: name of the property
13742912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
13752912Sartem *
13762912Sartem * Get the value of a property of type signed integer.
13772912Sartem *
13782912Sartem * Returns: Property value (64-bit unsigned integer)
13792912Sartem */
13802912Sartem dbus_uint64_t
libhal_device_get_property_uint64(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)13812912Sartem libhal_device_get_property_uint64 (LibHalContext *ctx,
13822912Sartem const char *udi, const char *key, DBusError *error)
13832912Sartem {
13842912Sartem DBusMessage *message;
13852912Sartem DBusMessage *reply;
13862912Sartem DBusMessageIter iter, reply_iter;
13872912Sartem dbus_uint64_t value;
13882912Sartem DBusError _error;
13892912Sartem
13902912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1);
13912912Sartem
13922912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
13932912Sartem "org.freedesktop.Hal.Device",
13942912Sartem "GetPropertyInteger");
13952912Sartem if (message == NULL) {
13962912Sartem fprintf (stderr,
13972912Sartem "%s %d : Couldn't allocate D-BUS message\n",
13982912Sartem __FILE__, __LINE__);
13992912Sartem return -1;
14002912Sartem }
14012912Sartem
14022912Sartem dbus_message_iter_init_append (message, &iter);
14032912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
14042912Sartem
14052912Sartem dbus_error_init (&_error);
14062912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
14072912Sartem message, -1,
14082912Sartem &_error);
14092912Sartem
14102912Sartem dbus_move_error (&_error, error);
14112912Sartem if (error != NULL && dbus_error_is_set (error)) {
14122912Sartem dbus_message_unref (message);
14132912Sartem return -1;
14142912Sartem }
14152912Sartem if (reply == NULL) {
14162912Sartem dbus_message_unref (message);
14172912Sartem return -1;
14182912Sartem }
14192912Sartem
14202912Sartem dbus_message_iter_init (reply, &reply_iter);
14212912Sartem /* now analyze reply */
14222912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
14232912Sartem DBUS_TYPE_UINT64) {
14242912Sartem fprintf (stderr,
14252912Sartem "%s %d : property '%s' for device '%s' is not "
14262912Sartem "of type integer\n", __FILE__, __LINE__, key,
14272912Sartem udi);
14282912Sartem dbus_message_unref (message);
14292912Sartem dbus_message_unref (reply);
14302912Sartem return -1;
14312912Sartem }
14322912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
14332912Sartem
14342912Sartem dbus_message_unref (message);
14352912Sartem dbus_message_unref (reply);
14362912Sartem return value;
14372912Sartem }
14382912Sartem
14392912Sartem /**
14402912Sartem * libhal_device_get_property_double:
14412912Sartem * @ctx: the context for the connection to hald
14422912Sartem * @udi: the Unique Device Id
14432912Sartem * @key: name of the property
14442912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
14452912Sartem *
14462912Sartem * Get the value of a property of type double.
14472912Sartem *
14482912Sartem * Returns: Property value (IEEE754 double precision float)
14492912Sartem */
14502912Sartem double
libhal_device_get_property_double(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)14512912Sartem libhal_device_get_property_double (LibHalContext *ctx,
14522912Sartem const char *udi, const char *key, DBusError *error)
14532912Sartem {
14542912Sartem DBusMessage *message;
14552912Sartem DBusMessage *reply;
14562912Sartem DBusMessageIter iter, reply_iter;
14572912Sartem double value;
14582912Sartem DBusError _error;
14592912Sartem
14602912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, -1.0);
14612912Sartem
14622912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
14632912Sartem "org.freedesktop.Hal.Device",
14642912Sartem "GetPropertyDouble");
14652912Sartem if (message == NULL) {
14662912Sartem fprintf (stderr,
14672912Sartem "%s %d : Couldn't allocate D-BUS message\n",
14682912Sartem __FILE__, __LINE__);
14692912Sartem return -1.0f;
14702912Sartem }
14712912Sartem
14722912Sartem dbus_message_iter_init_append (message, &iter);
14732912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
14742912Sartem
14752912Sartem dbus_error_init (&_error);
14762912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
14772912Sartem message, -1,
14782912Sartem &_error);
14792912Sartem
14802912Sartem dbus_move_error (&_error, error);
14812912Sartem if (error != NULL && dbus_error_is_set (error)) {
14822912Sartem dbus_message_unref (message);
14832912Sartem return -1.0f;
14842912Sartem }
14852912Sartem if (reply == NULL) {
14862912Sartem dbus_message_unref (message);
14872912Sartem return -1.0f;
14882912Sartem }
14892912Sartem
14902912Sartem dbus_message_iter_init (reply, &reply_iter);
14912912Sartem
14922912Sartem /* now analyze reply */
14932912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
14942912Sartem DBUS_TYPE_DOUBLE) {
14952912Sartem fprintf (stderr,
14962912Sartem "%s %d : property '%s' for device '%s' is not "
14972912Sartem "of type double\n", __FILE__, __LINE__, key, udi);
14982912Sartem dbus_message_unref (message);
14992912Sartem dbus_message_unref (reply);
15002912Sartem return -1.0f;
15012912Sartem }
15022912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
15032912Sartem
15042912Sartem dbus_message_unref (message);
15052912Sartem dbus_message_unref (reply);
15062912Sartem return (double) value;
15072912Sartem }
15082912Sartem
15092912Sartem /**
15102912Sartem * libhal_device_get_property_bool:
15112912Sartem * @ctx: the context for the connection to hald
15122912Sartem * @udi: the Unique Device Id
15132912Sartem * @key: name of the property
15142912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
15152912Sartem *
15162912Sartem * Get the value of a property of type bool.
15172912Sartem *
15182912Sartem * Returns: Property value (boolean)
15192912Sartem */
15202912Sartem dbus_bool_t
libhal_device_get_property_bool(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)15212912Sartem libhal_device_get_property_bool (LibHalContext *ctx,
15222912Sartem const char *udi, const char *key, DBusError *error)
15232912Sartem {
15242912Sartem DBusMessage *message;
15252912Sartem DBusMessage *reply;
15262912Sartem DBusMessageIter iter, reply_iter;
15272912Sartem dbus_bool_t value;
15282912Sartem DBusError _error;
15292912Sartem
15302912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
15312912Sartem
15322912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
15332912Sartem "org.freedesktop.Hal.Device",
15342912Sartem "GetPropertyBoolean");
15352912Sartem if (message == NULL) {
15362912Sartem fprintf (stderr,
15372912Sartem "%s %d : Couldn't allocate D-BUS message\n",
15382912Sartem __FILE__, __LINE__);
15392912Sartem return FALSE;
15402912Sartem }
15412912Sartem
15422912Sartem dbus_message_iter_init_append (message, &iter);
15432912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
15442912Sartem
15452912Sartem dbus_error_init (&_error);
15462912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
15472912Sartem message, -1,
15482912Sartem &_error);
15492912Sartem
15502912Sartem dbus_move_error (&_error, error);
15512912Sartem if (error != NULL && dbus_error_is_set (error)) {
15522912Sartem dbus_message_unref (message);
15532912Sartem return FALSE;
15542912Sartem }
15552912Sartem if (reply == NULL) {
15562912Sartem dbus_message_unref (message);
15572912Sartem return FALSE;
15582912Sartem }
15592912Sartem
15602912Sartem dbus_message_iter_init (reply, &reply_iter);
15612912Sartem
15622912Sartem /* now analyze reply */
15632912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
15642912Sartem DBUS_TYPE_BOOLEAN) {
15652912Sartem fprintf (stderr,
15662912Sartem "%s %d : property '%s' for device '%s' is not "
15672912Sartem "of type bool\n", __FILE__, __LINE__, key, udi);
15682912Sartem dbus_message_unref (message);
15692912Sartem dbus_message_unref (reply);
15702912Sartem return FALSE;
15712912Sartem }
15722912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
15732912Sartem
15742912Sartem dbus_message_unref (message);
15752912Sartem dbus_message_unref (reply);
15762912Sartem return value;
15772912Sartem }
15782912Sartem
15792912Sartem
15802912Sartem /* generic helper */
15812912Sartem static dbus_bool_t
libhal_device_set_property_helper(LibHalContext * ctx,const char * udi,const char * key,int type,const char * str_value,dbus_int32_t int_value,dbus_uint64_t uint64_value,double double_value,dbus_bool_t bool_value,DBusError * error)15822912Sartem libhal_device_set_property_helper (LibHalContext *ctx,
15832912Sartem const char *udi,
15842912Sartem const char *key,
15852912Sartem int type,
15862912Sartem const char *str_value,
15872912Sartem dbus_int32_t int_value,
15882912Sartem dbus_uint64_t uint64_value,
15892912Sartem double double_value,
15902912Sartem dbus_bool_t bool_value,
15912912Sartem DBusError *error)
15922912Sartem {
15932912Sartem DBusMessage *message;
15942912Sartem DBusMessage *reply;
15952912Sartem DBusMessageIter iter;
15962912Sartem char *method_name = NULL;
15972912Sartem
15982912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
15992912Sartem
16002912Sartem /** @todo sanity check incoming params */
16012912Sartem switch (type) {
16022912Sartem case DBUS_TYPE_INVALID:
16032912Sartem method_name = "RemoveProperty";
16042912Sartem break;
16052912Sartem case DBUS_TYPE_STRING:
16062912Sartem method_name = "SetPropertyString";
16072912Sartem break;
16082912Sartem case DBUS_TYPE_INT32:
16092912Sartem case DBUS_TYPE_UINT64:
16102912Sartem method_name = "SetPropertyInteger";
16112912Sartem break;
16122912Sartem case DBUS_TYPE_DOUBLE:
16132912Sartem method_name = "SetPropertyDouble";
16142912Sartem break;
16152912Sartem case DBUS_TYPE_BOOLEAN:
16162912Sartem method_name = "SetPropertyBoolean";
16172912Sartem break;
16182912Sartem
16192912Sartem default:
16202912Sartem /* cannot happen; is not callable from outside this file */
16212912Sartem break;
16222912Sartem }
16232912Sartem
16242912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
16252912Sartem "org.freedesktop.Hal.Device",
16262912Sartem method_name);
16272912Sartem if (message == NULL) {
16282912Sartem fprintf (stderr,
16292912Sartem "%s %d : Couldn't allocate D-BUS message\n",
16302912Sartem __FILE__, __LINE__);
16312912Sartem return FALSE;
16322912Sartem }
16332912Sartem
16342912Sartem dbus_message_iter_init_append (message, &iter);
16352912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
16362912Sartem switch (type) {
16372912Sartem case DBUS_TYPE_STRING:
16382912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str_value);
16392912Sartem break;
16402912Sartem case DBUS_TYPE_INT32:
16412912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &int_value);
16422912Sartem break;
16432912Sartem case DBUS_TYPE_UINT64:
16442912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &uint64_value);
16452912Sartem break;
16462912Sartem case DBUS_TYPE_DOUBLE:
16472912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &double_value);
16482912Sartem break;
16492912Sartem case DBUS_TYPE_BOOLEAN:
16502912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bool_value);
16512912Sartem break;
16522912Sartem }
16532912Sartem
16542912Sartem
16552912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
16562912Sartem message, -1,
16572912Sartem error);
1658*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
16592912Sartem dbus_message_unref (message);
16602912Sartem return FALSE;
16612912Sartem }
16622912Sartem
16632912Sartem if (reply == NULL) {
16642912Sartem dbus_message_unref (message);
16652912Sartem return FALSE;
16662912Sartem }
16672912Sartem
16682912Sartem dbus_message_unref (message);
16692912Sartem dbus_message_unref (reply);
16702912Sartem
16712912Sartem return TRUE;
16722912Sartem }
16732912Sartem
16742912Sartem /**
16752912Sartem * libhal_device_set_property_string:
16762912Sartem * @ctx: the context for the connection to hald
16772912Sartem * @udi: the Unique Device Id
16782912Sartem * @key: name of the property
16792912Sartem * @value: value of the property; a UTF8 string
16802912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
16812912Sartem *
16822912Sartem * Set a property of type string.
16832912Sartem *
16842912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't
16852912Sartem * exist or the property had a different type.
16862912Sartem */
16872912Sartem dbus_bool_t
libhal_device_set_property_string(LibHalContext * ctx,const char * udi,const char * key,const char * value,DBusError * error)16882912Sartem libhal_device_set_property_string (LibHalContext *ctx,
16892912Sartem const char *udi,
16902912Sartem const char *key,
16912912Sartem const char *value,
16922912Sartem DBusError *error)
16932912Sartem {
16942912Sartem return libhal_device_set_property_helper (ctx, udi, key,
16952912Sartem DBUS_TYPE_STRING,
16962912Sartem value, 0, 0, 0.0f, FALSE, error);
16972912Sartem }
16982912Sartem
16992912Sartem /**
17002912Sartem * libhal_device_set_property_int:
17012912Sartem * @ctx: the context for the connection to hald
17022912Sartem * @udi: the Unique Device Id
17032912Sartem * @key: name of the property
17042912Sartem * @value: value of the property
17052912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
17062912Sartem *
17072912Sartem * Set a property of type signed integer.
17082912Sartem *
17092912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't
17102912Sartem * exist or the property had a different type.
17112912Sartem */
17122912Sartem dbus_bool_t
libhal_device_set_property_int(LibHalContext * ctx,const char * udi,const char * key,dbus_int32_t value,DBusError * error)17132912Sartem libhal_device_set_property_int (LibHalContext *ctx, const char *udi,
17142912Sartem const char *key, dbus_int32_t value, DBusError *error)
17152912Sartem {
17162912Sartem return libhal_device_set_property_helper (ctx, udi, key,
17172912Sartem DBUS_TYPE_INT32,
17182912Sartem NULL, value, 0, 0.0f, FALSE, error);
17192912Sartem }
17202912Sartem
17212912Sartem /**
17222912Sartem * libhal_device_set_property_uint64:
17232912Sartem * @ctx: the context for the connection to hald
17242912Sartem * @udi: the Unique Device Id
17252912Sartem * @key: name of the property
17262912Sartem * @value: value of the property
17272912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
17282912Sartem *
17292912Sartem * Set a property of type unsigned integer.
17302912Sartem *
17312912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't
17322912Sartem * exist or the property had a different type.
17332912Sartem */
17342912Sartem dbus_bool_t
libhal_device_set_property_uint64(LibHalContext * ctx,const char * udi,const char * key,dbus_uint64_t value,DBusError * error)17352912Sartem libhal_device_set_property_uint64 (LibHalContext *ctx, const char *udi,
17362912Sartem const char *key, dbus_uint64_t value, DBusError *error)
17372912Sartem {
17382912Sartem return libhal_device_set_property_helper (ctx, udi, key,
17392912Sartem DBUS_TYPE_UINT64,
17402912Sartem NULL, 0, value, 0.0f, FALSE, error);
17412912Sartem }
17422912Sartem
17432912Sartem /**
17442912Sartem * libhal_device_set_property_double:
17452912Sartem * @ctx: the context for the connection to hald
17462912Sartem * @udi: the Unique Device Id
17472912Sartem * @key: name of the property
17482912Sartem * @value: value of the property
17492912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
17502912Sartem *
17512912Sartem * Set a property of type double.
17522912Sartem *
17532912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't
17542912Sartem * exist or the property had a different type.
17552912Sartem */
17562912Sartem dbus_bool_t
libhal_device_set_property_double(LibHalContext * ctx,const char * udi,const char * key,double value,DBusError * error)17572912Sartem libhal_device_set_property_double (LibHalContext *ctx, const char *udi,
17582912Sartem const char *key, double value, DBusError *error)
17592912Sartem {
17602912Sartem return libhal_device_set_property_helper (ctx, udi, key,
17612912Sartem DBUS_TYPE_DOUBLE,
17622912Sartem NULL, 0, 0, value, FALSE, error);
17632912Sartem }
17642912Sartem
17652912Sartem /**
17662912Sartem * libhal_device_set_property_bool:
17672912Sartem * @ctx: the context for the connection to hald
17682912Sartem * @udi: the Unique Device Id
17692912Sartem * @key: name of the property
17702912Sartem * @value: value of the property
17712912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
17722912Sartem *
17732912Sartem * Set a property of type bool.
17742912Sartem *
17752912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't
17762912Sartem * exist or the property had a different type.
17772912Sartem */
17782912Sartem dbus_bool_t
libhal_device_set_property_bool(LibHalContext * ctx,const char * udi,const char * key,dbus_bool_t value,DBusError * error)17792912Sartem libhal_device_set_property_bool (LibHalContext *ctx, const char *udi,
17802912Sartem const char *key, dbus_bool_t value, DBusError *error)
17812912Sartem {
17822912Sartem return libhal_device_set_property_helper (ctx, udi, key,
17832912Sartem DBUS_TYPE_BOOLEAN,
17842912Sartem NULL, 0, 0, 0.0f, value, error);
17852912Sartem }
17862912Sartem
17872912Sartem
17882912Sartem /**
17892912Sartem * libhal_device_remove_property:
17902912Sartem * @ctx: the context for the connection to hald
17912912Sartem * @udi: the Unique Device Id
17922912Sartem * @key: name of the property
17932912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
17942912Sartem *
17952912Sartem * Remove a property.
17962912Sartem *
17972912Sartem * Returns: TRUE if the property was set, FALSE if the device didn't
17982912Sartem * exist
17992912Sartem */
18002912Sartem dbus_bool_t
libhal_device_remove_property(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)18012912Sartem libhal_device_remove_property (LibHalContext *ctx,
18022912Sartem const char *udi, const char *key, DBusError *error)
18032912Sartem {
18042912Sartem return libhal_device_set_property_helper (ctx, udi, key, DBUS_TYPE_INVALID,
18052912Sartem /* DBUS_TYPE_INVALID means remove */
18062912Sartem NULL, 0, 0, 0.0f, FALSE, error);
18072912Sartem }
18082912Sartem
18092912Sartem /**
18102912Sartem * libhal_device_property_strlist_append:
18112912Sartem * @ctx: the context for the connection to hald
18122912Sartem * @udi: the Unique Device Id
18132912Sartem * @key: name of the property
18142912Sartem * @value: value to append to property
18152912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
18162912Sartem *
18172912Sartem * Append to a property of type strlist.
18182912Sartem *
18192912Sartem * Returns: TRUE if the value was appended, FALSE if the device didn't
18202912Sartem * exist or the property had a different type.
18212912Sartem */
18222912Sartem dbus_bool_t
libhal_device_property_strlist_append(LibHalContext * ctx,const char * udi,const char * key,const char * value,DBusError * error)18232912Sartem libhal_device_property_strlist_append (LibHalContext *ctx,
18242912Sartem const char *udi,
18252912Sartem const char *key,
18262912Sartem const char *value,
18272912Sartem DBusError *error)
18282912Sartem {
18292912Sartem DBusMessage *message;
18302912Sartem DBusMessage *reply;
18312912Sartem DBusMessageIter iter;
18322912Sartem
18332912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
18342912Sartem
18352912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
18362912Sartem "org.freedesktop.Hal.Device",
18372912Sartem "StringListAppend");
18382912Sartem if (message == NULL) {
18392912Sartem fprintf (stderr,
18402912Sartem "%s %d : Couldn't allocate D-BUS message\n",
18412912Sartem __FILE__, __LINE__);
18422912Sartem return FALSE;
18432912Sartem }
18442912Sartem dbus_message_iter_init_append (message, &iter);
18452912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
18462912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
18472912Sartem
18482912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
18492912Sartem message, -1,
18502912Sartem error);
1851*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
18522912Sartem dbus_message_unref (message);
18532912Sartem return FALSE;
18542912Sartem }
18552912Sartem if (reply == NULL) {
18562912Sartem dbus_message_unref (message);
18572912Sartem return FALSE;
18582912Sartem }
18592912Sartem return TRUE;
18602912Sartem }
18612912Sartem
18622912Sartem /**
18632912Sartem * libhal_device_property_strlist_prepend:
18642912Sartem * @ctx: the context for the connection to hald
18652912Sartem * @udi: the Unique Device Id
18662912Sartem * @key: name of the property
18672912Sartem * @value: value to prepend to property
18682912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
18692912Sartem *
18702912Sartem * Prepend to a property of type strlist.
18712912Sartem *
18722912Sartem * Returns: TRUE if the value was prepended, FALSE if the device
18732912Sartem * didn't exist or the property had a different type.
18742912Sartem */
18752912Sartem dbus_bool_t
libhal_device_property_strlist_prepend(LibHalContext * ctx,const char * udi,const char * key,const char * value,DBusError * error)18762912Sartem libhal_device_property_strlist_prepend (LibHalContext *ctx,
18772912Sartem const char *udi,
18782912Sartem const char *key,
18792912Sartem const char *value,
18802912Sartem DBusError *error)
18812912Sartem {
18822912Sartem DBusMessage *message;
18832912Sartem DBusMessage *reply;
18842912Sartem DBusMessageIter iter;
18852912Sartem
18862912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
18872912Sartem
18882912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
18892912Sartem "org.freedesktop.Hal.Device",
18902912Sartem "StringListPrepend");
18912912Sartem if (message == NULL) {
18922912Sartem fprintf (stderr,
18932912Sartem "%s %d : Couldn't allocate D-BUS message\n",
18942912Sartem __FILE__, __LINE__);
18952912Sartem return FALSE;
18962912Sartem }
18972912Sartem dbus_message_iter_init_append (message, &iter);
18982912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
18992912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
19002912Sartem
19012912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
19022912Sartem message, -1,
19032912Sartem error);
1904*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
19052912Sartem dbus_message_unref (message);
19062912Sartem return FALSE;
19072912Sartem }
19082912Sartem if (reply == NULL) {
19092912Sartem dbus_message_unref (message);
19102912Sartem return FALSE;
19112912Sartem }
19122912Sartem return TRUE;
19132912Sartem }
19142912Sartem
19152912Sartem /**
19162912Sartem * libhal_device_property_strlist_remove_index:
19172912Sartem * @ctx: the context for the connection to hald
19182912Sartem * @udi: the Unique Device Id
19192912Sartem * @key: name of the property
19202912Sartem * @idx: index of string to remove in the strlist
19212912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
19222912Sartem *
19232912Sartem * Remove a specified string from a property of type strlist.
19242912Sartem *
19252912Sartem * Returns: TRUE if the string was removed, FALSE if the device didn't
19262912Sartem * exist or the property had a different type.
19272912Sartem */
19282912Sartem dbus_bool_t
libhal_device_property_strlist_remove_index(LibHalContext * ctx,const char * udi,const char * key,unsigned int idx,DBusError * error)19292912Sartem libhal_device_property_strlist_remove_index (LibHalContext *ctx,
19302912Sartem const char *udi,
19312912Sartem const char *key,
19322912Sartem unsigned int idx,
19332912Sartem DBusError *error)
19342912Sartem {
19352912Sartem DBusMessage *message;
19362912Sartem DBusMessage *reply;
19372912Sartem DBusMessageIter iter;
19382912Sartem
19392912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
19402912Sartem
19412912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
19422912Sartem "org.freedesktop.Hal.Device",
19432912Sartem "StringListRemoveIndex");
19442912Sartem if (message == NULL) {
19452912Sartem fprintf (stderr,
19462912Sartem "%s %d : Couldn't allocate D-BUS message\n",
19472912Sartem __FILE__, __LINE__);
19482912Sartem return FALSE;
19492912Sartem }
19502912Sartem dbus_message_iter_init_append (message, &iter);
19512912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
19522912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &idx);
19532912Sartem
19542912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
19552912Sartem message, -1,
19562912Sartem error);
1957*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
19582912Sartem dbus_message_unref (message);
19592912Sartem return FALSE;
19602912Sartem }
19612912Sartem if (reply == NULL) {
19622912Sartem dbus_message_unref (message);
19632912Sartem return FALSE;
19642912Sartem }
19652912Sartem return TRUE;
19662912Sartem }
19672912Sartem
19682912Sartem /**
19692912Sartem * libhal_device_property_strlist_remove:
19702912Sartem * @ctx: the context for the connection to hald
19712912Sartem * @udi: the Unique Device Id
19722912Sartem * @key: name of the property
19732912Sartem * @value: the string to remove
19742912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
19752912Sartem *
19762912Sartem * Remove a specified string from a property of type strlist.
19772912Sartem *
19782912Sartem * Returns: TRUE if the string was removed, FALSE if the device didn't
19792912Sartem * exist or the property had a different type.
19802912Sartem */
19812912Sartem dbus_bool_t
libhal_device_property_strlist_remove(LibHalContext * ctx,const char * udi,const char * key,const char * value,DBusError * error)19822912Sartem libhal_device_property_strlist_remove (LibHalContext *ctx,
19832912Sartem const char *udi,
19842912Sartem const char *key,
19852912Sartem const char *value, DBusError *error)
19862912Sartem {
19872912Sartem DBusMessage *message;
19882912Sartem DBusMessage *reply;
19892912Sartem DBusMessageIter iter;
19902912Sartem
19912912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
19922912Sartem
19932912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
19942912Sartem "org.freedesktop.Hal.Device",
19952912Sartem "StringListRemove");
19962912Sartem if (message == NULL) {
19972912Sartem fprintf (stderr,
19982912Sartem "%s %d : Couldn't allocate D-BUS message\n",
19992912Sartem __FILE__, __LINE__);
20002912Sartem return FALSE;
20012912Sartem }
20022912Sartem dbus_message_iter_init_append (message, &iter);
20032912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
20042912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
20052912Sartem
20062912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
20072912Sartem message, -1,
20082912Sartem error);
2009*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
20102912Sartem dbus_message_unref (message);
20112912Sartem return FALSE;
20122912Sartem }
20132912Sartem if (reply == NULL) {
20142912Sartem dbus_message_unref (message);
20152912Sartem return FALSE;
20162912Sartem }
20172912Sartem return TRUE;
20182912Sartem }
20192912Sartem
20202912Sartem
20212912Sartem /**
20222912Sartem * libhal_device_lock:
20232912Sartem * @ctx: the context for the connection to hald
20242912Sartem * @udi: the Unique Device Id
20252912Sartem * @reason_to_lock: a user-presentable reason why the device is locked.
20262912Sartem * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL
20272912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
20282912Sartem *
20292912Sartem * Take an advisory lock on the device.
20302912Sartem *
20312912Sartem * Returns: TRUE if the lock was obtained, FALSE otherwise
20322912Sartem */
20332912Sartem dbus_bool_t
libhal_device_lock(LibHalContext * ctx,const char * udi,const char * reason_to_lock,char ** reason_why_locked,DBusError * error)20342912Sartem libhal_device_lock (LibHalContext *ctx,
20352912Sartem const char *udi,
20362912Sartem const char *reason_to_lock,
20372912Sartem char **reason_why_locked, DBusError *error)
20382912Sartem {
20392912Sartem DBusMessage *message;
20402912Sartem DBusMessageIter iter;
20412912Sartem DBusMessage *reply;
20422912Sartem
20432912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
20442912Sartem
20452912Sartem if (reason_why_locked != NULL)
20462912Sartem *reason_why_locked = NULL;
20472912Sartem
20482912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
20492912Sartem udi,
20502912Sartem "org.freedesktop.Hal.Device",
20512912Sartem "Lock");
20522912Sartem
20532912Sartem if (message == NULL) {
20542912Sartem fprintf (stderr,
20552912Sartem "%s %d : Couldn't allocate D-BUS message\n",
20562912Sartem __FILE__, __LINE__);
20572912Sartem return FALSE;
20582912Sartem }
20592912Sartem
20602912Sartem dbus_message_iter_init_append (message, &iter);
20612912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &reason_to_lock);
20622912Sartem
20632912Sartem
20642912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
20652912Sartem message, -1,
20662912Sartem error);
20672912Sartem
2068*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
20692912Sartem if (strcmp (error->name,
20702912Sartem "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
20712912Sartem if (reason_why_locked != NULL) {
20722912Sartem *reason_why_locked =
20732912Sartem dbus_malloc0 (strlen (error->message) + 1);
20742912Sartem strcpy (*reason_why_locked, error->message);
20752912Sartem }
20762912Sartem }
20772912Sartem
20782912Sartem dbus_message_unref (message);
20792912Sartem return FALSE;
20802912Sartem }
20812912Sartem
20822912Sartem dbus_message_unref (message);
20832912Sartem
20842912Sartem if (reply == NULL)
20852912Sartem return FALSE;
20862912Sartem
20872912Sartem dbus_message_unref (reply);
20882912Sartem
20892912Sartem return TRUE;
20902912Sartem }
20912912Sartem
20922912Sartem /**
20932912Sartem * libhal_device_unlock:
20942912Sartem * @ctx: the context for the connection to hald
20952912Sartem * @udi: the Unique Device Id
20962912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
20972912Sartem *
20982912Sartem * Release an advisory lock on the device.
20992912Sartem *
21002912Sartem * Returns: TRUE if the device was successfully unlocked,
21012912Sartem * FALSE otherwise
21022912Sartem */
21032912Sartem dbus_bool_t
libhal_device_unlock(LibHalContext * ctx,const char * udi,DBusError * error)21042912Sartem libhal_device_unlock (LibHalContext *ctx,
21052912Sartem const char *udi, DBusError *error)
21062912Sartem {
21072912Sartem DBusMessage *message;
21082912Sartem DBusMessage *reply;
21092912Sartem
21102912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
21112912Sartem
21122912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
21132912Sartem udi,
21142912Sartem "org.freedesktop.Hal.Device",
21152912Sartem "Unlock");
21162912Sartem
21172912Sartem if (message == NULL) {
21182912Sartem fprintf (stderr,
21192912Sartem "%s %d : Couldn't allocate D-BUS message\n",
21202912Sartem __FILE__, __LINE__);
21212912Sartem return FALSE;
21222912Sartem }
21232912Sartem
21242912Sartem
21252912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
21262912Sartem message, -1,
21272912Sartem error);
21282912Sartem
2129*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
21302912Sartem dbus_message_unref (message);
21312912Sartem return FALSE;
21322912Sartem }
21332912Sartem
21342912Sartem dbus_message_unref (message);
21352912Sartem
21362912Sartem if (reply == NULL)
21372912Sartem return FALSE;
21382912Sartem
21392912Sartem dbus_message_unref (reply);
21402912Sartem
21412912Sartem return TRUE;
21422912Sartem }
21432912Sartem
21442912Sartem
21452912Sartem /**
21462912Sartem * libhal_new_device:
21472912Sartem * @ctx: the context for the connection to hald
21482912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
21492912Sartem *
21502912Sartem * Create a new device object which will be hidden from applications
21512912Sartem * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method
21522912Sartem * is called. Note that the program invoking this method needs to run
21532912Sartem * with super user privileges.
21542912Sartem *
21552912Sartem * Returns: Temporary device unique id or NULL if there was a
21562912Sartem * problem. This string must be freed by the caller.
21572912Sartem */
21582912Sartem char *
libhal_new_device(LibHalContext * ctx,DBusError * error)21592912Sartem libhal_new_device (LibHalContext *ctx, DBusError *error)
21602912Sartem {
21612912Sartem DBusMessage *message;
21622912Sartem DBusMessage *reply;
21632912Sartem DBusMessageIter reply_iter;
21642912Sartem char *value;
21652912Sartem char *dbus_str;
21662912Sartem
21672912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
21682912Sartem
21692912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
21702912Sartem "/org/freedesktop/Hal/Manager",
21712912Sartem "org.freedesktop.Hal.Manager",
21722912Sartem "NewDevice");
21732912Sartem if (message == NULL) {
21742912Sartem fprintf (stderr,
21752912Sartem "%s %d : Couldn't allocate D-BUS message\n",
21762912Sartem __FILE__, __LINE__);
21772912Sartem return NULL;
21782912Sartem }
21792912Sartem
21802912Sartem
21812912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
21822912Sartem message, -1,
21832912Sartem error);
2184*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
21852912Sartem dbus_message_unref (message);
21862912Sartem return NULL;
21872912Sartem }
21882912Sartem if (reply == NULL) {
21892912Sartem dbus_message_unref (message);
21902912Sartem return NULL;
21912912Sartem }
21922912Sartem
21932912Sartem dbus_message_iter_init (reply, &reply_iter);
21942912Sartem
21952912Sartem /* now analyze reply */
21962912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_STRING) {
21972912Sartem fprintf (stderr,
21982912Sartem "%s %d : expected a string in reply to NewDevice\n",
21992912Sartem __FILE__, __LINE__);
22002912Sartem dbus_message_unref (message);
22012912Sartem dbus_message_unref (reply);
22022912Sartem return NULL;
22032912Sartem }
22042912Sartem
22052912Sartem dbus_message_iter_get_basic (&reply_iter, &dbus_str);
22062912Sartem value = (char *) ((dbus_str != NULL) ? strdup (dbus_str) : NULL);
22072912Sartem if (value == NULL) {
22082912Sartem fprintf (stderr, "%s %d : error allocating memory\n",
22092912Sartem __FILE__, __LINE__);
22102912Sartem }
22112912Sartem
22122912Sartem dbus_message_unref (message);
22132912Sartem dbus_message_unref (reply);
22142912Sartem return value;
22152912Sartem }
22162912Sartem
22172912Sartem
22182912Sartem /**
22192912Sartem * libhal_device_commit_to_gdl:
22202912Sartem * @ctx: the context for the connection to hald
22212912Sartem * @temp_udi: the temporary unique device id as returned by libhal_new_device()
22222912Sartem * @udi: the new unique device id.
22232912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
22242912Sartem *
22252912Sartem * When a hidden device has been built using the NewDevice method,
22262912Sartem * ie. libhal_new_device(), and the org.freedesktop.Hal.Device
22272912Sartem * interface this function will commit it to the global device list.
22282912Sartem *
22292912Sartem * This means that the device object will be visible to applications
22302912Sartem * and the HAL daemon will possibly attempt to boot the device
22312912Sartem * (depending on the property RequireEnable).
22322912Sartem *
22332912Sartem * Note that the program invoking this method needs to run with super
22342912Sartem * user privileges.
22352912Sartem *
22362912Sartem * Returns: FALSE if the given unique device id is already in use.
22372912Sartem */
22382912Sartem dbus_bool_t
libhal_device_commit_to_gdl(LibHalContext * ctx,const char * temp_udi,const char * udi,DBusError * error)22392912Sartem libhal_device_commit_to_gdl (LibHalContext *ctx,
22402912Sartem const char *temp_udi, const char *udi, DBusError *error)
22412912Sartem {
22422912Sartem DBusMessage *message;
22432912Sartem DBusMessage *reply;
22442912Sartem DBusMessageIter iter;
22452912Sartem
22462912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
22472912Sartem
22482912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
22492912Sartem "/org/freedesktop/Hal/Manager",
22502912Sartem "org.freedesktop.Hal.Manager",
22512912Sartem "CommitToGdl");
22522912Sartem if (message == NULL) {
22532912Sartem fprintf (stderr,
22542912Sartem "%s %d : Couldn't allocate D-BUS message\n",
22552912Sartem __FILE__, __LINE__);
22562912Sartem return FALSE;
22572912Sartem }
22582912Sartem
22592912Sartem dbus_message_iter_init_append (message, &iter);
22602912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &temp_udi);
22612912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
22622912Sartem
22632912Sartem
22642912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
22652912Sartem message, -1,
22662912Sartem error);
2267*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
22682912Sartem dbus_message_unref (message);
22692912Sartem return FALSE;
22702912Sartem }
22712912Sartem if (reply == NULL) {
22722912Sartem dbus_message_unref (message);
22732912Sartem return FALSE;
22742912Sartem }
22752912Sartem
22762912Sartem dbus_message_unref (message);
22772912Sartem dbus_message_unref (reply);
22782912Sartem return TRUE;
22792912Sartem }
22802912Sartem
22812912Sartem /**
22822912Sartem * libhal_remove_device:
22832912Sartem * @ctx: the context for the connection to hald
22842912Sartem * @udi: the Unique device id.
22852912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
22862912Sartem *
22872912Sartem * This method can be invoked when a device is removed. The HAL daemon
22882912Sartem * will shut down the device. Note that the device may still be in the
22892912Sartem * device list if the Persistent property is set to true.
22902912Sartem *
22912912Sartem * Note that the program invoking this method needs to run with super
22922912Sartem * user privileges.
22932912Sartem *
22942912Sartem * Returns: TRUE if the device was removed, FALSE otherwise
22952912Sartem */
22962912Sartem dbus_bool_t
libhal_remove_device(LibHalContext * ctx,const char * udi,DBusError * error)22972912Sartem libhal_remove_device (LibHalContext *ctx, const char *udi, DBusError *error)
22982912Sartem {
22992912Sartem DBusMessage *message;
23002912Sartem DBusMessage *reply;
23012912Sartem DBusMessageIter iter;
23022912Sartem
23032912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
23042912Sartem
23052912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
23062912Sartem "/org/freedesktop/Hal/Manager",
23072912Sartem "org.freedesktop.Hal.Manager",
23082912Sartem "Remove");
23092912Sartem if (message == NULL) {
23102912Sartem fprintf (stderr,
23112912Sartem "%s %d : Couldn't allocate D-BUS message\n",
23122912Sartem __FILE__, __LINE__);
23132912Sartem return FALSE;
23142912Sartem }
23152912Sartem
23162912Sartem dbus_message_iter_init_append (message, &iter);
23172912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
23182912Sartem
23192912Sartem
23202912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
23212912Sartem message, -1,
23222912Sartem error);
2323*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
23242912Sartem dbus_message_unref (message);
23252912Sartem return FALSE;
23262912Sartem }
23272912Sartem if (reply == NULL) {
23282912Sartem dbus_message_unref (message);
23292912Sartem return FALSE;
23302912Sartem }
23312912Sartem
23322912Sartem dbus_message_unref (message);
23332912Sartem dbus_message_unref (reply);
23342912Sartem return TRUE;
23352912Sartem }
23362912Sartem
23372912Sartem /**
23382912Sartem * libhal_device_exists:
23392912Sartem * @ctx: the context for the connection to hald
23402912Sartem * @udi: the Unique device id.
23412912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
23422912Sartem *
23432912Sartem * Determine if a device exists.
23442912Sartem *
23452912Sartem * Returns: TRUE if the device exists
23462912Sartem */
23472912Sartem dbus_bool_t
libhal_device_exists(LibHalContext * ctx,const char * udi,DBusError * error)23482912Sartem libhal_device_exists (LibHalContext *ctx, const char *udi, DBusError *error)
23492912Sartem {
23502912Sartem DBusMessage *message;
23512912Sartem DBusMessage *reply;
23522912Sartem DBusMessageIter iter, reply_iter;
23532912Sartem dbus_bool_t value;
23542912Sartem DBusError _error;
23552912Sartem
23562912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
23572912Sartem
23582912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
23592912Sartem "/org/freedesktop/Hal/Manager",
23602912Sartem "org.freedesktop.Hal.Manager",
23612912Sartem "DeviceExists");
23622912Sartem if (message == NULL) {
23632912Sartem fprintf (stderr,
23642912Sartem "%s %d : Couldn't allocate D-BUS message\n",
23652912Sartem __FILE__, __LINE__);
23662912Sartem return FALSE;
23672912Sartem }
23682912Sartem
23692912Sartem dbus_message_iter_init_append (message, &iter);
23702912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &udi);
23712912Sartem
23722912Sartem dbus_error_init (&_error);
23732912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
23742912Sartem message, -1,
23752912Sartem &_error);
23762912Sartem
23772912Sartem dbus_move_error (&_error, error);
23782912Sartem if (error != NULL && dbus_error_is_set (error)) {
23792912Sartem dbus_message_unref (message);
23802912Sartem return FALSE;
23812912Sartem }
23822912Sartem if (reply == NULL) {
23832912Sartem dbus_message_unref (message);
23842912Sartem return FALSE;
23852912Sartem }
23862912Sartem
23872912Sartem dbus_message_iter_init (reply, &reply_iter);
23882912Sartem
23892912Sartem /* now analyze reply */
23902912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
23912912Sartem fprintf (stderr,
23922912Sartem "%s %d : expected a bool in reply to DeviceExists\n",
23932912Sartem __FILE__, __LINE__);
23942912Sartem dbus_message_unref (message);
23952912Sartem dbus_message_unref (reply);
23962912Sartem return FALSE;
23972912Sartem }
23982912Sartem
23992912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
24002912Sartem
24012912Sartem dbus_message_unref (message);
24022912Sartem dbus_message_unref (reply);
24032912Sartem return value;
24042912Sartem }
24052912Sartem
24062912Sartem /**
24072912Sartem * libhal_device_property_exists:
24082912Sartem * @ctx: the context for the connection to hald
24092912Sartem * @udi: the Unique device id.
24102912Sartem * @key: name of the property
24112912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
24122912Sartem *
24132912Sartem * Determine if a property on a device exists.
24142912Sartem *
24152912Sartem * Returns: TRUE if the device exists, FALSE otherwise
24162912Sartem */
24172912Sartem dbus_bool_t
libhal_device_property_exists(LibHalContext * ctx,const char * udi,const char * key,DBusError * error)24182912Sartem libhal_device_property_exists (LibHalContext *ctx,
24192912Sartem const char *udi, const char *key, DBusError *error)
24202912Sartem {
24212912Sartem DBusMessage *message;
24222912Sartem DBusMessage *reply;
24232912Sartem DBusMessageIter iter, reply_iter;
24242912Sartem dbus_bool_t value;
24252912Sartem DBusError _error;
24262912Sartem
24272912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
24282912Sartem
24292912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
24302912Sartem "org.freedesktop.Hal.Device",
24312912Sartem "PropertyExists");
24322912Sartem if (message == NULL) {
24332912Sartem fprintf (stderr,
24342912Sartem "%s %d : Couldn't allocate D-BUS message\n",
24352912Sartem __FILE__, __LINE__);
24362912Sartem return FALSE;
24372912Sartem }
24382912Sartem
24392912Sartem dbus_message_iter_init_append (message, &iter);
24402912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
24412912Sartem
24422912Sartem dbus_error_init (&_error);
24432912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
24442912Sartem message, -1,
24452912Sartem &_error);
24462912Sartem
24472912Sartem dbus_move_error (&_error, error);
24482912Sartem if (error != NULL && dbus_error_is_set (error)) {
24492912Sartem dbus_message_unref (message);
24502912Sartem return FALSE;
24512912Sartem }
24522912Sartem if (reply == NULL) {
24532912Sartem dbus_message_unref (message);
24542912Sartem return FALSE;
24552912Sartem }
24562912Sartem
24572912Sartem dbus_message_iter_init (reply, &reply_iter);
24582912Sartem
24592912Sartem /* now analyse reply */
24602912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
24612912Sartem fprintf (stderr, "%s %d : expected a bool in reply to "
24622912Sartem "PropertyExists\n", __FILE__, __LINE__);
24632912Sartem dbus_message_unref (message);
24642912Sartem dbus_message_unref (reply);
24652912Sartem return FALSE;
24662912Sartem }
24672912Sartem
24682912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
24692912Sartem
24702912Sartem dbus_message_unref (message);
24712912Sartem dbus_message_unref (reply);
24722912Sartem return value;
24732912Sartem }
24742912Sartem
24752912Sartem /**
24762912Sartem * libhal_merge_properties:
24772912Sartem * @ctx: the context for the connection to hald
24782912Sartem * @target_udi: the Unique device id of target device to merge to
24792912Sartem * @source_udi: the Unique device id of device to merge from
24802912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
24812912Sartem *
24822912Sartem * Merge properties from one device to another.
24832912Sartem *
24842912Sartem * Returns: TRUE if the properties were merged, FALSE otherwise
24852912Sartem */
24862912Sartem dbus_bool_t
libhal_merge_properties(LibHalContext * ctx,const char * target_udi,const char * source_udi,DBusError * error)24872912Sartem libhal_merge_properties (LibHalContext *ctx,
24882912Sartem const char *target_udi, const char *source_udi, DBusError *error)
24892912Sartem {
24902912Sartem DBusMessage *message;
24912912Sartem DBusMessage *reply;
24922912Sartem DBusMessageIter iter;
24932912Sartem
24942912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
24952912Sartem
24962912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
24972912Sartem "/org/freedesktop/Hal/Manager",
24982912Sartem "org.freedesktop.Hal.Manager",
24992912Sartem "MergeProperties");
25002912Sartem if (message == NULL) {
25012912Sartem fprintf (stderr,
25022912Sartem "%s %d : Couldn't allocate D-BUS message\n",
25032912Sartem __FILE__, __LINE__);
25042912Sartem return FALSE;
25052912Sartem }
25062912Sartem
25072912Sartem dbus_message_iter_init_append (message, &iter);
25082912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &target_udi);
25092912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &source_udi);
25102912Sartem
25112912Sartem
25122912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
25132912Sartem message, -1,
25142912Sartem error);
2515*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
25162912Sartem dbus_message_unref (message);
25172912Sartem return FALSE;
25182912Sartem }
25192912Sartem if (reply == NULL) {
25202912Sartem dbus_message_unref (message);
25212912Sartem return FALSE;
25222912Sartem }
25232912Sartem
25242912Sartem dbus_message_unref (message);
25252912Sartem dbus_message_unref (reply);
25262912Sartem return TRUE;
25272912Sartem }
25282912Sartem
25292912Sartem /**
25302912Sartem * libhal_device_matches:
25312912Sartem * @ctx: the context for the connection to hald
25322912Sartem * @udi1: the Unique Device Id for device 1
25332912Sartem * @udi2: the Unique Device Id for device 2
25342912Sartem * @property_namespace: the namespace for set of devices, e.g. "usb"
25352912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
25362912Sartem *
25372912Sartem * Check a set of properties for two devices matches.
25382912Sartem *
25392912Sartem * Checks that all properties where keys, starting with a given value
25402912Sartem * (namespace), of the first device is in the second device and that
25412912Sartem * they got the same value and type.
25422912Sartem *
25432912Sartem * Note that the other inclusion isn't tested, so there could be
25442912Sartem * properties (from the given namespace) in the second device not
25452912Sartem * present in the first device.
25462912Sartem *
25472912Sartem * Returns: TRUE if all properties starting with the given namespace
25482912Sartem * parameter from one device is in the other and have the same value.
25492912Sartem */
25502912Sartem dbus_bool_t
libhal_device_matches(LibHalContext * ctx,const char * udi1,const char * udi2,const char * property_namespace,DBusError * error)25512912Sartem libhal_device_matches (LibHalContext *ctx,
25522912Sartem const char *udi1, const char *udi2,
25532912Sartem const char *property_namespace, DBusError *error)
25542912Sartem {
25552912Sartem DBusMessage *message;
25562912Sartem DBusMessage *reply;
25572912Sartem DBusMessageIter iter, reply_iter;
25582912Sartem dbus_bool_t value;
25592912Sartem DBusError _error;
25602912Sartem
25612912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
25622912Sartem
25632912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
25642912Sartem "/org/freedesktop/Hal/Manager",
25652912Sartem "org.freedesktop.Hal.Manager",
25662912Sartem "DeviceMatches");
25672912Sartem if (message == NULL) {
25682912Sartem fprintf (stderr,
25692912Sartem "%s %d : Couldn't allocate D-BUS message\n",
25702912Sartem __FILE__, __LINE__);
25712912Sartem return FALSE;
25722912Sartem }
25732912Sartem
25742912Sartem dbus_message_iter_init_append (message, &iter);
25752912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi1);
25762912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, udi2);
25772912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, property_namespace);
25782912Sartem
25792912Sartem dbus_error_init (&_error);
25802912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
25812912Sartem message, -1,
25822912Sartem &_error);
25832912Sartem
25842912Sartem dbus_move_error (&_error, error);
25852912Sartem if (error != NULL && dbus_error_is_set (error)) {
25862912Sartem dbus_message_unref (message);
25872912Sartem return FALSE;
25882912Sartem }
25892912Sartem if (reply == NULL) {
25902912Sartem dbus_message_unref (message);
25912912Sartem return FALSE;
25922912Sartem }
25932912Sartem /* now analyse reply */
25942912Sartem dbus_message_iter_init (reply, &reply_iter);
25952912Sartem
25962912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
25972912Sartem fprintf (stderr,
25982912Sartem "%s %d : expected a bool in reply to DeviceMatches\n",
25992912Sartem __FILE__, __LINE__);
26002912Sartem dbus_message_unref (message);
26012912Sartem dbus_message_unref (reply);
26022912Sartem return FALSE;
26032912Sartem }
26042912Sartem
26052912Sartem dbus_message_iter_get_basic (&reply_iter, &value);
26062912Sartem
26072912Sartem dbus_message_unref (message);
26082912Sartem dbus_message_unref (reply);
26092912Sartem return value;
26102912Sartem }
26112912Sartem
26122912Sartem /**
26132912Sartem * libhal_device_print:
26142912Sartem * @ctx: the context for the connection to hald
26152912Sartem * @udi: the Unique Device Id
26162912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
26172912Sartem *
26182912Sartem * Print a device to stdout; useful for debugging.
26192912Sartem *
26202912Sartem * Returns: TRUE if device's information could be obtained, FALSE otherwise
26212912Sartem */
26222912Sartem dbus_bool_t
libhal_device_print(LibHalContext * ctx,const char * udi,DBusError * error)26232912Sartem libhal_device_print (LibHalContext *ctx, const char *udi, DBusError *error)
26242912Sartem {
26252912Sartem int type;
26262912Sartem char *key;
26272912Sartem LibHalPropertySet *pset;
26282912Sartem LibHalPropertySetIterator i;
26292912Sartem
26302912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
26312912Sartem
26322912Sartem printf ("device_id = %s\n", udi);
26332912Sartem
26342912Sartem if ((pset = libhal_device_get_all_properties (ctx, udi, error)) == NULL)
26352912Sartem return FALSE;
26362912Sartem
26372912Sartem for (libhal_psi_init (&i, pset); libhal_psi_has_more (&i);
26382912Sartem libhal_psi_next (&i)) {
26392912Sartem type = libhal_psi_get_type (&i);
26402912Sartem key = libhal_psi_get_key (&i);
26412912Sartem
26422912Sartem switch (type) {
26432912Sartem case LIBHAL_PROPERTY_TYPE_STRING:
26442912Sartem printf (" %s = '%s' (string)\n", key,
26452912Sartem libhal_psi_get_string (&i));
26462912Sartem break;
26472912Sartem case LIBHAL_PROPERTY_TYPE_INT32:
26482912Sartem printf (" %s = %d = 0x%x (int)\n", key,
26492912Sartem libhal_psi_get_int (&i),
26502912Sartem libhal_psi_get_int (&i));
26512912Sartem break;
26522912Sartem case LIBHAL_PROPERTY_TYPE_UINT64:
26532912Sartem printf (" %s = %llu = 0x%llx (uint64)\n", key,
26542912Sartem (long long unsigned int) libhal_psi_get_uint64 (&i),
26552912Sartem (long long unsigned int) libhal_psi_get_uint64 (&i));
26562912Sartem break;
26572912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN:
26582912Sartem printf (" %s = %s (bool)\n", key,
26592912Sartem (libhal_psi_get_bool (&i) ? "true" :
26602912Sartem "false"));
26612912Sartem break;
26622912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE:
26632912Sartem printf (" %s = %g (double)\n", key,
26642912Sartem libhal_psi_get_double (&i));
26652912Sartem break;
26662912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST:
26672912Sartem {
26682912Sartem unsigned int j;
26692912Sartem char **str_list;
26702912Sartem
26712912Sartem str_list = libhal_psi_get_strlist (&i);
26722912Sartem printf (" %s = [", key);
26732912Sartem for (j = 0; str_list[j] != NULL; j++) {
26742912Sartem printf ("'%s'", str_list[j]);
26752912Sartem if (str_list[j+1] != NULL)
26762912Sartem printf (", ");
26772912Sartem }
26782912Sartem printf ("] (string list)\n");
26792912Sartem
26802912Sartem break;
26812912Sartem }
26822912Sartem default:
26832912Sartem printf (" *** unknown type for key %s\n", key);
26842912Sartem break;
26852912Sartem }
26862912Sartem }
26872912Sartem
26882912Sartem libhal_free_property_set (pset);
26892912Sartem
26902912Sartem return TRUE;
26912912Sartem }
26922912Sartem
26932912Sartem /**
26942912Sartem * libhal_manager_find_device_string_match:
26952912Sartem * @ctx: the context for the connection to hald
26962912Sartem * @key: name of the property
26972912Sartem * @value: the value to match
26982912Sartem * @num_devices: pointer to store number of devices
26992912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
27002912Sartem *
27012912Sartem * Find a device in the GDL where a single string property matches a
27022912Sartem * given value.
27032912Sartem *
27042912Sartem * Returns: UDI of devices; free with libhal_free_string_array()
27052912Sartem */
27062912Sartem char **
libhal_manager_find_device_string_match(LibHalContext * ctx,const char * key,const char * value,int * num_devices,DBusError * error)27072912Sartem libhal_manager_find_device_string_match (LibHalContext *ctx,
27082912Sartem const char *key,
27092912Sartem const char *value, int *num_devices, DBusError *error)
27102912Sartem {
27112912Sartem DBusMessage *message;
27122912Sartem DBusMessage *reply;
27132912Sartem DBusMessageIter iter, iter_array, reply_iter;
27142912Sartem char **hal_device_names;
27152912Sartem DBusError _error;
27162912Sartem
27172912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
27182912Sartem
27192912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
27202912Sartem "/org/freedesktop/Hal/Manager",
27212912Sartem "org.freedesktop.Hal.Manager",
27222912Sartem "FindDeviceStringMatch");
27232912Sartem if (message == NULL) {
27242912Sartem fprintf (stderr,
27252912Sartem "%s %d : Couldn't allocate D-BUS message\n",
27262912Sartem __FILE__, __LINE__);
27272912Sartem return NULL;
27282912Sartem }
27292912Sartem
27302912Sartem dbus_message_iter_init_append (message, &iter);
27312912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
27322912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
27332912Sartem
27342912Sartem dbus_error_init (&_error);
27352912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
27362912Sartem message, -1,
27372912Sartem &_error);
27382912Sartem
27392912Sartem dbus_move_error (&_error, error);
27402912Sartem if (error != NULL && dbus_error_is_set (error)) {
27412912Sartem dbus_message_unref (message);
27422912Sartem return NULL;
27432912Sartem }
27442912Sartem if (reply == NULL) {
27452912Sartem dbus_message_unref (message);
27462912Sartem return NULL;
27472912Sartem }
27482912Sartem /* now analyse reply */
27492912Sartem dbus_message_iter_init (reply, &reply_iter);
27502912Sartem
27512912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
27522912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
27532912Sartem return NULL;
27542912Sartem }
27552912Sartem
27562912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array);
27572912Sartem
27582912Sartem hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
27592912Sartem
27602912Sartem dbus_message_unref (reply);
27612912Sartem dbus_message_unref (message);
27622912Sartem
27632912Sartem return hal_device_names;
27642912Sartem }
27652912Sartem
27662912Sartem
27672912Sartem /**
27682912Sartem * libhal_device_add_capability:
27692912Sartem * @ctx: the context for the connection to hald
27702912Sartem * @udi: the Unique Device Id
27712912Sartem * @capability: the capability name to add
27722912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
27732912Sartem *
27742912Sartem * Assign a capability to a device.
27752912Sartem *
27762912Sartem * Returns: TRUE if the capability was added, FALSE if the device didn't exist
27772912Sartem */
27782912Sartem dbus_bool_t
libhal_device_add_capability(LibHalContext * ctx,const char * udi,const char * capability,DBusError * error)27792912Sartem libhal_device_add_capability (LibHalContext *ctx,
27802912Sartem const char *udi, const char *capability, DBusError *error)
27812912Sartem {
27822912Sartem DBusMessage *message;
27832912Sartem DBusMessage *reply;
27842912Sartem DBusMessageIter iter;
27852912Sartem
27862912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
27872912Sartem
27882912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
27892912Sartem "org.freedesktop.Hal.Device",
27902912Sartem "AddCapability");
27912912Sartem if (message == NULL) {
27922912Sartem fprintf (stderr,
27932912Sartem "%s %d : Couldn't allocate D-BUS message\n",
27942912Sartem __FILE__, __LINE__);
27952912Sartem return FALSE;
27962912Sartem }
27972912Sartem
27982912Sartem dbus_message_iter_init_append (message, &iter);
27992912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
28002912Sartem
28012912Sartem
28022912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
28032912Sartem message, -1,
28042912Sartem error);
2805*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
28062912Sartem dbus_message_unref (message);
28072912Sartem return FALSE;
28082912Sartem }
28092912Sartem
28102912Sartem if (reply == NULL) {
28112912Sartem dbus_message_unref (message);
28122912Sartem return FALSE;
28132912Sartem }
28142912Sartem
28152912Sartem dbus_message_unref (reply);
28162912Sartem dbus_message_unref (message);
28172912Sartem return TRUE;
28182912Sartem }
28192912Sartem
28202912Sartem /**
28212912Sartem * libhal_device_query_capability:
28222912Sartem * @ctx: the context for the connection to hald
28232912Sartem * @udi: the Unique Device Id
28242912Sartem * @capability: the capability name
28252912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
28262912Sartem *
28272912Sartem * Check if a device has a capability. The result is undefined if the
28282912Sartem * device doesn't exist.
28292912Sartem *
28302912Sartem * Returns: TRUE if the device has the capability, otherwise FALSE
28312912Sartem */
28322912Sartem dbus_bool_t
libhal_device_query_capability(LibHalContext * ctx,const char * udi,const char * capability,DBusError * error)28332912Sartem libhal_device_query_capability (LibHalContext *ctx, const char *udi, const char *capability, DBusError *error)
28342912Sartem {
28352912Sartem char **caps;
28362912Sartem unsigned int i;
28372912Sartem dbus_bool_t ret;
28382912Sartem
28392912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
28402912Sartem
28412912Sartem ret = FALSE;
28422912Sartem
28432912Sartem caps = libhal_device_get_property_strlist (ctx, udi, "info.capabilities", error);
28442912Sartem if (caps != NULL) {
28452912Sartem for (i = 0; caps[i] != NULL; i++) {
28462912Sartem if (strcmp (caps[i], capability) == 0) {
28472912Sartem ret = TRUE;
28482912Sartem break;
28492912Sartem }
28502912Sartem }
28512912Sartem libhal_free_string_array (caps);
28522912Sartem }
28532912Sartem
28542912Sartem return ret;
28552912Sartem }
28562912Sartem
28572912Sartem /**
28582912Sartem * libhal_find_device_by_capability:
28592912Sartem * @ctx: the context for the connection to hald
28602912Sartem * @capability: the capability name
28612912Sartem * @num_devices: pointer to store number of devices
28622912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
28632912Sartem *
28642912Sartem * Find devices with a given capability.
28652912Sartem *
28662912Sartem * Returns: UDI of devices; free with libhal_free_string_array()
28672912Sartem */
28682912Sartem char **
libhal_find_device_by_capability(LibHalContext * ctx,const char * capability,int * num_devices,DBusError * error)28692912Sartem libhal_find_device_by_capability (LibHalContext *ctx,
28702912Sartem const char *capability, int *num_devices, DBusError *error)
28712912Sartem {
28722912Sartem DBusMessage *message;
28732912Sartem DBusMessage *reply;
28742912Sartem DBusMessageIter iter, iter_array, reply_iter;
28752912Sartem char **hal_device_names;
28762912Sartem DBusError _error;
28772912Sartem
28782912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, NULL);
28792912Sartem
28802912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
28812912Sartem "/org/freedesktop/Hal/Manager",
28822912Sartem "org.freedesktop.Hal.Manager",
28832912Sartem "FindDeviceByCapability");
28842912Sartem if (message == NULL) {
28852912Sartem fprintf (stderr,
28862912Sartem "%s %d : Couldn't allocate D-BUS message\n",
28872912Sartem __FILE__, __LINE__);
28882912Sartem return NULL;
28892912Sartem }
28902912Sartem
28912912Sartem dbus_message_iter_init_append (message, &iter);
28922912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &capability);
28932912Sartem
28942912Sartem dbus_error_init (&_error);
28952912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
28962912Sartem message, -1,
28972912Sartem &_error);
28982912Sartem
28992912Sartem dbus_move_error (&_error, error);
29002912Sartem if (error != NULL && dbus_error_is_set (error)) {
29012912Sartem dbus_message_unref (message);
29022912Sartem return NULL;
29032912Sartem }
29042912Sartem if (reply == NULL) {
29052912Sartem dbus_message_unref (message);
29062912Sartem return NULL;
29072912Sartem }
29082912Sartem /* now analyse reply */
29092912Sartem dbus_message_iter_init (reply, &reply_iter);
29102912Sartem
29112912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY) {
29122912Sartem fprintf (stderr, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__, __LINE__);
29132912Sartem return NULL;
29142912Sartem }
29152912Sartem
29162912Sartem dbus_message_iter_recurse (&reply_iter, &iter_array);
29172912Sartem
29182912Sartem hal_device_names = libhal_get_string_array_from_iter (&iter_array, num_devices);
29192912Sartem
29202912Sartem dbus_message_unref (reply);
29212912Sartem dbus_message_unref (message);
29222912Sartem
29232912Sartem return hal_device_names;
29242912Sartem }
29252912Sartem
29262912Sartem /**
29272912Sartem * libhal_device_property_watch_all:
29282912Sartem * @ctx: the context for the connection to hald
29292912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
29302912Sartem *
29312912Sartem * Watch all devices, ie. the device_property_changed callback is
29322912Sartem * invoked when the properties on any device changes.
29332912Sartem *
29342912Sartem * Returns: TRUE only if the operation succeeded
29352912Sartem */
29362912Sartem dbus_bool_t
libhal_device_property_watch_all(LibHalContext * ctx,DBusError * error)29372912Sartem libhal_device_property_watch_all (LibHalContext *ctx, DBusError *error)
29382912Sartem {
29392912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
29402912Sartem
29412912Sartem dbus_bus_add_match (ctx->connection,
29422912Sartem "type='signal',"
29432912Sartem "interface='org.freedesktop.Hal.Device',"
29442912Sartem "sender='org.freedesktop.Hal'", error);
2945*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
29462912Sartem return FALSE;
29472912Sartem }
29482912Sartem return TRUE;
29492912Sartem }
29502912Sartem
29512912Sartem
29522912Sartem /**
29532912Sartem * libhal_device_add_property_watch:
29542912Sartem * @ctx: the context for the connection to hald
29552912Sartem * @udi: the Unique Device Id
29562912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
29572912Sartem *
29582912Sartem * Add a watch on a device, so the device_property_changed callback is
29592912Sartem * invoked when the properties on the given device changes.
29602912Sartem *
29612912Sartem * The application itself is responsible for deleting the watch, using
29622912Sartem * libhal_device_remove_property_watch, if the device is removed.
29632912Sartem *
29642912Sartem * Returns: TRUE only if the operation succeeded
29652912Sartem */
29662912Sartem dbus_bool_t
libhal_device_add_property_watch(LibHalContext * ctx,const char * udi,DBusError * error)29672912Sartem libhal_device_add_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
29682912Sartem {
29692912Sartem char buf[512];
29702912Sartem
29712912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
29722912Sartem
29732912Sartem snprintf (buf, 512,
29742912Sartem "type='signal',"
29752912Sartem "interface='org.freedesktop.Hal.Device',"
29762912Sartem "sender='org.freedesktop.Hal'," "path=%s", udi);
29772912Sartem
29782912Sartem dbus_bus_add_match (ctx->connection, buf, error);
2979*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
29802912Sartem return FALSE;
29812912Sartem }
29822912Sartem return TRUE;
29832912Sartem }
29842912Sartem
29852912Sartem
29862912Sartem /**
29872912Sartem * libhal_device_remove_property_watch:
29882912Sartem * @ctx: the context for the connection to hald
29892912Sartem * @udi: the Unique Device Id
29902912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
29912912Sartem *
29922912Sartem * Remove a watch on a device.
29932912Sartem *
29942912Sartem * Returns: TRUE only if the operation succeeded
29952912Sartem */
29962912Sartem dbus_bool_t
libhal_device_remove_property_watch(LibHalContext * ctx,const char * udi,DBusError * error)29972912Sartem libhal_device_remove_property_watch (LibHalContext *ctx, const char *udi, DBusError *error)
29982912Sartem {
29992912Sartem char buf[512];
30002912Sartem
30012912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
30022912Sartem
30032912Sartem snprintf (buf, 512,
30042912Sartem "type='signal',"
30052912Sartem "interface='org.freedesktop.Hal.Device',"
30062912Sartem "sender='org.freedesktop.Hal'," "path=%s", udi);
30072912Sartem
30082912Sartem dbus_bus_remove_match (ctx->connection, buf, error);
3009*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
30102912Sartem return FALSE;
30112912Sartem }
30122912Sartem return TRUE;
30132912Sartem }
30142912Sartem
30152912Sartem
30162912Sartem /**
30172912Sartem * libhal_ctx_new:
30182912Sartem *
30192912Sartem * Create a new LibHalContext
30202912Sartem *
30212912Sartem * Returns: a new uninitialized LibHalContext object
30222912Sartem */
30232912Sartem LibHalContext *
libhal_ctx_new(void)30242912Sartem libhal_ctx_new (void)
30252912Sartem {
30262912Sartem LibHalContext *ctx;
30272912Sartem
30282912Sartem if (!libhal_already_initialized_once) {
30292912Sartem bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
30302912Sartem bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
30312912Sartem
30322912Sartem libhal_already_initialized_once = TRUE;
30332912Sartem }
30342912Sartem
30352912Sartem ctx = calloc (1, sizeof (LibHalContext));
30362912Sartem if (ctx == NULL) {
30372912Sartem fprintf (stderr,
30382912Sartem "%s %d : Failed to allocate %d bytes\n",
30392912Sartem __FILE__, __LINE__, sizeof (LibHalContext));
30402912Sartem return NULL;
30412912Sartem }
30422912Sartem
30432912Sartem ctx->is_initialized = FALSE;
30442912Sartem ctx->is_shutdown = FALSE;
30452912Sartem ctx->connection = NULL;
30462912Sartem ctx->is_direct = FALSE;
30472912Sartem
30482912Sartem return ctx;
30492912Sartem }
30502912Sartem
30512912Sartem /**
30522912Sartem * libhal_ctx_set_cache:
30532912Sartem * @ctx: context to enable/disable cache for
30542912Sartem * @use_cache: whether or not to use cache
30552912Sartem *
30562912Sartem * Enable or disable caching. Note: Caching is not actually
30572912Sartem * implemented yet.
30582912Sartem *
30592912Sartem * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise
30602912Sartem */
30612912Sartem dbus_bool_t
libhal_ctx_set_cache(LibHalContext * ctx,dbus_bool_t use_cache)30622912Sartem libhal_ctx_set_cache (LibHalContext *ctx, dbus_bool_t use_cache)
30632912Sartem {
30642912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
30652912Sartem
30662912Sartem ctx->cache_enabled = use_cache;
30672912Sartem return TRUE;
30682912Sartem }
30692912Sartem
30702912Sartem /**
30712912Sartem * libhal_ctx_set_dbus_connection:
30722912Sartem * @ctx: context to set connection for
30732912Sartem * @conn: DBus connection to use
30742912Sartem *
30752912Sartem * Set DBus connection to use to talk to hald.
30762912Sartem *
30772912Sartem * Returns: TRUE if connection was successfully set, FALSE otherwise
30782912Sartem */
30792912Sartem dbus_bool_t
libhal_ctx_set_dbus_connection(LibHalContext * ctx,DBusConnection * conn)30802912Sartem libhal_ctx_set_dbus_connection (LibHalContext *ctx, DBusConnection *conn)
30812912Sartem {
30822912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
30832912Sartem
30842912Sartem if (conn == NULL)
30852912Sartem return FALSE;
30862912Sartem
30872912Sartem ctx->connection = conn;
30882912Sartem return TRUE;
30892912Sartem }
30902912Sartem
30912912Sartem /**
30922912Sartem * libhal_ctx_get_dbus_connection:
30932912Sartem * @ctx: context to get connection for
30942912Sartem *
30952912Sartem * Get DBus connection used for talking to hald.
30962912Sartem *
30972912Sartem * Returns: DBus connection to use or NULL
30982912Sartem */
30992912Sartem DBusConnection *
libhal_ctx_get_dbus_connection(LibHalContext * ctx)31002912Sartem libhal_ctx_get_dbus_connection (LibHalContext *ctx)
31012912Sartem {
31022912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
31032912Sartem
31042912Sartem return ctx->connection;
31052912Sartem }
31062912Sartem
31072912Sartem
31082912Sartem /**
31092912Sartem * libhal_ctx_init:
31102912Sartem * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection)
31112912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
31122912Sartem *
31132912Sartem * Initialize the connection to hald.
31142912Sartem *
31152912Sartem * Returns: TRUE if initialization succeeds, FALSE otherwise
31162912Sartem */
31172912Sartem dbus_bool_t
libhal_ctx_init(LibHalContext * ctx,DBusError * error)31182912Sartem libhal_ctx_init (LibHalContext *ctx, DBusError *error)
31192912Sartem {
31202912Sartem DBusError _error;
31212912Sartem dbus_bool_t hald_exists;
31222912Sartem
31232912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
31242912Sartem
31252912Sartem if (ctx->connection == NULL)
31262912Sartem return FALSE;
31272912Sartem
31282912Sartem dbus_error_init (&_error);
31292912Sartem hald_exists = dbus_bus_name_has_owner (ctx->connection, "org.freedesktop.Hal", &_error);
31302912Sartem dbus_move_error (&_error, error);
31312912Sartem if (error != NULL && dbus_error_is_set (error)) {
31322912Sartem return FALSE;
31332912Sartem }
31342912Sartem
31352912Sartem if (!hald_exists) {
31362912Sartem return FALSE;
31372912Sartem }
31382912Sartem
31392912Sartem
31402912Sartem if (!dbus_connection_add_filter (ctx->connection, filter_func, ctx, NULL)) {
31412912Sartem return FALSE;
31422912Sartem }
31432912Sartem
31442912Sartem dbus_bus_add_match (ctx->connection,
31452912Sartem "type='signal',"
31462912Sartem "interface='org.freedesktop.Hal.Manager',"
31472912Sartem "sender='org.freedesktop.Hal',"
31482912Sartem "path='/org/freedesktop/Hal/Manager'", &_error);
31492912Sartem dbus_move_error (&_error, error);
31502912Sartem if (error != NULL && dbus_error_is_set (error)) {
31512912Sartem return FALSE;
31522912Sartem }
31532912Sartem ctx->is_initialized = TRUE;
31542912Sartem ctx->is_direct = FALSE;
31552912Sartem
31562912Sartem return TRUE;
31572912Sartem }
31582912Sartem
31592912Sartem /**
31602912Sartem * libhal_ctx_init_direct:
31612912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
31622912Sartem *
31632912Sartem * Create an already initialized connection to hald. This function should only be used by HAL helpers.
31642912Sartem *
31652912Sartem * Returns: A pointer to an already initialized LibHalContext
31662912Sartem */
31672912Sartem LibHalContext *
libhal_ctx_init_direct(DBusError * error)31682912Sartem libhal_ctx_init_direct (DBusError *error)
31692912Sartem {
31702912Sartem char *hald_addr;
31712912Sartem LibHalContext *ctx;
31722912Sartem DBusError _error;
31732912Sartem
31742912Sartem ctx = libhal_ctx_new ();
31752912Sartem if (ctx == NULL)
31762912Sartem goto out;
31772912Sartem
31782912Sartem if (((hald_addr = getenv ("HALD_DIRECT_ADDR"))) == NULL) {
31792912Sartem libhal_ctx_free (ctx);
31802912Sartem ctx = NULL;
31812912Sartem goto out;
31822912Sartem }
31832912Sartem
31842912Sartem dbus_error_init (&_error);
31852912Sartem ctx->connection = dbus_connection_open (hald_addr, &_error);
31862912Sartem dbus_move_error (&_error, error);
31872912Sartem if (error != NULL && dbus_error_is_set (error)) {
31882912Sartem libhal_ctx_free (ctx);
31892912Sartem ctx = NULL;
31902912Sartem goto out;
31912912Sartem }
31922912Sartem
31932912Sartem ctx->is_initialized = TRUE;
31942912Sartem ctx->is_direct = TRUE;
31952912Sartem
31962912Sartem out:
31972912Sartem return ctx;
31982912Sartem }
31992912Sartem
32002912Sartem /**
32012912Sartem * libhal_ctx_shutdown:
32022912Sartem * @ctx: the context for the connection to hald
32032912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
32042912Sartem *
32052912Sartem * Shut down a connection to hald.
32062912Sartem *
32072912Sartem * Returns: TRUE if connection successfully shut down, FALSE otherwise
32082912Sartem */
32092912Sartem dbus_bool_t
libhal_ctx_shutdown(LibHalContext * ctx,DBusError * error)32102912Sartem libhal_ctx_shutdown (LibHalContext *ctx, DBusError *error)
32112912Sartem {
32122912Sartem DBusError myerror;
32132912Sartem
32142912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
32152912Sartem
32162912Sartem if (ctx->is_direct) {
32172912Sartem /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */
32182912Sartem /*dbus_connection_unref (ctx->connection);*/
32192912Sartem } else {
32202912Sartem dbus_error_init (&myerror);
32212912Sartem dbus_bus_remove_match (ctx->connection,
32222912Sartem "type='signal',"
32232912Sartem "interface='org.freedesktop.Hal.Manager',"
32242912Sartem "sender='org.freedesktop.Hal',"
32252912Sartem "path='/org/freedesktop/Hal/Manager'", &myerror);
322611283SFei.Feng@Sun.COM dbus_move_error(&myerror, error);
322711283SFei.Feng@Sun.COM if (error != NULL && dbus_error_is_set(error)) {
32282912Sartem fprintf (stderr, "%s %d : Error unsubscribing to signals, error=%s\n",
32292912Sartem __FILE__, __LINE__, error->message);
32302912Sartem /** @todo clean up */
32312912Sartem }
32322912Sartem
32332912Sartem /* TODO: remove other matches */
32342912Sartem
32352912Sartem dbus_connection_remove_filter (ctx->connection, filter_func, ctx);
32362912Sartem }
32372912Sartem
32382912Sartem ctx->is_initialized = FALSE;
32392912Sartem
32402912Sartem return TRUE;
32412912Sartem }
32422912Sartem
32432912Sartem /**
32442912Sartem * libhal_ctx_free:
32452912Sartem * @ctx: pointer to a LibHalContext
32462912Sartem *
32472912Sartem * Free a LibHalContext resource.
32482912Sartem *
32492912Sartem * Returns: TRUE
32502912Sartem */
32512912Sartem dbus_bool_t
libhal_ctx_free(LibHalContext * ctx)32522912Sartem libhal_ctx_free (LibHalContext *ctx)
32532912Sartem {
32542912Sartem free (ctx);
32552912Sartem return TRUE;
32562912Sartem }
32572912Sartem
32582912Sartem /**
32592912Sartem * libhal_ctx_set_device_added:
32602912Sartem * @ctx: the context for the connection to hald
32612912Sartem * @callback: the function to call when a device is added
32622912Sartem *
32632912Sartem * Set the callback for when a device is added
32642912Sartem *
32652912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise
32662912Sartem */
32672912Sartem dbus_bool_t
libhal_ctx_set_device_added(LibHalContext * ctx,LibHalDeviceAdded callback)32682912Sartem libhal_ctx_set_device_added (LibHalContext *ctx, LibHalDeviceAdded callback)
32692912Sartem {
32702912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
32712912Sartem
32722912Sartem ctx->device_added = callback;
32732912Sartem return TRUE;
32742912Sartem }
32752912Sartem
32762912Sartem /**
32772912Sartem * libhal_ctx_set_device_removed:
32782912Sartem * @ctx: the context for the connection to hald
32792912Sartem * @callback: the function to call when a device is removed
32802912Sartem *
32812912Sartem * Set the callback for when a device is removed.
32822912Sartem *
32832912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise
32842912Sartem */
32852912Sartem dbus_bool_t
libhal_ctx_set_device_removed(LibHalContext * ctx,LibHalDeviceRemoved callback)32862912Sartem libhal_ctx_set_device_removed (LibHalContext *ctx, LibHalDeviceRemoved callback)
32872912Sartem {
32882912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
32892912Sartem
32902912Sartem ctx->device_removed = callback;
32912912Sartem return TRUE;
32922912Sartem }
32932912Sartem
32942912Sartem /**
32952912Sartem * libhal_ctx_set_device_new_capability:
32962912Sartem * @ctx: the context for the connection to hald
32972912Sartem * @callback: the function to call when a device gains a new capability
32982912Sartem *
32992912Sartem * Set the callback for when a device gains a new capability.
33002912Sartem *
33012912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise
33022912Sartem */
33032912Sartem dbus_bool_t
libhal_ctx_set_device_new_capability(LibHalContext * ctx,LibHalDeviceNewCapability callback)33042912Sartem libhal_ctx_set_device_new_capability (LibHalContext *ctx, LibHalDeviceNewCapability callback)
33052912Sartem {
33062912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
33072912Sartem
33082912Sartem ctx->device_new_capability = callback;
33092912Sartem return TRUE;
33102912Sartem }
33112912Sartem
33122912Sartem /**
33132912Sartem * libhal_ctx_set_device_lost_capability:
33142912Sartem * @ctx: the context for the connection to hald
33152912Sartem * @callback: the function to call when a device loses a capability
33162912Sartem *
33172912Sartem * Set the callback for when a device loses a capability
33182912Sartem *
33192912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise
33202912Sartem */
33212912Sartem dbus_bool_t
libhal_ctx_set_device_lost_capability(LibHalContext * ctx,LibHalDeviceLostCapability callback)33222912Sartem libhal_ctx_set_device_lost_capability (LibHalContext *ctx, LibHalDeviceLostCapability callback)
33232912Sartem {
33242912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
33252912Sartem
33262912Sartem ctx->device_lost_capability = callback;
33272912Sartem return TRUE;
33282912Sartem }
33292912Sartem
33302912Sartem /**
33312912Sartem * libhal_ctx_set_device_property_modified:
33322912Sartem * @ctx: the context for the connection to hald
33332912Sartem * @callback: the function to call when a property is modified on a device
33342912Sartem *
33352912Sartem * Set the callback for when a property is modified on a device.
33362912Sartem *
33372912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise
33382912Sartem */
33392912Sartem dbus_bool_t
libhal_ctx_set_device_property_modified(LibHalContext * ctx,LibHalDevicePropertyModified callback)33402912Sartem libhal_ctx_set_device_property_modified (LibHalContext *ctx, LibHalDevicePropertyModified callback)
33412912Sartem {
33422912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
33432912Sartem
33442912Sartem ctx->device_property_modified = callback;
33452912Sartem return TRUE;
33462912Sartem }
33472912Sartem
33482912Sartem /**
33492912Sartem * libhal_ctx_set_device_condition:
33502912Sartem * @ctx: the context for the connection to hald
33512912Sartem * @callback: the function to call when a device emits a condition
33522912Sartem *
33532912Sartem * Set the callback for when a device emits a condition
33542912Sartem *
33552912Sartem * Returns: TRUE if callback was successfully set, FALSE otherwise
33562912Sartem */
33572912Sartem dbus_bool_t
libhal_ctx_set_device_condition(LibHalContext * ctx,LibHalDeviceCondition callback)33582912Sartem libhal_ctx_set_device_condition (LibHalContext *ctx, LibHalDeviceCondition callback)
33592912Sartem {
33602912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
33612912Sartem
33622912Sartem ctx->device_condition = callback;
33632912Sartem return TRUE;
33642912Sartem }
33652912Sartem
33662912Sartem /**
33672912Sartem * libhal_string_array_length:
33682912Sartem * @str_array: array of strings to consider
33692912Sartem *
33702912Sartem * Get the length of an array of strings.
33712912Sartem *
33722912Sartem * Returns: Number of strings in array
33732912Sartem */
33742912Sartem unsigned int
libhal_string_array_length(char ** str_array)33752912Sartem libhal_string_array_length (char **str_array)
33762912Sartem {
33772912Sartem unsigned int i;
33782912Sartem
33792912Sartem if (str_array == NULL)
33802912Sartem return 0;
33812912Sartem
33822912Sartem for (i = 0; str_array[i] != NULL; i++)
33832912Sartem ;
33842912Sartem
33852912Sartem return i;
33862912Sartem }
33872912Sartem
33882912Sartem
33892912Sartem /**
33902912Sartem * libhal_device_rescan:
33912912Sartem * @ctx: the context for the connection to hald
33922912Sartem * @udi: the Unique id of device
33932912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
33942912Sartem *
33952912Sartem * TODO document me.
33962912Sartem *
33972912Sartem * Returns: Whether the operation succeeded
33982912Sartem */
33992912Sartem dbus_bool_t
libhal_device_rescan(LibHalContext * ctx,const char * udi,DBusError * error)34002912Sartem libhal_device_rescan (LibHalContext *ctx, const char *udi, DBusError *error)
34012912Sartem {
34022912Sartem DBusMessage *message;
34032912Sartem DBusMessageIter reply_iter;
34042912Sartem DBusMessage *reply;
34052912Sartem dbus_bool_t result;
34062912Sartem
34072912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
34082912Sartem
34092912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
34102912Sartem "org.freedesktop.Hal.Device",
34112912Sartem "Rescan");
34122912Sartem
34132912Sartem if (message == NULL) {
34142912Sartem fprintf (stderr,
34152912Sartem "%s %d : Couldn't allocate D-BUS message\n",
34162912Sartem __FILE__, __LINE__);
34172912Sartem return FALSE;
34182912Sartem }
34192912Sartem
34202912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
34212912Sartem message, -1,
34222912Sartem error);
34232912Sartem
3424*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
34252912Sartem dbus_message_unref (message);
34262912Sartem return FALSE;
34272912Sartem }
34282912Sartem
34292912Sartem dbus_message_unref (message);
34302912Sartem
34312912Sartem if (reply == NULL)
34322912Sartem return FALSE;
34332912Sartem
34342912Sartem dbus_message_iter_init (reply, &reply_iter);
34352912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
34362912Sartem DBUS_TYPE_BOOLEAN) {
34372912Sartem dbus_message_unref (message);
34382912Sartem dbus_message_unref (reply);
34392912Sartem return FALSE;
34402912Sartem }
34412912Sartem dbus_message_iter_get_basic (&reply_iter, &result);
34422912Sartem
34432912Sartem dbus_message_unref (reply);
34442912Sartem
34452912Sartem return result;
34462912Sartem }
34472912Sartem
34482912Sartem /**
34492912Sartem * libhal_device_reprobe:
34502912Sartem * @ctx: the context for the connection to hald
34512912Sartem * @udi: the Unique id of device
34522912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
34532912Sartem *
34542912Sartem * TODO document me.
34552912Sartem *
34562912Sartem * Returns: Whether the operation succeeded
34572912Sartem */
34582912Sartem dbus_bool_t
libhal_device_reprobe(LibHalContext * ctx,const char * udi,DBusError * error)34592912Sartem libhal_device_reprobe (LibHalContext *ctx, const char *udi, DBusError *error)
34602912Sartem {
34612912Sartem DBusMessage *message;
34622912Sartem DBusMessageIter reply_iter;
34632912Sartem DBusMessage *reply;
34642912Sartem dbus_bool_t result;
34652912Sartem
34662912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
34672912Sartem
34682912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
34692912Sartem udi,
34702912Sartem "org.freedesktop.Hal.Device",
34712912Sartem "Reprobe");
34722912Sartem
34732912Sartem if (message == NULL) {
34742912Sartem fprintf (stderr,
34752912Sartem "%s %d : Couldn't allocate D-BUS message\n",
34762912Sartem __FILE__, __LINE__);
34772912Sartem return FALSE;
34782912Sartem }
34792912Sartem
34802912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
34812912Sartem message, -1,
34822912Sartem error);
34832912Sartem
3484*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
34852912Sartem dbus_message_unref (message);
34862912Sartem return FALSE;
34872912Sartem }
34882912Sartem
34892912Sartem dbus_message_unref (message);
34902912Sartem
34912912Sartem if (reply == NULL)
34922912Sartem return FALSE;
34932912Sartem
34942912Sartem dbus_message_iter_init (reply, &reply_iter);
34952912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
34962912Sartem DBUS_TYPE_BOOLEAN) {
34972912Sartem dbus_message_unref (message);
34982912Sartem dbus_message_unref (reply);
34992912Sartem return FALSE;
35002912Sartem }
35012912Sartem dbus_message_iter_get_basic (&reply_iter, &result);
35022912Sartem
35032912Sartem dbus_message_unref (reply);
35042912Sartem
35052912Sartem return result;
35062912Sartem }
35072912Sartem
35082912Sartem /**
35092912Sartem * libhal_device_emit_condition:
35102912Sartem * @ctx: the context for the connection to hald
35112912Sartem * @udi: the Unique Device Id
35122912Sartem * @condition_name: user-readable name of condition
35132912Sartem * @condition_details: user-readable details of condition
35142912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
35152912Sartem *
35162912Sartem * Emit a condition from a device. Can only be used from hald helpers.
35172912Sartem *
35182912Sartem * Returns: TRUE if condition successfully emitted,
35192912Sartem * FALSE otherwise
35202912Sartem */
libhal_device_emit_condition(LibHalContext * ctx,const char * udi,const char * condition_name,const char * condition_details,DBusError * error)35212912Sartem dbus_bool_t libhal_device_emit_condition (LibHalContext *ctx,
35222912Sartem const char *udi,
35232912Sartem const char *condition_name,
35242912Sartem const char *condition_details,
35252912Sartem DBusError *error)
35262912Sartem {
35272912Sartem DBusMessage *message;
35282912Sartem DBusMessageIter iter;
35292912Sartem DBusMessageIter reply_iter;
35302912Sartem DBusMessage *reply;
35312912Sartem dbus_bool_t result;
35322912Sartem
35332912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
35342912Sartem
35352912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
35362912Sartem udi,
35372912Sartem "org.freedesktop.Hal.Device",
35382912Sartem "EmitCondition");
35392912Sartem
35402912Sartem if (message == NULL) {
35412912Sartem fprintf (stderr,
35422912Sartem "%s %d : Couldn't allocate D-BUS message\n",
35432912Sartem __FILE__, __LINE__);
35442912Sartem return FALSE;
35452912Sartem }
35462912Sartem
35472912Sartem dbus_message_iter_init_append (message, &iter);
35482912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_name);
35492912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &condition_details);
35502912Sartem
35512912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
35522912Sartem message, -1,
35532912Sartem error);
35542912Sartem
3555*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
35562912Sartem dbus_message_unref (message);
35572912Sartem return FALSE;
35582912Sartem }
35592912Sartem
35602912Sartem dbus_message_unref (message);
35612912Sartem
35622912Sartem if (reply == NULL)
35632912Sartem return FALSE;
35642912Sartem
35652912Sartem dbus_message_iter_init (reply, &reply_iter);
35662912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
35672912Sartem DBUS_TYPE_BOOLEAN) {
35682912Sartem dbus_message_unref (message);
35692912Sartem dbus_message_unref (reply);
35702912Sartem return FALSE;
35712912Sartem }
35722912Sartem dbus_message_iter_get_basic (&reply_iter, &result);
35732912Sartem
35742912Sartem dbus_message_unref (reply);
35752912Sartem
35762912Sartem return result;
35772912Sartem }
35782912Sartem
35792912Sartem /**
35802912Sartem * libhal_device_addon_is_ready:
35812912Sartem * @ctx: the context for the connection to hald
35822912Sartem * @udi: the Unique Device Id
35832912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
35842912Sartem *
35852912Sartem * HAL addon's must call this method when they are done initializing the device object. The HAL
35862912Sartem * daemon will wait for all addon's to call this.
35872912Sartem *
35882912Sartem * Can only be used from hald helpers.
35892912Sartem *
35902912Sartem * Returns: TRUE if the HAL daemon received the message, FALSE otherwise
35912912Sartem */
35922912Sartem dbus_bool_t
libhal_device_addon_is_ready(LibHalContext * ctx,const char * udi,DBusError * error)35932912Sartem libhal_device_addon_is_ready (LibHalContext *ctx, const char *udi, DBusError *error)
35942912Sartem {
35952912Sartem DBusMessage *message;
35962912Sartem DBusMessageIter iter;
35972912Sartem DBusMessageIter reply_iter;
35982912Sartem DBusMessage *reply;
35992912Sartem dbus_bool_t result;
36002912Sartem
36012912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
36022912Sartem
36032912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
36042912Sartem udi,
36052912Sartem "org.freedesktop.Hal.Device",
36062912Sartem "AddonIsReady");
36072912Sartem
36082912Sartem if (message == NULL) {
36092912Sartem fprintf (stderr,
36102912Sartem "%s %d : Couldn't allocate D-BUS message\n",
36112912Sartem __FILE__, __LINE__);
36122912Sartem return FALSE;
36132912Sartem }
36142912Sartem
36152912Sartem dbus_message_iter_init_append (message, &iter);
36162912Sartem
36172912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
36182912Sartem message, -1,
36192912Sartem error);
36202912Sartem
3621*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
36222912Sartem dbus_message_unref (message);
36232912Sartem return FALSE;
36242912Sartem }
36252912Sartem
36262912Sartem dbus_message_unref (message);
36272912Sartem
36282912Sartem if (reply == NULL)
36292912Sartem return FALSE;
36302912Sartem
36312912Sartem dbus_message_iter_init (reply, &reply_iter);
36322912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_BOOLEAN) {
36332912Sartem dbus_message_unref (message);
36342912Sartem dbus_message_unref (reply);
36352912Sartem return FALSE;
36362912Sartem }
36372912Sartem dbus_message_iter_get_basic (&reply_iter, &result);
36382912Sartem
36392912Sartem dbus_message_unref (reply);
36402912Sartem return result;
36412912Sartem }
36422912Sartem
36432912Sartem /**
36442912Sartem * libhal_device_claim_interface:
36452912Sartem * @ctx: the context for the connection to hald
36462912Sartem * @udi: the Unique Device Id
36472912Sartem * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing
36482912Sartem * @introspection_xml: Introspection XML containing what would be inside the interface XML tag
36492912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
36502912Sartem *
36512912Sartem * Claim an interface for a device. All messages to this interface
36522912Sartem * will be forwarded to the helper. Can only be used from hald
36532912Sartem * helpers.
36542912Sartem *
36552912Sartem * Returns: TRUE if interface was claimed, FALSE otherwise
36562912Sartem */
36572912Sartem dbus_bool_t
libhal_device_claim_interface(LibHalContext * ctx,const char * udi,const char * interface_name,const char * introspection_xml,DBusError * error)36582912Sartem libhal_device_claim_interface (LibHalContext *ctx,
36592912Sartem const char *udi,
36602912Sartem const char *interface_name,
36612912Sartem const char *introspection_xml,
36622912Sartem DBusError *error)
36632912Sartem {
36642912Sartem DBusMessage *message;
36652912Sartem DBusMessageIter iter;
36662912Sartem DBusMessageIter reply_iter;
36672912Sartem DBusMessage *reply;
36682912Sartem dbus_bool_t result;
36692912Sartem
36702912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
36712912Sartem
36722912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal",
36732912Sartem udi,
36742912Sartem "org.freedesktop.Hal.Device",
36752912Sartem "ClaimInterface");
36762912Sartem
36772912Sartem if (message == NULL) {
36782912Sartem fprintf (stderr,
36792912Sartem "%s %d : Couldn't allocate D-BUS message\n",
36802912Sartem __FILE__, __LINE__);
36812912Sartem return FALSE;
36822912Sartem }
36832912Sartem
36842912Sartem dbus_message_iter_init_append (message, &iter);
36852912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &interface_name);
36862912Sartem dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &introspection_xml);
36872912Sartem
36882912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
36892912Sartem message, -1,
36902912Sartem error);
36912912Sartem
3692*11992SLin.Guo@Sun.COM if (error != NULL && dbus_error_is_set (error)) {
36932912Sartem dbus_message_unref (message);
36942912Sartem return FALSE;
36952912Sartem }
36962912Sartem
36972912Sartem dbus_message_unref (message);
36982912Sartem
36992912Sartem if (reply == NULL)
37002912Sartem return FALSE;
37012912Sartem
37022912Sartem dbus_message_iter_init (reply, &reply_iter);
37032912Sartem if (dbus_message_iter_get_arg_type (&reply_iter) !=
37042912Sartem DBUS_TYPE_BOOLEAN) {
37052912Sartem dbus_message_unref (message);
37062912Sartem dbus_message_unref (reply);
37072912Sartem return FALSE;
37082912Sartem }
37092912Sartem dbus_message_iter_get_basic (&reply_iter, &result);
37102912Sartem
37112912Sartem dbus_message_unref (reply);
37122912Sartem
37132912Sartem return result;
37142912Sartem }
37152912Sartem
37162912Sartem
37172912Sartem
37182912Sartem struct LibHalChangeSetElement_s;
37192912Sartem
37202912Sartem typedef struct LibHalChangeSetElement_s LibHalChangeSetElement;
37212912Sartem
37222912Sartem struct LibHalChangeSetElement_s {
37232912Sartem char *key;
37242912Sartem int change_type;
37252912Sartem union {
37262912Sartem char *val_str;
37272912Sartem dbus_int32_t val_int;
37282912Sartem dbus_uint64_t val_uint64;
37292912Sartem double val_double;
37302912Sartem dbus_bool_t val_bool;
37312912Sartem char **val_strlist;
37322912Sartem } value;
37332912Sartem LibHalChangeSetElement *next;
37342912Sartem LibHalChangeSetElement *prev;
37352912Sartem };
37362912Sartem
37372912Sartem struct LibHalChangeSet_s {
37382912Sartem char *udi;
37392912Sartem LibHalChangeSetElement *head;
37402912Sartem LibHalChangeSetElement *tail;
37412912Sartem };
37422912Sartem
37432912Sartem /**
37442912Sartem * libhal_device_new_changeset:
37452912Sartem * @udi: unique device identifier
37462912Sartem *
37472912Sartem * Request a new changeset object. Used for changing multiple properties at once. Useful when
37482912Sartem * performance is critical and also for atomically updating several properties.
37492912Sartem *
37502912Sartem * Returns: A new changeset object or NULL on error
37512912Sartem */
37522912Sartem LibHalChangeSet *
libhal_device_new_changeset(const char * udi)37532912Sartem libhal_device_new_changeset (const char *udi)
37542912Sartem {
37552912Sartem LibHalChangeSet *changeset;
37562912Sartem
37572912Sartem changeset = calloc (1, sizeof (LibHalChangeSet));
37582912Sartem if (changeset == NULL)
37592912Sartem goto out;
37602912Sartem
37612912Sartem changeset->udi = strdup (udi);
37622912Sartem if (changeset->udi == NULL) {
37632912Sartem free (changeset);
37642912Sartem changeset = NULL;
37652912Sartem goto out;
37662912Sartem }
37672912Sartem
37682912Sartem changeset->head = NULL;
37692912Sartem changeset->tail = NULL;
37702912Sartem
37712912Sartem out:
37722912Sartem return changeset;
37732912Sartem }
37742912Sartem
37752912Sartem static void
libhal_changeset_append(LibHalChangeSet * changeset,LibHalChangeSetElement * elem)37762912Sartem libhal_changeset_append (LibHalChangeSet *changeset, LibHalChangeSetElement *elem)
37772912Sartem {
37782912Sartem if (changeset->head == NULL) {
37792912Sartem changeset->head = elem;
37802912Sartem changeset->tail = elem;
37812912Sartem elem->next = NULL;
37822912Sartem elem->prev = NULL;
37832912Sartem } else {
37842912Sartem elem->prev = changeset->tail;
37852912Sartem elem->next = NULL;
37862912Sartem elem->prev->next = elem;
37872912Sartem changeset->tail = elem;
37882912Sartem }
37892912Sartem }
37902912Sartem
37912912Sartem
37922912Sartem /**
37932912Sartem * libhal_device_set_property_string:
37942912Sartem * @changeset: the changeset
37952912Sartem * @key: key of property
37962912Sartem * @value: the value to set
37972912Sartem *
37982912Sartem * Set a property.
37992912Sartem *
38002912Sartem * Returns: FALSE on OOM
38012912Sartem */
38022912Sartem dbus_bool_t
libhal_changeset_set_property_string(LibHalChangeSet * changeset,const char * key,const char * value)38032912Sartem libhal_changeset_set_property_string (LibHalChangeSet *changeset, const char *key, const char *value)
38042912Sartem {
38052912Sartem LibHalChangeSetElement *elem;
38062912Sartem
38072912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement));
38082912Sartem if (elem == NULL)
38092912Sartem goto out;
38102912Sartem elem->key = strdup (key);
38112912Sartem if (elem->key == NULL) {
38122912Sartem free (elem);
38132912Sartem elem = NULL;
38142912Sartem goto out;
38152912Sartem }
38162912Sartem
38172912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_STRING;
38182912Sartem elem->value.val_str = strdup (value);
38192912Sartem if (elem->value.val_str == NULL) {
38202912Sartem free (elem->key);
38212912Sartem free (elem);
38222912Sartem elem = NULL;
38232912Sartem goto out;
38242912Sartem }
38252912Sartem
38262912Sartem libhal_changeset_append (changeset, elem);
38272912Sartem out:
38282912Sartem return elem != NULL;
38292912Sartem }
38302912Sartem
38312912Sartem /**
38322912Sartem * libhal_device_set_property_int:
38332912Sartem * @changeset: the changeset
38342912Sartem * @key: key of property
38352912Sartem * @value: the value to set
38362912Sartem *
38372912Sartem * Set a property.
38382912Sartem *
38392912Sartem * Returns: FALSE on OOM
38402912Sartem */
38412912Sartem dbus_bool_t
libhal_changeset_set_property_int(LibHalChangeSet * changeset,const char * key,dbus_int32_t value)38422912Sartem libhal_changeset_set_property_int (LibHalChangeSet *changeset, const char *key, dbus_int32_t value)
38432912Sartem {
38442912Sartem LibHalChangeSetElement *elem;
38452912Sartem
38462912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement));
38472912Sartem if (elem == NULL)
38482912Sartem goto out;
38492912Sartem elem->key = strdup (key);
38502912Sartem if (elem->key == NULL) {
38512912Sartem free (elem);
38522912Sartem elem = NULL;
38532912Sartem goto out;
38542912Sartem }
38552912Sartem
38562912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_INT32;
38572912Sartem elem->value.val_int = value;
38582912Sartem
38592912Sartem libhal_changeset_append (changeset, elem);
38602912Sartem out:
38612912Sartem return elem != NULL;
38622912Sartem }
38632912Sartem
38642912Sartem /**
38652912Sartem * libhal_device_set_property_uint64:
38662912Sartem * @changeset: the changeset
38672912Sartem * @key: key of property
38682912Sartem * @value: the value to set
38692912Sartem *
38702912Sartem * Set a property.
38712912Sartem *
38722912Sartem * Returns: FALSE on OOM
38732912Sartem */
38742912Sartem dbus_bool_t
libhal_changeset_set_property_uint64(LibHalChangeSet * changeset,const char * key,dbus_uint64_t value)38752912Sartem libhal_changeset_set_property_uint64 (LibHalChangeSet *changeset, const char *key, dbus_uint64_t value)
38762912Sartem {
38772912Sartem LibHalChangeSetElement *elem;
38782912Sartem
38792912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement));
38802912Sartem if (elem == NULL)
38812912Sartem goto out;
38822912Sartem elem->key = strdup (key);
38832912Sartem if (elem->key == NULL) {
38842912Sartem free (elem);
38852912Sartem elem = NULL;
38862912Sartem goto out;
38872912Sartem }
38882912Sartem
38892912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_UINT64;
38902912Sartem elem->value.val_uint64 = value;
38912912Sartem
38922912Sartem libhal_changeset_append (changeset, elem);
38932912Sartem out:
38942912Sartem return elem != NULL;
38952912Sartem }
38962912Sartem
38972912Sartem /**
38982912Sartem * libhal_device_set_property_double:
38992912Sartem * @changeset: the changeset
39002912Sartem * @key: key of property
39012912Sartem * @value: the value to set
39022912Sartem *
39032912Sartem * Set a property.
39042912Sartem *
39052912Sartem * Returns: FALSE on OOM
39062912Sartem */
39072912Sartem dbus_bool_t
libhal_changeset_set_property_double(LibHalChangeSet * changeset,const char * key,double value)39082912Sartem libhal_changeset_set_property_double (LibHalChangeSet *changeset, const char *key, double value)
39092912Sartem {
39102912Sartem LibHalChangeSetElement *elem;
39112912Sartem
39122912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement));
39132912Sartem if (elem == NULL)
39142912Sartem goto out;
39152912Sartem elem->key = strdup (key);
39162912Sartem if (elem->key == NULL) {
39172912Sartem free (elem);
39182912Sartem elem = NULL;
39192912Sartem goto out;
39202912Sartem }
39212912Sartem
39222912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_DOUBLE;
39232912Sartem elem->value.val_double = value;
39242912Sartem
39252912Sartem libhal_changeset_append (changeset, elem);
39262912Sartem out:
39272912Sartem return elem != NULL;
39282912Sartem }
39292912Sartem
39302912Sartem /**
39312912Sartem * libhal_device_set_property_bool:
39322912Sartem * @changeset: the changeset
39332912Sartem * @key: key of property
39342912Sartem * @value: the value to set
39352912Sartem *
39362912Sartem * Set a property.
39372912Sartem *
39382912Sartem * Returns: FALSE on OOM
39392912Sartem */
39402912Sartem dbus_bool_t
libhal_changeset_set_property_bool(LibHalChangeSet * changeset,const char * key,dbus_bool_t value)39412912Sartem libhal_changeset_set_property_bool (LibHalChangeSet *changeset, const char *key, dbus_bool_t value)
39422912Sartem {
39432912Sartem LibHalChangeSetElement *elem;
39442912Sartem
39452912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement));
39462912Sartem if (elem == NULL)
39472912Sartem goto out;
39482912Sartem elem->key = strdup (key);
39492912Sartem if (elem->key == NULL) {
39502912Sartem free (elem);
39512912Sartem elem = NULL;
39522912Sartem goto out;
39532912Sartem }
39542912Sartem
39552912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_BOOLEAN;
39562912Sartem elem->value.val_bool = value;
39572912Sartem
39582912Sartem libhal_changeset_append (changeset, elem);
39592912Sartem out:
39602912Sartem return elem != NULL;
39612912Sartem }
39622912Sartem
39632912Sartem /**
39642912Sartem * libhal_device_set_property_strlist:
39652912Sartem * @changeset: the changeset
39662912Sartem * @key: key of property
39672912Sartem * @value: the value to set - NULL terminated array of strings
39682912Sartem *
39692912Sartem * Set a property.
39702912Sartem *
39712912Sartem * Returns: FALSE on OOM
39722912Sartem */
39732912Sartem dbus_bool_t
libhal_changeset_set_property_strlist(LibHalChangeSet * changeset,const char * key,const char ** value)39742912Sartem libhal_changeset_set_property_strlist (LibHalChangeSet *changeset, const char *key, const char **value)
39752912Sartem {
39762912Sartem LibHalChangeSetElement *elem;
39772912Sartem char **value_copy;
39782912Sartem int len;
39792912Sartem int i, j;
39802912Sartem
39812912Sartem elem = calloc (1, sizeof (LibHalChangeSetElement));
39822912Sartem if (elem == NULL)
39832912Sartem goto out;
39842912Sartem elem->key = strdup (key);
39852912Sartem if (elem->key == NULL) {
39862912Sartem free (elem);
39872912Sartem elem = NULL;
39882912Sartem goto out;
39892912Sartem }
39902912Sartem
39912912Sartem for (i = 0; value[i] != NULL; i++)
39922912Sartem ;
39932912Sartem len = i;
39942912Sartem
39952912Sartem value_copy = calloc (len + 1, sizeof (char *));
39962912Sartem if (value_copy == NULL) {
39972912Sartem free (elem->key);
39982912Sartem free (elem);
39992912Sartem elem = NULL;
40002912Sartem goto out;
40012912Sartem }
40022912Sartem
40032912Sartem for (i = 0; i < len; i++) {
40042912Sartem value_copy[i] = strdup (value[i]);
40052912Sartem if (value_copy[i] == NULL) {
40062912Sartem for (j = 0; j < i; j++) {
40072912Sartem free (value_copy[j]);
40082912Sartem }
40092912Sartem free (value_copy);
40102912Sartem free (elem->key);
40112912Sartem free (elem);
40122912Sartem elem = NULL;
40132912Sartem goto out;
40142912Sartem }
40152912Sartem }
40162912Sartem value_copy[i] = NULL;
40172912Sartem
40182912Sartem elem->change_type = LIBHAL_PROPERTY_TYPE_STRLIST;
40192912Sartem elem->value.val_strlist = value_copy;
40202912Sartem
40212912Sartem libhal_changeset_append (changeset, elem);
40222912Sartem out:
40232912Sartem return elem != NULL;
40242912Sartem }
40252912Sartem
40262912Sartem /**
40272912Sartem * libhal_device_commit_changeset:
40282912Sartem * @ctx: the context for the connection to hald
40292912Sartem * @changeset: the changeset to commit
40302912Sartem * @error: pointer to an initialized dbus error object for returning errors or NULL
40312912Sartem *
40322912Sartem * Commit a changeset to the daemon.
40332912Sartem *
40342912Sartem * Returns: True if the changeset was committed on the daemon side
40352912Sartem */
40362912Sartem dbus_bool_t
libhal_device_commit_changeset(LibHalContext * ctx,LibHalChangeSet * changeset,DBusError * error)40372912Sartem libhal_device_commit_changeset (LibHalContext *ctx, LibHalChangeSet *changeset, DBusError *error)
40382912Sartem {
40392912Sartem LibHalChangeSetElement *elem;
40402912Sartem DBusMessage *message;
40412912Sartem DBusMessage *reply;
40422912Sartem DBusError _error;
40432912Sartem DBusMessageIter iter;
40442912Sartem DBusMessageIter sub;
40452912Sartem DBusMessageIter sub2;
40462912Sartem DBusMessageIter sub3;
40472912Sartem DBusMessageIter sub4;
40482912Sartem int i;
40492912Sartem
40502912Sartem LIBHAL_CHECK_LIBHALCONTEXT(ctx, FALSE);
40512912Sartem
40522912Sartem if (changeset->head == NULL) {
40532912Sartem return TRUE;
40542912Sartem }
40552912Sartem
40562912Sartem message = dbus_message_new_method_call ("org.freedesktop.Hal", changeset->udi,
40572912Sartem "org.freedesktop.Hal.Device",
40582912Sartem "SetMultipleProperties");
40592912Sartem
40602912Sartem if (message == NULL) {
40612912Sartem fprintf (stderr, "%s %d : Couldn't allocate D-BUS message\n", __FILE__, __LINE__);
40622912Sartem return FALSE;
40632912Sartem }
40642912Sartem
40652912Sartem dbus_message_iter_init_append (message, &iter);
40662912Sartem
40672912Sartem dbus_message_iter_open_container (&iter,
40682912Sartem DBUS_TYPE_ARRAY,
40692912Sartem DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
40702912Sartem DBUS_TYPE_STRING_AS_STRING
40712912Sartem DBUS_TYPE_VARIANT_AS_STRING
40722912Sartem DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
40732912Sartem &sub);
40742912Sartem
40752912Sartem for (elem = changeset->head; elem != NULL; elem = elem->next) {
40762912Sartem dbus_message_iter_open_container (&sub,
40772912Sartem DBUS_TYPE_DICT_ENTRY,
40782912Sartem NULL,
40792912Sartem &sub2);
40802912Sartem dbus_message_iter_append_basic (&sub2, DBUS_TYPE_STRING, &(elem->key));
40812912Sartem
40822912Sartem switch (elem->change_type) {
40832912Sartem case LIBHAL_PROPERTY_TYPE_STRING:
40842912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &sub3);
40852912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_STRING, &(elem->value.val_str));
40862912Sartem dbus_message_iter_close_container (&sub2, &sub3);
40872912Sartem break;
40882912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST:
40892912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT,
40902912Sartem DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &sub3);
40912912Sartem dbus_message_iter_open_container (&sub3, DBUS_TYPE_ARRAY,
40922912Sartem DBUS_TYPE_STRING_AS_STRING, &sub4);
40932912Sartem for (i = 0; elem->value.val_strlist[i] != NULL; i++) {
40942912Sartem dbus_message_iter_append_basic (&sub4, DBUS_TYPE_STRING,
40952912Sartem &(elem->value.val_strlist[i]));
40962912Sartem }
40972912Sartem dbus_message_iter_close_container (&sub3, &sub4);
40982912Sartem dbus_message_iter_close_container (&sub2, &sub3);
40992912Sartem break;
41002912Sartem case LIBHAL_PROPERTY_TYPE_INT32:
41012912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &sub3);
41022912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_INT32, &(elem->value.val_int));
41032912Sartem dbus_message_iter_close_container (&sub2, &sub3);
41042912Sartem break;
41052912Sartem case LIBHAL_PROPERTY_TYPE_UINT64:
41062912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT64_AS_STRING, &sub3);
41072912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_UINT64, &(elem->value.val_uint64));
41082912Sartem dbus_message_iter_close_container (&sub2, &sub3);
41092912Sartem break;
41102912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE:
41112912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_DOUBLE_AS_STRING, &sub3);
41122912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_DOUBLE, &(elem->value.val_double));
41132912Sartem dbus_message_iter_close_container (&sub2, &sub3);
41142912Sartem break;
41152912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN:
41162912Sartem dbus_message_iter_open_container (&sub2, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING,&sub3);
41172912Sartem dbus_message_iter_append_basic (&sub3, DBUS_TYPE_BOOLEAN, &(elem->value.val_bool));
41182912Sartem dbus_message_iter_close_container (&sub2, &sub3);
41192912Sartem break;
41202912Sartem default:
41212912Sartem fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type);
41222912Sartem break;
41232912Sartem }
41242912Sartem dbus_message_iter_close_container (&sub, &sub2);
41252912Sartem }
41262912Sartem
41272912Sartem dbus_message_iter_close_container (&iter, &sub);
41282912Sartem
41292912Sartem
41302912Sartem dbus_error_init (&_error);
41312912Sartem reply = dbus_connection_send_with_reply_and_block (ctx->connection,
41322912Sartem message, -1,
41332912Sartem &_error);
41342912Sartem
41352912Sartem dbus_move_error (&_error, error);
41362912Sartem if (error != NULL && dbus_error_is_set (error)) {
41372912Sartem fprintf (stderr,
41382912Sartem "%s %d : %s\n",
41392912Sartem __FILE__, __LINE__, error->message);
41402912Sartem
41412912Sartem dbus_message_unref (message);
41422912Sartem return FALSE;
41432912Sartem }
41442912Sartem
41452912Sartem if (reply == NULL) {
41462912Sartem dbus_message_unref (message);
41472912Sartem return FALSE;
41482912Sartem }
41492912Sartem
41502912Sartem return TRUE;
41512912Sartem }
41522912Sartem
41532912Sartem /**
41542912Sartem * libhal_device_free_changeset:
41552912Sartem * @changeset: the changeset to free
41562912Sartem *
41572912Sartem * Free a changeset.
41582912Sartem */
41592912Sartem void
libhal_device_free_changeset(LibHalChangeSet * changeset)41602912Sartem libhal_device_free_changeset (LibHalChangeSet *changeset)
41612912Sartem {
41622912Sartem LibHalChangeSetElement *elem;
41632912Sartem LibHalChangeSetElement *elem2;
41642912Sartem
41652912Sartem for (elem = changeset->head; elem != NULL; elem = elem2) {
41662912Sartem elem2 = elem->next;
41672912Sartem
41682912Sartem switch (elem->change_type) {
41692912Sartem case LIBHAL_PROPERTY_TYPE_STRING:
41702912Sartem free (elem->value.val_str);
41712912Sartem break;
41722912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST:
41732912Sartem libhal_free_string_array (elem->value.val_strlist);
41742912Sartem break;
41752912Sartem /* explicit fallthrough */
41762912Sartem case LIBHAL_PROPERTY_TYPE_INT32:
41772912Sartem case LIBHAL_PROPERTY_TYPE_UINT64:
41782912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE:
41792912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN:
41802912Sartem break;
41812912Sartem default:
41822912Sartem fprintf (stderr, "%s %d : unknown change_type %d\n", __FILE__, __LINE__, elem->change_type);
41832912Sartem break;
41842912Sartem }
41852912Sartem free (elem);
41862912Sartem }
41872912Sartem
41882912Sartem free (changeset->udi);
41892912Sartem free (changeset);
41902912Sartem }
4191